From ef7c74cbc3bb7185095de48d2fa143bf581166ae Mon Sep 17 00:00:00 2001 From: John Lim Date: Mon, 30 Nov 2020 18:02:38 -0500 Subject: [PATCH] More 1.6.0 updates * Agent App API * VoiceId * Tasks * contact.reject * CHANGELOG.md --- CHANGELOG.md | 7 + Documentation.md | 174 +- Makefile | 4 +- README.md | 23 +- gulpfile.js | 4 +- package-lock.json | 1384 ++++++++++++++- package.json | 3 +- release/connect-streams-min.js | 2 +- release/connect-streams.js | 1511 ++++++++++++++--- src/agent-app/agent-app.js | 100 ++ src/agent-app/app-registry.js | 62 + src/api.js | 530 +++++- src/aws-client.js | 101 +- src/client.js | 65 +- src/core.js | 83 +- src/event.js | 15 +- src/index.d.ts | 208 ++- src/lib/amazon-connect-websocket-manager.js | 3 +- .../amazon-connect-websocket-manager.js.map | 2 +- src/log.js | 72 +- src/mediaControllers/chat.js | 15 +- src/mediaControllers/factory.js | 34 +- src/mediaControllers/task.js | 100 ++ src/ringtone.js | 25 +- src/softphone.js | 62 +- src/util.js | 57 +- src/worker.js | 117 +- test/unit/agent-app.spec.js | 155 ++ test/unit/app-registry.spec.js | 53 + test/unit/connections.spec.js | 150 ++ test/unit/core.spec.js | 261 ++- test/unit/ringtone.spec.js | 53 + test/unit/streams.spec.js | 3 +- test/unit/test-setup.js | 30 +- 34 files changed, 4949 insertions(+), 519 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 src/agent-app/agent-app.js create mode 100644 src/agent-app/app-registry.js create mode 100644 src/mediaControllers/task.js create mode 100644 test/unit/agent-app.spec.js create mode 100644 test/unit/app-registry.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..bb765833 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# CHANGELOG.md +## 1.6.0 (2020-12-01) +Features Introduced: + - A new media channel--tasks--has been added to Connect's offerings, alongside chat and voice. With this release, Streams, in conjunction with [TaskJS](https://github.com/amazon-connect/amazon-connect-taskjs) now supports this feature with relevant apis, etc. + - VoiceId: You can find relevant apis for using the feature in the src/api.js file. + - Agent App features: Connect is expanding its agent-app offering with an agent application container called Agent App. Within agent app you can embed CCP UI, Customer Profiles UI, and Wisdom UI. + - onConnectionOpened and onConnectionClosed websocket manager apis were introduced. diff --git a/Documentation.md b/Documentation.md index 4c4b1e30..bbcfd2c6 100644 --- a/Documentation.md +++ b/Documentation.md @@ -2,21 +2,23 @@ (c) 2018-2020 Amazon.com, Inc. All rights reserved. # Important Announcements -1. July 2020 -- We recently changed the new, omnichannel, CCP's behavior when it encounters three voice-only agent states: `FailedConnectAgent`, `FailedConnectCustomer`, and `AfterCallWork`. +1. December 2020 — 1.6.0 brings with it the release of a new Agent App API. In addition to the CCP, customers can now embed additional applications using connect.agentApp, including Customer Profiles and Wisdom (preview). See the [updated documentation](#initialization-for-ccp-customer-profiles-and-wisdom) for details on usage. We are also introducing a preview release for Amazon Connect Voice ID. + * ### About Amazon Connect Customer Profiles + + Amazon Connect Customer Profiles provides pre-built integrations so you can quickly combine customer information from multiple external applications, with contact history from Amazon Connect. This allows you to create a customer profile that has all the information agents need during customer interactions in a single place. + * ### About Amazon Connect Wisdom (this feature is in preview release for Amazon Connect and is subject to change) + + With Amazon Connect Wisdom, agents can search and find content across multiple repositories, such as frequently asked questions (FAQs), wikis, articles, and step-by-step instructions for handling different customer issues. They can type questions or phrases in a search box (such as, "how long after purchase can handbags be exchanged?") without having to guess which keywords will work. + * ### About Amazon Connect Voice ID (this feature is in preview release for Amazon Connect and is subject to change) + + Amazon Connect Voice ID provides real-time caller authentication which makes voice interactions in contact centers more secure and efficient. Voice ID uses machine learning to verify the identity of genuine customers by analyzing a caller’s unique voice characteristics. This allows contact centers to use an additional security layer that doesn’t rely on the caller answering multiple security questions, and makes it easy to enroll and verify customers without changing the natural flow of their conversation. +2. July 2020 -- We recently changed the new, omnichannel, CCP's behavior when it encounters three voice-only agent states: `FailedConnectAgent`, `FailedConnectCustomer`, and `AfterCallWork`. * `FailedConnectAgent` -- Previously, we required the agent to click the "Clear Contact" button to clear this state. When the agent clicked the "Clear Contact" button, the previous behavior took the agent back to the `Available` state without fail. Now the `FailedConnectAgent` state will be "auto-cleared", much like `FailedConnectCustomer` always has been. * `FailedConnectAgent` and `FailedConnectCustomer` -- We are now using the `contact.clear()` API to auto-clear these states. As a result, the agent will be returned to their previous visible agent state (e.g. `Available`). Previously, the agent had always been set to `Available` as a result of this "auto-clearing" behavior. Note that even custom CCPs will behave differently with this update for `FailedConnectAgent` and `FailedConnectCustomer`. * `AfterCallWork` -- As part of the new `contact.clear()` behavior, clicking "Clear Contact" while in `AfterCallWork` will return the agent to their previous visible agent state (e.g. `Available`, etc.). Note that custom CCPs that implement their own After Call Work behavior will not be affected by this change. * We are putting `contact.complete()` on a deprecation path. Therefore, you should start using `contact.clear()` in its place. If you want to emulate CCP's After Call Work behavior in your customer CCP, then make sure you use `contact.clear()` when clearing voice contacts. - + ## Overview -The Amazon Connect Streams API (Streams) gives you the power to integrate your -existing web applications with Amazon Connect. Streams lets you -embed the Contact Control Panel (CCP) UI components into your page, and/or -handle agent and contact state events directly giving you the power to control -agent and contact state through an object oriented event driven interface. You -can use the built in interface or build your own from scratch: Streams gives you -the choice. This library must be used in conjunction with [amazon-connect-chatjs](https://github.com/amazon-connect/amazon-connect-chatjs) -in order to utilize Amazon Connect's Chat functionality. +The Amazon Connect Streams API (Streams) gives you the power to integrate your existing web applications with Amazon Connect. Streams lets you embed the Contact Control Panel (CCP) and Customer Profiles app UI into your page. It also enables you to handle agent and contact state events directly through an object oriented event driven interface. You can use the built in interface or build your own from scratch: Streams gives you the choice. + +This library must be used in conjunction with [amazon-connect-chatjs](https://github.com/amazon-connect/amazon-connect-chatjs) or [amazon-connect-taskjs](https://github.com/amazon-connect/amazon-connect-taskjs) in order to utilize Amazon Connect's Chat or Task functionality. ## Architecture Click [here](Architecture.md) to view a quick architecture overview of how the @@ -228,6 +230,7 @@ this: Streams only needs ChatJS when it is being used for chat. Note that when including ChatJS, it must be imported after StreamsJS, or there will be AWS SDK issues (ChatJS relies on the ConnectParticipant Service, which is not in the Streams AWS SDK). +* If you are using task functionalities you must include [TaskJS](https://github.com/amazon-connect/amazon-connect-taskjs). TaskJS should be imported after Streams. * If you'd like access to the WebRTC session to further customize the softphone experience you can use [connect-rtc-js](https://github.com/aws/connect-rtc-js). Please refer to the connect-rtc-js readme for detailed instructions on integrating connect-rtc-js with Streams. @@ -661,7 +664,7 @@ Subscribe a method to be invoked when the contact is pending. This event is expe ```js contact.onConnecting(function(contact) { /* ... */ }); ``` -Subscribe a method to be invoked when the contact is connecting. This works with chat and softphone contacts. This event happens when a call or chat comes in, before accepting (there is an exception for queue callbacks, in which onConnecting's handler is executed after the callback is accepted). Note that once the contact has been accepted, the `onAccepted` handler will be triggered. +Subscribe a method to be invoked when the contact is connecting. This works with chat and softphone contacts. This event happens when a call or chat comes in, before accepting (there is an exception for queue callbacks, in which onConnecting's handler is started after the callback is accepted). Note that once the contact has been accepted, the `onAccepted` handler will be triggered. ### `contact.onAccepted()` ```js @@ -856,6 +859,15 @@ Optional success and failure callbacks can be provided to determine if the opera ### `contact.destroy()` This method is now deprecated. +### `contact.reject()` +```js +contact.reject({ + success: function() { /* ... */ }, + failure: function(err) { /* ... */ } +}); +``` +Reject an incoming contact. + ### `contact.clear()` ```js @@ -864,7 +876,7 @@ contact.clear({ failure: function(err) { /* ... */ } }); ``` -This is a more generic form of `contact.complete()`. Use this for voice and chat contacts to clear the contact +This is a more generic form of `contact.complete()`. Use this for voice, chat, and task contacts to clear the contact when the contact is no longer actively being worked on (i.e. it's one of ERROR, ACW, MISSED, REJECTED). It works for both monitoring and non-monitoring connections. @@ -941,11 +953,39 @@ The data behind the `Contact` API object is ephemeral and changes whenever new d provides an opportunity to create a snapshot version of the `Contact` API object and save it for future use, such as adding to a log file or posting elsewhere. +### Task Contact APIs +The following contact methods are currently only available for task contacts. + +### `contact.getName()` +```js +var taskName = contact.getName(); +``` +Gets the name of the contact. + +### `contact.getDescription()` +```js +var taskDescription = contact.getDescription(); +``` +Gets the description of the contact. + +### `contact.getReferences()` +```js +var taskReferences = contact.getReferences(); +``` +Gets references for the contact. A sample reference looks like the following: + +```js +"Reference-Name": { + type: "URL", + value: "https://link.com" +} +``` + ## Connection API The Connection API provides action methods (no event subscriptions) which can be called to manipulate the state of a particular connection within a contact. Like contacts, connections come and go. It is good practice not -to persist these object or keep them as internal state. If you need to, store the `contactId` and `connectionId` +to persist these objects or keep them as internal state. If you need to, store the `contactId` and `connectionId` of the connection and make sure that the contact and connection still exist by fetching them in order from the `Agent` API object before calling methods on them. @@ -1080,7 +1120,7 @@ Optional success and failure callbacks can be provided to determine if the opera ## VoiceConnection API The VoiceConnection API provides action methods (no event subscriptions) which can be called to manipulate the state of a particular voice connection within a contact. Like contacts, connections come and go. It is good practice not -to persist these object or keep them as internal state. If you need to, store the `contactId` and `connectionId` +to persist these objects or keep them as internal state. If you need to, store the `contactId` and `connectionId` of the connection and make sure that the contact and connection still exist by fetching them in order from the `Agent` API object before calling methods on them. @@ -1108,7 +1148,7 @@ The promise resolves to the return value of `voiceConnection.getMediaInfo()` but ## ChatConnection API The ChatConnection API provides action methods (no event subscriptions) which can be called to manipulate the state of a particular chat connection within a contact. Like contacts, connections come and go. It is good practice not -to persist these object or keep them as internal state. If you need to, store the `contactId` and `connectionId` +to persist these objects or keep them as internal state. If you need to, store the `contactId` and `connectionId` of the connection and make sure that the contact and connection still exist by fetching them in order from the `Agent` API object before calling methods on them. @@ -1140,6 +1180,33 @@ Gets a `Promise` with the media controller associated with this connection. The promise resolves to a `ChatSession` object from `amazon-connect-chatjs` library. See the [amazon-connect-chatjs documentation](https://github.com/amazon-connect/amazon-connect-chatjs) for more information. +## TaskConnection API +The TaskConnection API provides action methods (no event subscriptions) which can be called to manipulate the state +of a particular task connection within a contact. Like contacts, connections come and go. It is good practice not +to persist these objects or keep them as internal state. If you need to, store the `contactId` and `connectionId` +of the connection and make sure that the contact and connection still exist by fetching them in order from +the `Agent` API object before calling methods on them. + +### `taskConnection.getMediaInfo()` +```js +var mediaInfo = conn.getMediaInfo(); +``` +Get the media info object associated with this connection. + +### `taskConnection.getMediaType()` +```js +if (conn.getMediaType() === "task") { /* ... */ } +``` +Returns the `MediaType` enum value: `"task"`. + +### `taskConnection.getMediaController()` +```js +conn.getMediaController().then(function (taskController) { /* ... */ }); +``` +Gets a `Promise` with the media controller associated with this connection. +The promise resolves to a `TaskSession` object from the `amazon-connect-taskjs` library. +See the [amazon-connect-taskjs documentation](https://github.com/amazon-connect/amazon-connect-taskjs) for more information. + ## Utility Functions ### `Endpoint.byPhoneNumber()` (static function) ```js @@ -1174,6 +1241,7 @@ This enumeration lists the different types of contact channels. * `ChannelType.VOICE`: A voice contact. * `ChannelType.CHAT`: A chat contact. +* `ChannelType.TASK`: A task contact. ### `EndpointType` This enumeration lists the different types of endpoints. @@ -1217,6 +1285,7 @@ This enumeration lists all of the contact types supported by Connect Streams. * `ContactType.VOICE`: Normal incoming and outgoing voice calls. * `ContactType.QUEUE_CALLBACK`: Special outbound voice calls which are routed to agents before being placed. For more information about how to setup and use queued callbacks, see the Amazon Connect user documentation. * `ContactType.CHAT`: Chat contact. +* `ContactType.TASK`: Task contact. ### `EventType` This is a list of some of the special event types which are published into the low-level @@ -1251,6 +1320,8 @@ Each of these functions returns a `LogEntry` object, onto which additional infor `.withException(e)` and pass an exception (`e`) to add stack trace and additional info to the logs, and you can call `.withObject(o)` to add an arbitrary object (`o`) to the logs. +A new method `sendInternalLogToServer()` that can be chained to the other methods of the logger has been implemented and is intended for internal use only. It is NOT recommended for use by customers. + Finally, you can trigger the logs to be downloaded to the agent's machine in JSON form by calling `connect.getLog().download()`. ### LogLevel @@ -1333,3 +1404,76 @@ An internal communication error occurred. ### `ERROR Default` All errors not otherwise defined. + +## Initialization for CCP, Customer Profiles, and Wisdom + +*Note that if you are only using CCP, please follow [these directions](#initialization)* + +Initializing the Streams API is the first step to verify that you have everything set up correctly and that you are able to listen for events. + +### `connect.agentApp.initApp(name, containerId, appUrl, config)` + +```js + + + + + + + + +
+
+
+
+
+ + + +``` + +Integrates with Amazon Connect by loading the pre-built app located at `appUrl` into an iframe and appending it into the DOM element with id of `containerId`. Underneath the hood, `initApp` creates a `WindowIOStream` for the iframes to communicate with the main CCP iframe, which is in charge of authenticating the agent's session, managing the agent state, and contact state. +* `name`: A string which should be one of `ccp`, `customerprofiles`, or `wisdom`. +* `containerId`: The string id of the DOM element that will contain the app iframe. +* `appUrl`: The string URL of the app. This is the page you would normally navigate to in order to use the app in a standalone page, it is different for each instance. +* `config`: This object is optional and allows you to specify some settings surrounding the CCP. + * `ccpParams`: Optional params that mirror the configuration options for `initCCP`. + * `style`: An optional string to supply inline styling for the iframe. + +## Voice ID APIs +Use the following methods to integrate Voice ID into your existing agent web applications. + +### `voiceConnection.enrollSpeakerInVoiceId()` +Enroll a customer to Voice ID using a click of a button. +### `voiceConnection.evaluateSpeakerWithVoiceId()` +Check the customer's Voice ID verification status. +### `voiceConnection.optOutVoiceIdSpeaker()` + Opt out a customer from Voice ID. +### `voiceConnection.getVoiceIdSpeakerStatus()` +Describe the enrollment status of a customer. +### `voiceConnection.getVoiceIdSpeakerId()` +Get the speaker ID. +### `voiceConnection.updateVoiceIdSpeakerId()` +Update the speaker ID. diff --git a/Makefile b/Makefile index cb8998dd..f8514882 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,9 @@ SOURCE_FILES = src/aws-client.js \ src/ringtone.js \ src/softphone.js \ src/worker.js \ - src/mediaControllers/* + src/mediaControllers/* \ + src/agent-app/agent-app.js \ + src/agent-app/app-registry.js $(OUTPUT_JS): $(SOURCE_FILES) cat $^ >$@ diff --git a/README.md b/README.md index 27a4452b..2cbf6bee 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,9 @@ [![Build Status](https://travis-ci.org/amazon-connect/amazon-connect-streams.svg?branch=master)](https://travis-ci.org/amazon-connect/amazon-connect-streams) -The Amazon Connect Streams API (Streams) gives you the power to integrate your -existing web applications with Amazon Connect. Streams lets you -embed the Contact Control Panel (CCP) UI components into your page, and/or -handle agent and contact state events directly giving you the power to control -agent and contact state through an object oriented event driven interface. You -can use the built in interface or build your own from scratch: Streams gives you -the choice. This library must be used in conjunction with [amazon-connect-chatjs](https://github.com/amazon-connect/amazon-connect-chatjs) -in order to utilize Amazon Connect's Chat functionality. +The Amazon Connect Streams API (Streams) gives you the power to integrate your existing web applications with Amazon Connect. Streams lets you embed the Contact Control Panel (CCP) and Customer Profiles app UI into your page. It also enables you to handle agent and contact state events directly through an object oriented event driven interface. You can use the built in interface or build your own from scratch: Streams gives you the choice. + +This library must be used in conjunction with [amazon-connect-chatjs](https://github.com/amazon-connect/amazon-connect-chatjs) or [amazon-connect-taskjs](https://github.com/amazon-connect/amazon-connect-taskjs) in order to utilize Amazon Connect's Chat or Task functionality. # Learn More To learn more about Amazon Connect and its capabilities, please check out @@ -24,7 +19,14 @@ $ make ``` # Important Announcements -1. July 2020 -- We recently changed the new, omnichannel, CCP's behavior when it encounters three voice-only agent states: `FailedConnectAgent`, `FailedConnectCustomer`, and `AfterCallWork`. +1. December 2020 — 1.6.0 brings with it the release of a new Agent App API. In addition to the CCP, customers can now embed additional applications using connect.agentApp, including Customer Profiles and Wisdom (preview). See the [updated documentation](Documentation.md#initialization-for-ccp-customer-profiles-and-wisdom) for details on usage. We are also introducing a preview release for Amazon Connect Voice ID. + * ### About Amazon Connect Customer Profiles + + Amazon Connect Customer Profiles provides pre-built integrations so you can quickly combine customer information from multiple external applications, with contact history from Amazon Connect. This allows you to create a customer profile that has all the information agents need during customer interactions in a single place. + * ### About Amazon Connect Wisdom (this feature is in preview release for Amazon Connect and is subject to change) + + With Amazon Connect Wisdom, agents can search and find content across multiple repositories, such as frequently asked questions (FAQs), wikis, articles, and step-by-step instructions for handling different customer issues. They can type questions or phrases in a search box (such as, "how long after purchase can handbags be exchanged?") without having to guess which keywords will work. + * ### About Amazon Connect Voice ID (The feature is in preview release for Amazon Connect and is subject to change) + + Amazon Connect Voice ID provides real-time caller authentication which makes voice interactions in contact centers more secure and efficient. Voice ID uses machine learning to verify the identity of genuine customers by analyzing a caller’s unique voice characteristics. This allows contact centers to use an additional security layer that doesn’t rely on the caller answering multiple security questions, and makes it easy to enroll and verify customers without changing the natural flow of their conversation. +2. July 2020 -- We recently changed the new, omnichannel, CCP's behavior when it encounters three voice-only agent states: `FailedConnectAgent`, `FailedConnectCustomer`, and `AfterCallWork`. * `FailedConnectAgent` -- Previously, we required the agent to click the "Clear Contact" button to clear this state. When the agent clicked the "Clear Contact" button, the previous behavior took the agent back to the `Available` state without fail. Now the `FailedConnectAgent` state will be "auto-cleared", much like `FailedConnectCustomer` always has been. * `FailedConnectAgent` and `FailedConnectCustomer` -- We are now using the `contact.clear()` API to auto-clear these states. As a result, the agent will be returned to their previous visible agent state (e.g. `Available`). Previously, the agent had always been set to `Available` as a result of this "auto-clearing" behavior. Note that even custom CCPs will behave differently with this update for `FailedConnectAgent` and `FailedConnectCustomer`. * `AfterCallWork` -- As part of the new `contact.clear()` behavior, clicking "Clear Contact" while in `AfterCallWork` will return the agent to their previous visible agent state (e.g. `Available`, etc.). Note that custom CCPs that implement their own After Call Work behavior will not be affected by this change. @@ -76,7 +78,7 @@ This will make the `connect` variable available in the current context. ```ts import "amazon-connect-streams"; -connect.initCCP({ /* ... */ }); +connect.core.initCCP({ /* ... */ }); ``` ## Downloading Streams from Github @@ -225,6 +227,7 @@ this: Streams only needs ChatJS when it is being used for chat. Note that when including ChatJS, it must be imported after StreamsJS, or there will be AWS SDK issues (ChatJS relies on the ConnectParticipant Service, which is not in the Streams AWS SDK). +* If you are using task functionalities you must include [TaskJS](https://github.com/amazon-connect/amazon-connect-taskjs). TaskJS should be imported after Streams. * If you'd like access to the WebRTC session to further customize the softphone experience you can use [connect-rtc-js](https://github.com/aws/connect-rtc-js). Please refer to the connect-rtc-js readme for detailed instructions on integrating connect-rtc-js with Streams. diff --git a/gulpfile.js b/gulpfile.js index 3fc2f253..c3fe178d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -23,7 +23,9 @@ var source = [ "src/aws-client.js", "src/softphone.js", "src/worker.js", "src/mediaControllers/*", - + "src/agent-app/agent-app.js", + "src/agent-app/app-registry.js" + ]; gulp.task('pre-test', function () { diff --git a/package-lock.json b/package-lock.json index 959de615..f0c11dcb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,12 @@ { "name": "amazon-connect-streams", - "version": "1.5.2", + "version": "1.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@sinonjs/commons": { "version": "1.8.1", + "resolved": false, "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", "dev": true, "requires": { @@ -14,6 +15,7 @@ }, "@sinonjs/fake-timers": { "version": "6.0.1", + "resolved": false, "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", "dev": true, "requires": { @@ -22,6 +24,7 @@ }, "@sinonjs/formatio": { "version": "5.0.1", + "resolved": false, "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", "dev": true, "requires": { @@ -30,8 +33,9 @@ } }, "@sinonjs/samsam": { - "version": "5.2.0", - "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==", + "version": "5.3.0", + "resolved": false, + "integrity": "sha512-hXpcfx3aq+ETVBwPlRFICld5EnrkexXuXDwqUNhDdr5L8VjvMeSRwyOa0qL7XFmR+jVWR4rUZtnxlG7RX72sBg==", "dev": true, "requires": { "@sinonjs/commons": "^1.6.0", @@ -41,22 +45,74 @@ }, "@sinonjs/text-encoding": { "version": "0.7.1", + "resolved": false, "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, "abbrev": { "version": "1.0.9", + "resolved": false, "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", "dev": true }, + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "amdefine": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true, "optional": true }, "ansi-colors": { "version": "1.1.0", + "resolved": false, "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { @@ -65,6 +121,7 @@ }, "ansi-cyan": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", "dev": true, "requires": { @@ -73,6 +130,7 @@ }, "ansi-gray": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", "dev": true, "requires": { @@ -81,6 +139,7 @@ }, "ansi-red": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", "dev": true, "requires": { @@ -89,11 +148,13 @@ }, "ansi-regex": { "version": "2.1.1", + "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "3.2.1", + "resolved": false, "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { @@ -102,11 +163,13 @@ }, "ansi-wrap": { "version": "0.1.0", + "resolved": false, "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", "dev": true }, "anymatch": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { @@ -116,6 +179,7 @@ "dependencies": { "normalize-path": { "version": "2.1.1", + "resolved": false, "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { @@ -126,6 +190,7 @@ }, "append-buffer": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", "dev": true, "requires": { @@ -134,11 +199,13 @@ }, "archy": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "argparse": { "version": "1.0.10", + "resolved": false, "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { @@ -147,11 +214,13 @@ }, "arr-diff": { "version": "4.0.0", + "resolved": false, "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, "arr-filter": { "version": "1.1.2", + "resolved": false, "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", "dev": true, "requires": { @@ -160,11 +229,13 @@ }, "arr-flatten": { "version": "1.1.0", + "resolved": false, "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, "arr-map": { "version": "2.0.2", + "resolved": false, "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", "dev": true, "requires": { @@ -173,16 +244,25 @@ }, "arr-union": { "version": "3.1.0", + "resolved": false, "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, "array-each": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", "dev": true }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, "array-initial": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", "dev": true, "requires": { @@ -192,6 +272,7 @@ "dependencies": { "is-number": { "version": "4.0.0", + "resolved": false, "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true } @@ -199,6 +280,7 @@ }, "array-last": { "version": "1.3.0", + "resolved": false, "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", "dev": true, "requires": { @@ -207,6 +289,7 @@ "dependencies": { "is-number": { "version": "4.0.0", + "resolved": false, "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true } @@ -214,11 +297,13 @@ }, "array-slice": { "version": "1.1.0", + "resolved": false, "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, "array-sort": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", "dev": true, "requires": { @@ -229,6 +314,7 @@ "dependencies": { "kind-of": { "version": "5.1.0", + "resolved": false, "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } @@ -236,26 +322,46 @@ }, "array-unique": { "version": "0.3.2", + "resolved": false, "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, "assertion-error": { "version": "1.1.0", + "resolved": false, "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "assign-symbols": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, "async": { "version": "1.5.2", + "resolved": false, "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "async-done": { "version": "1.3.2", + "resolved": false, "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", "dev": true, "requires": { @@ -267,24 +373,52 @@ }, "async-each": { "version": "1.0.3", + "resolved": false, "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, "async-settle": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", "dev": true, "requires": { "async-done": "^1.2.2" } }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, "atob": { "version": "2.1.2", + "resolved": false, "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, "bach": { "version": "1.2.0", + "resolved": false, "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", "dev": true, "requires": { @@ -301,11 +435,13 @@ }, "balanced-match": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "base": { "version": "0.11.2", + "resolved": false, "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { @@ -320,6 +456,7 @@ "dependencies": { "define-property": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { @@ -328,6 +465,7 @@ }, "is-accessor-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { @@ -336,6 +474,7 @@ }, "is-data-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { @@ -344,6 +483,7 @@ }, "is-descriptor": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { @@ -354,18 +494,30 @@ } } }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, "binary-extensions": { "version": "1.13.1", + "resolved": false, "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "binaryextensions": { "version": "2.3.0", + "resolved": false, "integrity": "sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg==", "dev": true }, "bindings": { "version": "1.5.0", + "resolved": false, "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dev": true, "optional": true, @@ -375,6 +527,7 @@ }, "brace-expansion": { "version": "1.1.11", + "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { @@ -384,6 +537,7 @@ }, "braces": { "version": "2.3.2", + "resolved": false, "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { @@ -401,6 +555,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -409,23 +564,33 @@ } } }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, "browser-stdout": { "version": "1.3.1", + "resolved": false, "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "buffer-equal": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", "dev": true }, "buffer-from": { "version": "1.1.1", + "resolved": false, "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "cache-base": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { @@ -440,13 +605,31 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.0", + "resolved": false, + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, "camelcase": { "version": "3.0.0", + "resolved": false, "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, "chai": { "version": "4.2.0", + "resolved": false, "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "dev": true, "requires": { @@ -460,6 +643,7 @@ }, "chalk": { "version": "2.4.2", + "resolved": false, "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { @@ -470,11 +654,13 @@ "dependencies": { "has-flag": { "version": "3.0.0", + "resolved": false, "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "supports-color": { "version": "5.5.0", + "resolved": false, "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { @@ -485,11 +671,13 @@ }, "check-error": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, "chokidar": { "version": "2.1.8", + "resolved": false, "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { @@ -509,6 +697,7 @@ }, "class-utils": { "version": "0.3.6", + "resolved": false, "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { @@ -520,6 +709,7 @@ "dependencies": { "define-property": { "version": "0.2.5", + "resolved": false, "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -530,6 +720,7 @@ }, "cli": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", "dev": true, "requires": { @@ -539,6 +730,7 @@ }, "cliui": { "version": "3.2.0", + "resolved": false, "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { @@ -549,21 +741,25 @@ }, "clone": { "version": "2.1.2", + "resolved": false, "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, "clone-buffer": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", "dev": true }, "clone-stats": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", "dev": true }, "cloneable-readable": { "version": "1.1.3", + "resolved": false, "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", "dev": true, "requires": { @@ -574,11 +770,13 @@ }, "code-point-at": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "collection-map": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", "dev": true, "requires": { @@ -589,6 +787,7 @@ }, "collection-visit": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { @@ -598,6 +797,7 @@ }, "color-convert": { "version": "1.9.3", + "resolved": false, "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { @@ -606,26 +806,40 @@ }, "color-name": { "version": "1.1.3", + "resolved": false, "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "color-support": { "version": "1.1.3", + "resolved": false, "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "component-emitter": { "version": "1.3.0", + "resolved": false, "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "concat-map": { "version": "0.0.1", + "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "concat-stream": { "version": "1.6.2", + "resolved": false, "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { @@ -637,6 +851,7 @@ }, "concat-with-sourcemaps": { "version": "1.1.0", + "resolved": false, "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", "dev": true, "requires": { @@ -645,6 +860,7 @@ "dependencies": { "source-map": { "version": "0.6.1", + "resolved": false, "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } @@ -652,6 +868,7 @@ }, "console-browserify": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { @@ -660,6 +877,7 @@ }, "convert-source-map": { "version": "1.7.0", + "resolved": false, "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { @@ -668,11 +886,13 @@ }, "copy-descriptor": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, "copy-props": { "version": "2.0.4", + "resolved": false, "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", "dev": true, "requires": { @@ -682,11 +902,13 @@ }, "core-util-is": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "cross-spawn": { "version": "7.0.3", + "resolved": false, "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { @@ -697,6 +919,7 @@ "dependencies": { "which": { "version": "2.0.2", + "resolved": false, "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { @@ -705,8 +928,24 @@ } } }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, "d": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dev": true, "requires": { @@ -716,16 +955,52 @@ }, "dargs": { "version": "7.0.0", + "resolved": false, "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, "date-now": { "version": "0.1.4", + "resolved": false, "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, "debug": { "version": "2.6.9", + "resolved": false, "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { @@ -734,16 +1009,19 @@ }, "decamelize": { "version": "1.2.0", + "resolved": false, "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decode-uri-component": { "version": "0.2.0", + "resolved": false, "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, "deep-eql": { "version": "3.0.1", + "resolved": false, "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { @@ -752,11 +1030,13 @@ }, "deep-is": { "version": "0.1.3", + "resolved": false, "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "default-compare": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", "dev": true, "requires": { @@ -765,6 +1045,7 @@ "dependencies": { "kind-of": { "version": "5.1.0", + "resolved": false, "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } @@ -772,11 +1053,13 @@ }, "default-resolution": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", "dev": true }, "define-properties": { "version": "1.1.3", + "resolved": false, "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { @@ -785,6 +1068,7 @@ }, "define-property": { "version": "2.0.2", + "resolved": false, "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { @@ -794,6 +1078,7 @@ "dependencies": { "is-accessor-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { @@ -802,6 +1087,7 @@ }, "is-data-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { @@ -810,6 +1096,7 @@ }, "is-descriptor": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { @@ -820,18 +1107,27 @@ } } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, "detect-file": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, "diff": { "version": "3.5.0", + "resolved": false, "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "dom-serializer": { "version": "0.2.2", + "resolved": false, "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, "requires": { @@ -841,23 +1137,36 @@ "dependencies": { "domelementtype": { "version": "2.0.2", + "resolved": false, "integrity": "sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA==", "dev": true }, "entities": { - "version": "2.0.3", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "version": "2.1.0", + "resolved": false, + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true } } }, "domelementtype": { "version": "1.3.1", + "resolved": false, "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, "domhandler": { "version": "2.3.0", + "resolved": false, "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", "dev": true, "requires": { @@ -866,6 +1175,7 @@ }, "domutils": { "version": "1.5.1", + "resolved": false, "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", "dev": true, "requires": { @@ -875,6 +1185,7 @@ }, "duplexify": { "version": "3.7.1", + "resolved": false, "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, "requires": { @@ -886,6 +1197,7 @@ }, "each-props": { "version": "1.3.2", + "resolved": false, "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", "dev": true, "requires": { @@ -893,18 +1205,31 @@ "object.defaults": "^1.1.0" } }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "editions": { "version": "1.3.4", + "resolved": false, "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", "dev": true }, "emoji-regex": { "version": "7.0.3", + "resolved": false, "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "end-of-stream": { "version": "1.4.4", + "resolved": false, "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { @@ -913,38 +1238,22 @@ }, "entities": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", "dev": true }, "error-ex": { "version": "1.3.2", + "resolved": false, "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, - "es-abstract": { - "version": "1.18.0-next.1", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, "es-to-primitive": { "version": "1.2.1", + "resolved": false, "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { @@ -955,6 +1264,7 @@ }, "es5-ext": { "version": "0.10.53", + "resolved": false, "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", "dev": true, "requires": { @@ -965,6 +1275,7 @@ }, "es6-iterator": { "version": "2.0.3", + "resolved": false, "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "dev": true, "requires": { @@ -975,6 +1286,7 @@ }, "es6-symbol": { "version": "3.1.3", + "resolved": false, "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, "requires": { @@ -984,6 +1296,7 @@ }, "es6-weak-map": { "version": "2.0.3", + "resolved": false, "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dev": true, "requires": { @@ -995,11 +1308,13 @@ }, "escape-string-regexp": { "version": "1.0.5", + "resolved": false, "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "escodegen": { "version": "1.8.1", + "resolved": false, "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { @@ -1012,6 +1327,7 @@ "dependencies": { "source-map": { "version": "0.2.0", + "resolved": false, "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", "dev": true, "optional": true, @@ -1023,21 +1339,25 @@ }, "esprima": { "version": "2.7.3", + "resolved": false, "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, "estraverse": { "version": "1.9.3", + "resolved": false, "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", "dev": true }, "esutils": { "version": "2.0.3", + "resolved": false, "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "execa": { "version": "2.1.0", + "resolved": false, "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", "dev": true, "requires": { @@ -1054,11 +1374,13 @@ }, "exit": { "version": "0.1.2", + "resolved": false, "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, "expand-brackets": { "version": "2.1.4", + "resolved": false, "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { @@ -1073,6 +1395,7 @@ "dependencies": { "define-property": { "version": "0.2.5", + "resolved": false, "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -1081,6 +1404,7 @@ }, "extend-shallow": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -1091,6 +1415,7 @@ }, "expand-range": { "version": "1.8.2", + "resolved": false, "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { @@ -1099,6 +1424,7 @@ "dependencies": { "fill-range": { "version": "2.2.4", + "resolved": false, "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { @@ -1111,6 +1437,7 @@ }, "is-number": { "version": "2.1.0", + "resolved": false, "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { @@ -1119,6 +1446,7 @@ }, "isobject": { "version": "2.1.0", + "resolved": false, "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { @@ -1127,6 +1455,7 @@ }, "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -1137,6 +1466,7 @@ }, "expand-tilde": { "version": "2.0.2", + "resolved": false, "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { @@ -1145,6 +1475,7 @@ }, "ext": { "version": "1.4.0", + "resolved": false, "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", "dev": true, "requires": { @@ -1153,6 +1484,7 @@ "dependencies": { "type": { "version": "2.1.0", + "resolved": false, "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", "dev": true } @@ -1160,11 +1492,13 @@ }, "extend": { "version": "3.0.2", + "resolved": false, "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "extend-shallow": { "version": "3.0.2", + "resolved": false, "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { @@ -1174,6 +1508,7 @@ "dependencies": { "is-extendable": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { @@ -1184,6 +1519,7 @@ }, "extglob": { "version": "2.0.4", + "resolved": false, "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { @@ -1199,6 +1535,7 @@ "dependencies": { "define-property": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { @@ -1207,6 +1544,7 @@ }, "extend-shallow": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -1215,6 +1553,7 @@ }, "is-accessor-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { @@ -1223,6 +1562,7 @@ }, "is-data-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { @@ -1231,6 +1571,7 @@ }, "is-descriptor": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { @@ -1241,8 +1582,15 @@ } } }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, "fancy-log": { "version": "1.3.3", + "resolved": false, "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", "dev": true, "requires": { @@ -1252,24 +1600,40 @@ "time-stamp": "^1.0.0" } }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, "fast-levenshtein": { "version": "1.1.4", + "resolved": false, "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=", "dev": true }, "file-uri-to-path": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true, "optional": true }, "filename-regex": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", "dev": true }, "fill-range": { "version": "4.0.0", + "resolved": false, "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { @@ -1281,6 +1645,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -1291,6 +1656,7 @@ }, "find-up": { "version": "1.1.2", + "resolved": false, "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { @@ -1300,6 +1666,7 @@ }, "findup-sync": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", "dev": true, "requires": { @@ -1311,6 +1678,7 @@ }, "fined": { "version": "1.2.0", + "resolved": false, "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, "requires": { @@ -1323,6 +1691,7 @@ }, "first-chunk-stream": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", "dev": true, "requires": { @@ -1331,26 +1700,30 @@ }, "flagged-respawn": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true }, "flat": { - "version": "4.1.0", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "version": "4.1.1", + "resolved": false, + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", "dev": true, "requires": { "is-buffer": "~2.0.3" }, "dependencies": { "is-buffer": { - "version": "2.0.4", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "version": "2.0.5", + "resolved": false, + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true } } }, "flush-write-stream": { "version": "1.1.1", + "resolved": false, "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, "requires": { @@ -1360,19 +1733,39 @@ }, "for-in": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "for-own": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "^1.0.1" } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "fragment-cache": { "version": "0.2.1", + "resolved": false, "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { @@ -1381,6 +1774,7 @@ }, "fs-mkdirp-stream": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", "dev": true, "requires": { @@ -1390,11 +1784,13 @@ }, "fs.realpath": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "fsevents": { "version": "1.2.13", + "resolved": false, "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true, @@ -1405,21 +1801,36 @@ }, "function-bind": { "version": "1.1.1", + "resolved": false, "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "get-caller-file": { "version": "1.0.3", + "resolved": false, "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, "get-func-name": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": false, + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-stream": { "version": "5.2.0", + "resolved": false, "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { @@ -1428,11 +1839,22 @@ }, "get-value": { "version": "2.0.6", + "resolved": false, "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "glob": { "version": "7.1.6", + "resolved": false, "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { @@ -1446,6 +1868,7 @@ }, "glob-base": { "version": "0.3.0", + "resolved": false, "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { @@ -1455,6 +1878,7 @@ "dependencies": { "glob-parent": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { @@ -1463,11 +1887,13 @@ }, "is-extglob": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-glob": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { @@ -1478,6 +1904,7 @@ }, "glob-parent": { "version": "3.1.0", + "resolved": false, "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { @@ -1487,6 +1914,7 @@ "dependencies": { "is-glob": { "version": "3.1.0", + "resolved": false, "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { @@ -1497,6 +1925,7 @@ }, "glob-stream": { "version": "6.1.0", + "resolved": false, "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", "dev": true, "requires": { @@ -1514,6 +1943,7 @@ }, "glob-watcher": { "version": "5.0.5", + "resolved": false, "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", "dev": true, "requires": { @@ -1528,6 +1958,7 @@ }, "global-modules": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { @@ -1538,6 +1969,7 @@ }, "global-prefix": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "requires": { @@ -1550,6 +1982,7 @@ }, "glogg": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", "dev": true, "requires": { @@ -1558,16 +1991,19 @@ }, "graceful-fs": { "version": "4.2.4", + "resolved": false, "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "growl": { "version": "1.10.5", + "resolved": false, "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "gulp": { "version": "4.0.2", + "resolved": false, "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", "dev": true, "requires": { @@ -1579,6 +2015,7 @@ }, "gulp-cli": { "version": "2.3.0", + "resolved": false, "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", "dev": true, "requires": { @@ -1604,6 +2041,7 @@ }, "gulp-concat": { "version": "2.6.1", + "resolved": false, "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", "dev": true, "requires": { @@ -1614,6 +2052,7 @@ }, "gulp-istanbul": { "version": "1.1.3", + "resolved": false, "integrity": "sha512-uMLSdqPDnBAV/B9rNyOgVMgrVC1tPbe+5GH6P13UOyxbRDT/w4sKYHWftPMA8j9om+NFvfeRlqpDXL2fixFWNA==", "dev": true, "requires": { @@ -1627,6 +2066,7 @@ }, "gulp-jshint": { "version": "2.1.0", + "resolved": false, "integrity": "sha512-sP3NK8Y/1e58O0PH9t6s7DAr/lKDSUbIY207oWSeufM6/VclB7jJrIBcPCsyhrFTCDUl9DauePbt6VqP2vPM5w==", "dev": true, "requires": { @@ -1639,6 +2079,7 @@ }, "gulp-mocha": { "version": "7.0.2", + "resolved": false, "integrity": "sha512-ZXBGN60TXYnFhttr19mfZBOtlHYGx9SvCSc+Kr/m2cMIGloUe176HBPwvPqlakPuQgeTGVRS47NmcdZUereKMQ==", "dev": true, "requires": { @@ -1652,11 +2093,13 @@ "dependencies": { "has-flag": { "version": "4.0.0", + "resolved": false, "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "plugin-error": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", "dev": true, "requires": { @@ -1668,6 +2111,7 @@ }, "supports-color": { "version": "7.2.0", + "resolved": false, "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { @@ -1676,6 +2120,7 @@ }, "through2": { "version": "3.0.2", + "resolved": false, "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, "requires": { @@ -1687,11 +2132,13 @@ }, "gulp-rename": { "version": "1.4.0", + "resolved": false, "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==", "dev": true }, "gulp-replace": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==", "dev": true, "requires": { @@ -1702,6 +2149,7 @@ }, "gulp-rev": { "version": "8.1.1", + "resolved": false, "integrity": "sha1-sRBr+qVlMQahHRYS6wz/3lQMsZY=", "dev": true, "requires": { @@ -1717,6 +2165,7 @@ }, "gulp-uglify": { "version": "3.0.2", + "resolved": false, "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", "dev": true, "requires": { @@ -1734,6 +2183,7 @@ }, "gulp-watch": { "version": "5.0.1", + "resolved": false, "integrity": "sha512-HnTSBdzAOFIT4wmXYPDUn783TaYAq9bpaN05vuZNP5eni3z3aRx0NAKbjhhMYtcq76x4R1wf4oORDGdlrEjuog==", "dev": true, "requires": { @@ -1753,6 +2203,7 @@ "dependencies": { "anymatch": { "version": "1.3.2", + "resolved": false, "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { @@ -1762,6 +2213,7 @@ }, "arr-diff": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { @@ -1770,11 +2222,13 @@ }, "array-unique": { "version": "0.2.1", + "resolved": false, "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, "braces": { "version": "1.8.5", + "resolved": false, "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { @@ -1785,16 +2239,19 @@ }, "clone": { "version": "1.0.4", + "resolved": false, "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "clone-stats": { "version": "0.0.1", + "resolved": false, "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", "dev": true }, "expand-brackets": { "version": "0.1.5", + "resolved": false, "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { @@ -1803,6 +2260,7 @@ }, "extglob": { "version": "0.3.2", + "resolved": false, "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { @@ -1811,6 +2269,7 @@ }, "fancy-log": { "version": "1.3.2", + "resolved": false, "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", "dev": true, "requires": { @@ -1821,11 +2280,13 @@ }, "is-extglob": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-glob": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { @@ -1834,6 +2295,7 @@ }, "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -1842,6 +2304,7 @@ }, "micromatch": { "version": "2.3.11", + "resolved": false, "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { @@ -1862,6 +2325,7 @@ }, "normalize-path": { "version": "2.1.1", + "resolved": false, "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { @@ -1870,6 +2334,7 @@ }, "plugin-error": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", "dev": true, "requires": { @@ -1881,6 +2346,7 @@ "dependencies": { "arr-diff": { "version": "4.0.0", + "resolved": false, "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true } @@ -1888,11 +2354,13 @@ }, "replace-ext": { "version": "0.0.1", + "resolved": false, "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", "dev": true }, "vinyl-file": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-p+v1/779obfRjRQPyweyI++2dRo=", "dev": true, "requires": { @@ -1906,6 +2374,7 @@ "dependencies": { "vinyl": { "version": "1.2.0", + "resolved": false, "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { @@ -1920,6 +2389,7 @@ }, "gulplog": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "dev": true, "requires": { @@ -1928,6 +2398,7 @@ }, "handlebars": { "version": "4.7.6", + "resolved": false, "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", "dev": true, "requires": { @@ -1940,13 +2411,31 @@ "dependencies": { "source-map": { "version": "0.6.1", + "resolved": false, "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, "has": { "version": "1.0.3", + "resolved": false, "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { @@ -1955,11 +2444,13 @@ }, "has-flag": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "has-gulplog": { "version": "0.1.0", + "resolved": false, "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", "dev": true, "requires": { @@ -1968,11 +2459,13 @@ }, "has-symbols": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, "has-value": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { @@ -1983,6 +2476,7 @@ }, "has-values": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { @@ -1992,6 +2486,7 @@ "dependencies": { "kind-of": { "version": "4.0.0", + "resolved": false, "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { @@ -2002,11 +2497,13 @@ }, "he": { "version": "1.2.0", + "resolved": false, "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "homedir-polyfill": { "version": "1.0.3", + "resolved": false, "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "requires": { @@ -2015,11 +2512,22 @@ }, "hosted-git-info": { "version": "2.8.8", + "resolved": false, "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, "htmlparser2": { "version": "3.8.3", + "resolved": false, "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", "dev": true, "requires": { @@ -2032,11 +2540,13 @@ "dependencies": { "isarray": { "version": "0.0.1", + "resolved": false, "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.1.14", + "resolved": false, "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -2048,13 +2558,35 @@ }, "string_decoder": { "version": "0.10.31", + "resolved": false, "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "inflight": { "version": "1.0.6", + "resolved": false, "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { @@ -2064,26 +2596,31 @@ }, "inherits": { "version": "2.0.4", + "resolved": false, "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "ini": { "version": "1.3.5", + "resolved": false, "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "interpret": { "version": "1.4.0", + "resolved": false, "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, "invert-kv": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "is-absolute": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { @@ -2093,6 +2630,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", + "resolved": false, "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -2101,6 +2639,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -2111,11 +2650,13 @@ }, "is-arrayish": { "version": "0.2.1", + "resolved": false, "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-binary-path": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { @@ -2124,16 +2665,28 @@ }, "is-buffer": { "version": "1.1.6", + "resolved": false, "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-callable": { "version": "1.2.2", + "resolved": false, "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", "dev": true }, + "is-core-module": { + "version": "2.1.0", + "resolved": false, + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", + "resolved": false, "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -2142,6 +2695,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -2152,11 +2706,13 @@ }, "is-date-object": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, "is-descriptor": { "version": "0.1.6", + "resolved": false, "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { @@ -2167,6 +2723,7 @@ "dependencies": { "kind-of": { "version": "5.1.0", + "resolved": false, "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } @@ -2174,11 +2731,13 @@ }, "is-dotfile": { "version": "1.0.3", + "resolved": false, "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", "dev": true }, "is-equal-shallow": { "version": "0.1.3", + "resolved": false, "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { @@ -2187,16 +2746,19 @@ }, "is-extendable": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, "is-extglob": { "version": "2.1.1", + "resolved": false, "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { @@ -2205,6 +2767,7 @@ }, "is-glob": { "version": "4.0.1", + "resolved": false, "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { @@ -2213,16 +2776,19 @@ }, "is-negated-glob": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", "dev": true }, "is-negative-zero": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", "dev": true }, "is-number": { "version": "3.0.0", + "resolved": false, "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { @@ -2231,6 +2797,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -2241,11 +2808,13 @@ }, "is-plain-obj": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, "is-plain-object": { "version": "2.0.4", + "resolved": false, "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { @@ -2254,16 +2823,19 @@ }, "is-posix-bracket": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", "dev": true }, "is-primitive": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "dev": true }, "is-regex": { "version": "1.1.1", + "resolved": false, "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { @@ -2272,6 +2844,7 @@ }, "is-relative": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { @@ -2280,19 +2853,28 @@ }, "is-stream": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, "is-symbol": { "version": "1.0.3", + "resolved": false, "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "requires": { "has-symbols": "^1.0.1" } }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, "is-unc-path": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { @@ -2301,36 +2883,49 @@ }, "is-utf8": { "version": "0.2.1", + "resolved": false, "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-valid-glob": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", "dev": true }, "is-windows": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isexe": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isobject": { "version": "3.0.1", + "resolved": false, "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, "istanbul": { "version": "0.4.5", + "resolved": false, "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, "requires": { @@ -2352,6 +2947,7 @@ "dependencies": { "glob": { "version": "5.0.15", + "resolved": false, "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { @@ -2364,6 +2960,7 @@ }, "resolve": { "version": "1.1.7", + "resolved": false, "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true } @@ -2371,6 +2968,7 @@ }, "istanbul-threshold-checker": { "version": "0.2.1", + "resolved": false, "integrity": "sha1-xdyU6PLMXNP/0zVFL4S1U8QkgzE=", "dev": true, "requires": { @@ -2380,6 +2978,7 @@ }, "istextorbinary": { "version": "2.2.1", + "resolved": false, "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", "dev": true, "requires": { @@ -2390,6 +2989,7 @@ }, "js-yaml": { "version": "3.14.0", + "resolved": false, "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { @@ -2399,13 +2999,89 @@ "dependencies": { "esprima": { "version": "4.0.1", + "resolved": false, "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true } } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, "jshint": { "version": "2.12.0", + "resolved": false, "integrity": "sha512-TwuuaUDmra0JMkuqvqy+WGo2xGHSNjv1BA1nTIgtH2K5z1jHuAEeAgp7laaR+hLRmajRjcrM71+vByBDanCyYA==", "dev": true, "requires": { @@ -2421,33 +3097,69 @@ "dependencies": { "strip-json-comments": { "version": "1.0.4", + "resolved": false, "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", "dev": true } } }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, "just-debounce": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", "dev": true }, "just-extend": { "version": "4.1.1", + "resolved": false, "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", "dev": true }, "kind-of": { "version": "6.0.3", + "resolved": false, "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "last-run": { "version": "1.1.1", + "resolved": false, "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", "dev": true, "requires": { @@ -2457,6 +3169,7 @@ }, "lazystream": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { @@ -2465,6 +3178,7 @@ }, "lcid": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { @@ -2473,14 +3187,22 @@ }, "lead": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", "dev": true, "requires": { "flush-write-stream": "^1.0.2" } }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true + }, "levn": { "version": "0.3.0", + "resolved": false, "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { @@ -2490,6 +3212,7 @@ }, "liftoff": { "version": "3.1.0", + "resolved": false, "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", "dev": true, "requires": { @@ -2505,6 +3228,7 @@ }, "load-json-file": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -2517,6 +3241,7 @@ }, "locate-path": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { @@ -2526,6 +3251,7 @@ "dependencies": { "path-exists": { "version": "3.0.0", + "resolved": false, "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } @@ -2533,36 +3259,49 @@ }, "lodash": { "version": "4.17.20", + "resolved": false, "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, "lodash.assign": { "version": "4.2.0", + "resolved": false, "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, "lodash.clonedeep": { "version": "4.5.0", + "resolved": false, "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, "lodash.get": { "version": "4.4.2", + "resolved": false, "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, "lodash.isobject": { "version": "3.0.2", + "resolved": false, "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", "dev": true }, "lodash.merge": { "version": "4.6.2", + "resolved": false, "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, "log-symbols": { "version": "2.2.0", + "resolved": false, "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "requires": { @@ -2571,11 +3310,13 @@ }, "make-error": { "version": "1.3.6", + "resolved": false, "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "make-error-cause": { "version": "1.2.2", + "resolved": false, "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", "dev": true, "requires": { @@ -2584,6 +3325,7 @@ }, "make-iterator": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "requires": { @@ -2592,11 +3334,13 @@ }, "map-cache": { "version": "0.2.2", + "resolved": false, "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, "map-visit": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { @@ -2605,6 +3349,7 @@ }, "matchdep": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", "dev": true, "requires": { @@ -2616,6 +3361,7 @@ "dependencies": { "findup-sync": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { @@ -2627,6 +3373,7 @@ }, "is-glob": { "version": "3.1.0", + "resolved": false, "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { @@ -2637,16 +3384,19 @@ }, "math-random": { "version": "1.0.4", + "resolved": false, "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true }, "merge-stream": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, "micromatch": { "version": "3.1.10", + "resolved": false, "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { @@ -2665,13 +3415,30 @@ "to-regex": "^3.0.2" } }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, "mimic-fn": { "version": "2.1.0", + "resolved": false, "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "minimatch": { "version": "3.0.4", + "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { @@ -2680,11 +3447,13 @@ }, "minimist": { "version": "1.2.5", + "resolved": false, "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mixin-deep": { "version": "1.3.2", + "resolved": false, "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { @@ -2694,6 +3463,7 @@ "dependencies": { "is-extendable": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { @@ -2704,6 +3474,7 @@ }, "mkdirp": { "version": "0.5.5", + "resolved": false, "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { @@ -2712,6 +3483,7 @@ }, "mocha": { "version": "6.2.3", + "resolved": false, "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", "dev": true, "requires": { @@ -2742,21 +3514,25 @@ "dependencies": { "ansi-colors": { "version": "3.2.3", + "resolved": false, "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true }, "ansi-regex": { "version": "4.1.0", + "resolved": false, "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "camelcase": { "version": "5.3.1", + "resolved": false, "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "cliui": { "version": "5.0.0", + "resolved": false, "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { @@ -2767,6 +3543,7 @@ }, "debug": { "version": "3.2.6", + "resolved": false, "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { @@ -2775,11 +3552,13 @@ }, "esprima": { "version": "4.0.1", + "resolved": false, "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "find-up": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { @@ -2788,11 +3567,13 @@ }, "get-caller-file": { "version": "2.0.5", + "resolved": false, "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "glob": { "version": "7.1.3", + "resolved": false, "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { @@ -2806,16 +3587,19 @@ }, "has-flag": { "version": "3.0.0", + "resolved": false, "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "js-yaml": { "version": "3.13.1", + "resolved": false, "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { @@ -2825,6 +3609,7 @@ }, "mkdirp": { "version": "0.5.4", + "resolved": false, "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", "dev": true, "requires": { @@ -2833,11 +3618,13 @@ }, "ms": { "version": "2.1.1", + "resolved": false, "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "object.assign": { "version": "4.1.0", + "resolved": false, "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { @@ -2849,11 +3636,13 @@ }, "require-main-filename": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "string-width": { "version": "3.1.0", + "resolved": false, "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { @@ -2864,6 +3653,7 @@ }, "strip-ansi": { "version": "5.2.0", + "resolved": false, "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { @@ -2872,6 +3662,7 @@ }, "supports-color": { "version": "6.0.0", + "resolved": false, "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, "requires": { @@ -2880,11 +3671,13 @@ }, "which-module": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "wrap-ansi": { "version": "5.1.0", + "resolved": false, "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { @@ -2895,11 +3688,13 @@ }, "y18n": { "version": "4.0.0", + "resolved": false, "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, "yargs": { "version": "13.3.2", + "resolved": false, "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { @@ -2917,6 +3712,7 @@ }, "yargs-parser": { "version": "13.1.2", + "resolved": false, "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { @@ -2926,29 +3722,43 @@ } } }, + "mocha-jsdom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mocha-jsdom/-/mocha-jsdom-2.0.0.tgz", + "integrity": "sha512-+3D++FPXHXEesbBD7Q/r4dkc3XzVFMPLJVIECaQ685dj9qKQYzliqX8IXyIUbUL4x1QfgD9h8Zao8cn03NKKEA==", + "dev": true, + "requires": { + "jsdom": "^11.11.0" + } + }, "modify-filename": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE=", "dev": true }, "ms": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "mute-stdout": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", "dev": true }, "nan": { - "version": "2.14.1", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "version": "2.14.2", + "resolved": false, + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true, "optional": true }, "nanomatch": { "version": "1.2.13", + "resolved": false, "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { @@ -2967,16 +3777,19 @@ }, "neo-async": { "version": "2.6.2", + "resolved": false, "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "next-tick": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, "nise": { "version": "4.0.4", + "resolved": false, "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", "dev": true, "requires": { @@ -2989,6 +3802,7 @@ }, "node-environment-flags": { "version": "1.0.5", + "resolved": false, "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", "dev": true, "requires": { @@ -2998,6 +3812,7 @@ }, "nopt": { "version": "3.0.6", + "resolved": false, "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { @@ -3006,6 +3821,7 @@ }, "normalize-package-data": { "version": "2.5.0", + "resolved": false, "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { @@ -3017,11 +3833,13 @@ }, "normalize-path": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "now-and-later": { "version": "2.0.1", + "resolved": false, "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", "dev": true, "requires": { @@ -3030,6 +3848,7 @@ }, "npm-run-path": { "version": "3.1.0", + "resolved": false, "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", "dev": true, "requires": { @@ -3038,16 +3857,31 @@ }, "number-is-nan": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, "object-assign": { "version": "4.1.1", + "resolved": false, "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-copy": { "version": "0.1.0", + "resolved": false, "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { @@ -3058,6 +3892,7 @@ "dependencies": { "define-property": { "version": "0.2.5", + "resolved": false, "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -3066,6 +3901,7 @@ }, "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -3076,16 +3912,19 @@ }, "object-inspect": { "version": "1.8.0", + "resolved": false, "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true }, "object-keys": { "version": "1.1.1", + "resolved": false, "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, "object-visit": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { @@ -3093,18 +3932,20 @@ } }, "object.assign": { - "version": "4.1.1", - "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "version": "4.1.2", + "resolved": false, + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.0", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" } }, "object.defaults": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "dev": true, "requires": { @@ -3116,6 +3957,7 @@ }, "object.getownpropertydescriptors": { "version": "2.1.0", + "resolved": false, "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { @@ -3125,6 +3967,7 @@ "dependencies": { "es-abstract": { "version": "1.17.7", + "resolved": false, "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", "dev": true, "requires": { @@ -3145,6 +3988,7 @@ }, "object.map": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", "dev": true, "requires": { @@ -3154,6 +3998,7 @@ }, "object.omit": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { @@ -3163,6 +4008,7 @@ "dependencies": { "for-own": { "version": "0.1.5", + "resolved": false, "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { @@ -3173,6 +4019,7 @@ }, "object.pick": { "version": "1.3.0", + "resolved": false, "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { @@ -3181,6 +4028,7 @@ }, "object.reduce": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", "dev": true, "requires": { @@ -3190,6 +4038,7 @@ }, "once": { "version": "1.4.0", + "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { @@ -3198,6 +4047,7 @@ }, "onetime": { "version": "5.1.2", + "resolved": false, "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { @@ -3206,6 +4056,7 @@ }, "optionator": { "version": "0.8.3", + "resolved": false, "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { @@ -3219,6 +4070,7 @@ "dependencies": { "fast-levenshtein": { "version": "2.0.6", + "resolved": false, "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true } @@ -3226,6 +4078,7 @@ }, "ordered-read-streams": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", "dev": true, "requires": { @@ -3234,6 +4087,7 @@ }, "os-locale": { "version": "1.4.0", + "resolved": false, "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { @@ -3242,11 +4096,13 @@ }, "p-finally": { "version": "2.0.1", + "resolved": false, "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", "dev": true }, "p-limit": { "version": "2.3.0", + "resolved": false, "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { @@ -3255,6 +4111,7 @@ }, "p-locate": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { @@ -3263,11 +4120,13 @@ }, "p-try": { "version": "2.2.0", + "resolved": false, "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "parse-filepath": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { @@ -3278,6 +4137,7 @@ }, "parse-glob": { "version": "3.0.4", + "resolved": false, "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { @@ -3289,11 +4149,13 @@ "dependencies": { "is-extglob": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-glob": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { @@ -3304,6 +4166,7 @@ }, "parse-json": { "version": "2.2.0", + "resolved": false, "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { @@ -3312,26 +4175,37 @@ }, "parse-node-version": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true }, "parse-passwd": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, "pascalcase": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, "path-dirname": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, "path-exists": { "version": "2.1.0", + "resolved": false, "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { @@ -3340,21 +4214,25 @@ }, "path-is-absolute": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-key": { "version": "3.1.1", + "resolved": false, "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { "version": "1.0.6", + "resolved": false, "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-root": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "requires": { @@ -3363,11 +4241,13 @@ }, "path-root-regex": { "version": "0.1.2", + "resolved": false, "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, "path-to-regexp": { "version": "1.8.0", + "resolved": false, "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { @@ -3376,6 +4256,7 @@ "dependencies": { "isarray": { "version": "0.0.1", + "resolved": false, "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true } @@ -3383,6 +4264,7 @@ }, "path-type": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { @@ -3393,21 +4275,31 @@ }, "pathval": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, "pify": { "version": "2.3.0", + "resolved": false, "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", + "resolved": false, "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { @@ -3416,6 +4308,7 @@ }, "plugin-error": { "version": "0.1.2", + "resolved": false, "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", "dev": true, "requires": { @@ -3428,6 +4321,7 @@ "dependencies": { "arr-diff": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", "dev": true, "requires": { @@ -3437,16 +4331,19 @@ }, "arr-union": { "version": "2.1.0", + "resolved": false, "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", "dev": true }, "array-slice": { "version": "0.2.3", + "resolved": false, "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", "dev": true }, "extend-shallow": { "version": "1.1.4", + "resolved": false, "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", "dev": true, "requires": { @@ -3455,38 +4352,57 @@ }, "kind-of": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", "dev": true } } }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, "posix-character-classes": { "version": "0.1.1", + "resolved": false, "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, "prelude-ls": { "version": "1.1.2", + "resolved": false, "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "preserve": { "version": "0.2.0", + "resolved": false, "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, "pretty-hrtime": { "version": "1.0.3", + "resolved": false, "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, "process-nextick-args": { "version": "2.0.1", + "resolved": false, "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, "pump": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { @@ -3496,6 +4412,7 @@ }, "pumpify": { "version": "1.5.1", + "resolved": false, "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, "requires": { @@ -3506,6 +4423,7 @@ "dependencies": { "pump": { "version": "2.0.1", + "resolved": false, "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, "requires": { @@ -3515,8 +4433,21 @@ } } }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, "randomatic": { "version": "3.1.1", + "resolved": false, "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "requires": { @@ -3527,6 +4458,7 @@ "dependencies": { "is-number": { "version": "4.0.0", + "resolved": false, "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true } @@ -3534,6 +4466,7 @@ }, "rcfinder": { "version": "0.1.9", + "resolved": false, "integrity": "sha1-8+gPOH3fmugK4wpBADKWQuroERU=", "dev": true, "requires": { @@ -3542,6 +4475,7 @@ }, "rcloader": { "version": "0.2.2", + "resolved": false, "integrity": "sha1-WNIpi0YtC5v9ITPSoex0+9cFxxc=", "dev": true, "requires": { @@ -3553,6 +4487,7 @@ }, "read-pkg": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { @@ -3563,6 +4498,7 @@ }, "read-pkg-up": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { @@ -3572,6 +4508,7 @@ }, "readable-stream": { "version": "2.3.7", + "resolved": false, "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { @@ -3586,6 +4523,7 @@ }, "readdirp": { "version": "2.2.1", + "resolved": false, "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { @@ -3596,6 +4534,7 @@ }, "rechoir": { "version": "0.6.2", + "resolved": false, "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { @@ -3604,6 +4543,7 @@ }, "regex-cache": { "version": "0.4.4", + "resolved": false, "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { @@ -3612,6 +4552,7 @@ }, "regex-not": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { @@ -3621,6 +4562,7 @@ }, "remove-bom-buffer": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", "dev": true, "requires": { @@ -3630,6 +4572,7 @@ }, "remove-bom-stream": { "version": "1.2.0", + "resolved": false, "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", "dev": true, "requires": { @@ -3640,26 +4583,31 @@ }, "remove-trailing-separator": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, "repeat-element": { "version": "1.1.3", + "resolved": false, "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", "dev": true }, "repeat-string": { "version": "1.6.1", + "resolved": false, "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "replace-ext": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", "dev": true }, "replace-homedir": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", "dev": true, "requires": { @@ -3670,6 +4618,7 @@ }, "replacestream": { "version": "4.0.3", + "resolved": false, "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", "dev": true, "requires": { @@ -3678,26 +4627,79 @@ "readable-stream": "^2.0.2" } }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, "require-directory": { "version": "2.1.1", + "resolved": false, "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "resolve": { - "version": "1.17.0", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.19.0", + "resolved": false, + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, "resolve-dir": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "requires": { @@ -3707,6 +4709,7 @@ }, "resolve-options": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", "dev": true, "requires": { @@ -3715,21 +4718,25 @@ }, "resolve-url": { "version": "0.2.1", + "resolved": false, "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, "ret": { "version": "0.1.15", + "resolved": false, "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, "rev-hash": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-dyCiNu0MJY3z5kvsA+wEiwW5JMQ=", "dev": true }, "rev-path": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-G5R2L9gYu9kEuqPfIFgO9gO+OhBWOAT83HyauOQmGHO6y9Fsa4acv+XsmNhNDrod0HDh1/VxJRmsffThzeHJlQ==", "dev": true, "requires": { @@ -3738,24 +4745,40 @@ }, "safe-buffer": { "version": "5.1.2", + "resolved": false, "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "safe-regex": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { "ret": "~0.1.10" } }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "semver": { "version": "5.7.1", + "resolved": false, "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "semver-greatest-satisfied-range": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", "dev": true, "requires": { @@ -3764,11 +4787,13 @@ }, "set-blocking": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "set-value": { "version": "2.0.1", + "resolved": false, "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { @@ -3780,6 +4805,7 @@ "dependencies": { "extend-shallow": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -3790,6 +4816,7 @@ }, "shebang-command": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { @@ -3798,22 +4825,26 @@ }, "shebang-regex": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shelljs": { "version": "0.3.0", + "resolved": false, "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", "dev": true }, "signal-exit": { "version": "3.0.3", + "resolved": false, "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "sinon": { - "version": "9.2.0", - "integrity": "sha512-eSNXz1XMcGEMHw08NJXSyTHIu6qTCOiN8x9ODACmZpNQpr0aXTBXBnI4xTzQzR+TEpOmLiKowGf9flCuKIzsbw==", + "version": "9.2.1", + "resolved": false, + "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==", "dev": true, "requires": { "@sinonjs/commons": "^1.8.1", @@ -3827,16 +4858,19 @@ "dependencies": { "diff": { "version": "4.0.2", + "resolved": false, "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "has-flag": { "version": "4.0.0", + "resolved": false, "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", + "resolved": false, "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { @@ -3847,11 +4881,13 @@ }, "slash": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, "snapdragon": { "version": "0.8.2", + "resolved": false, "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { @@ -3867,6 +4903,7 @@ "dependencies": { "define-property": { "version": "0.2.5", + "resolved": false, "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -3875,6 +4912,7 @@ }, "extend-shallow": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { @@ -3885,6 +4923,7 @@ }, "snapdragon-node": { "version": "2.1.1", + "resolved": false, "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { @@ -3895,6 +4934,7 @@ "dependencies": { "define-property": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { @@ -3903,6 +4943,7 @@ }, "is-accessor-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { @@ -3911,6 +4952,7 @@ }, "is-data-descriptor": { "version": "1.0.0", + "resolved": false, "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { @@ -3919,6 +4961,7 @@ }, "is-descriptor": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { @@ -3931,6 +4974,7 @@ }, "snapdragon-util": { "version": "3.0.1", + "resolved": false, "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { @@ -3939,6 +4983,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -3949,6 +4994,7 @@ }, "sort-keys": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", "dev": true, "requires": { @@ -3957,11 +5003,13 @@ }, "source-map": { "version": "0.5.7", + "resolved": false, "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-resolve": { "version": "0.5.3", + "resolved": false, "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "requires": { @@ -3974,16 +5022,19 @@ }, "source-map-url": { "version": "0.4.0", + "resolved": false, "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, "sparkles": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", "dev": true }, "spdx-correct": { "version": "3.1.1", + "resolved": false, "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { @@ -3993,11 +5044,13 @@ }, "spdx-exceptions": { "version": "2.3.0", + "resolved": false, "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { "version": "3.0.1", + "resolved": false, "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { @@ -4007,11 +5060,13 @@ }, "spdx-license-ids": { "version": "3.0.5", + "resolved": false, "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "split-string": { "version": "3.1.0", + "resolved": false, "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { @@ -4020,16 +5075,36 @@ }, "sprintf-js": { "version": "1.0.3", + "resolved": false, "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, "stack-trace": { "version": "0.0.10", + "resolved": false, "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", "dev": true }, "static-extend": { "version": "0.1.2", + "resolved": false, "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { @@ -4039,6 +5114,7 @@ "dependencies": { "define-property": { "version": "0.2.5", + "resolved": false, "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { @@ -4047,18 +5123,27 @@ } } }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, "stream-exhaust": { "version": "1.0.2", + "resolved": false, "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", "dev": true }, "stream-shift": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, "string-width": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -4068,17 +5153,19 @@ } }, "string.prototype.trimend": { - "version": "1.0.1", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.2", + "resolved": false, + "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "es-abstract": "^1.18.0-next.1" }, "dependencies": { "es-abstract": { - "version": "1.17.7", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "version": "1.18.0-next.1", + "resolved": false, + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", @@ -4086,6 +5173,7 @@ "has": "^1.0.3", "has-symbols": "^1.0.1", "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", "is-regex": "^1.1.1", "object-inspect": "^1.8.0", "object-keys": "^1.1.1", @@ -4097,17 +5185,19 @@ } }, "string.prototype.trimstart": { - "version": "1.0.1", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.2", + "resolved": false, + "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "es-abstract": "^1.18.0-next.1" }, "dependencies": { "es-abstract": { - "version": "1.17.7", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "version": "1.18.0-next.1", + "resolved": false, + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", @@ -4115,6 +5205,7 @@ "has": "^1.0.3", "has-symbols": "^1.0.1", "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", "is-regex": "^1.1.1", "object-inspect": "^1.8.0", "object-keys": "^1.1.1", @@ -4127,6 +5218,7 @@ }, "string_decoder": { "version": "1.1.1", + "resolved": false, "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { @@ -4135,6 +5227,7 @@ }, "strip-ansi": { "version": "3.0.1", + "resolved": false, "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -4143,6 +5236,7 @@ }, "strip-bom": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { @@ -4151,6 +5245,7 @@ }, "strip-bom-buf": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", "dev": true, "requires": { @@ -4159,6 +5254,7 @@ }, "strip-bom-stream": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=", "dev": true, "requires": { @@ -4168,16 +5264,19 @@ }, "strip-final-newline": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, "strip-json-comments": { "version": "2.0.1", + "resolved": false, "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "supports-color": { "version": "3.2.3", + "resolved": false, "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { @@ -4186,6 +5285,7 @@ }, "sver-compat": { "version": "1.5.0", + "resolved": false, "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", "dev": true, "requires": { @@ -4193,13 +5293,21 @@ "es6-symbol": "^3.1.1" } }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "textextensions": { "version": "2.6.0", + "resolved": false, "integrity": "sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==", "dev": true }, "through2": { "version": "2.0.5", + "resolved": false, "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { @@ -4209,6 +5317,7 @@ }, "through2-filter": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "dev": true, "requires": { @@ -4218,11 +5327,13 @@ }, "time-stamp": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", "dev": true }, "to-absolute-glob": { "version": "2.0.2", + "resolved": false, "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", "dev": true, "requires": { @@ -4232,6 +5343,7 @@ }, "to-object-path": { "version": "0.3.0", + "resolved": false, "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { @@ -4240,6 +5352,7 @@ "dependencies": { "kind-of": { "version": "3.2.2", + "resolved": false, "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { @@ -4250,6 +5363,7 @@ }, "to-regex": { "version": "3.0.2", + "resolved": false, "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { @@ -4261,6 +5375,7 @@ }, "to-regex-range": { "version": "2.1.1", + "resolved": false, "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { @@ -4270,19 +5385,56 @@ }, "to-through": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", "dev": true, "requires": { "through2": "^2.0.3" } }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, "type": { "version": "1.2.0", + "resolved": false, "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", "dev": true }, "type-check": { "version": "0.3.2", + "resolved": false, "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { @@ -4291,31 +5443,37 @@ }, "type-detect": { "version": "4.0.8", + "resolved": false, "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "typedarray": { "version": "0.0.6", + "resolved": false, "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "typescript": { "version": "3.0.1", + "resolved": false, "integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==", "dev": true }, "uglify-js": { - "version": "3.11.2", - "integrity": "sha512-G440NU6fewtnQftSgqRV1r2A5ChKbU1gqFCJ7I8S7MPpY/eZZfLGefaY6gUZYiWebMaO+txgiQ1ZyLDuNWJulg==", + "version": "3.11.6", + "resolved": false, + "integrity": "sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==", "dev": true }, "unc-path-regex": { "version": "0.1.2", + "resolved": false, "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, "undertaker": { "version": "1.3.0", + "resolved": false, "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", "dev": true, "requires": { @@ -4333,11 +5491,13 @@ }, "undertaker-registry": { "version": "1.0.1", + "resolved": false, "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", "dev": true }, "union-value": { "version": "1.0.1", + "resolved": false, "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { @@ -4349,6 +5509,7 @@ }, "unique-stream": { "version": "2.3.1", + "resolved": false, "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", "dev": true, "requires": { @@ -4358,6 +5519,7 @@ }, "unset-value": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { @@ -4367,6 +5529,7 @@ "dependencies": { "has-value": { "version": "0.3.1", + "resolved": false, "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { @@ -4377,6 +5540,7 @@ "dependencies": { "isobject": { "version": "2.1.0", + "resolved": false, "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { @@ -4387,6 +5551,7 @@ }, "has-values": { "version": "0.1.4", + "resolved": false, "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true } @@ -4394,26 +5559,46 @@ }, "upath": { "version": "1.2.0", + "resolved": false, "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", + "resolved": false, "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, "use": { "version": "3.1.1", + "resolved": false, "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, "util-deprecate": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, "v8flags": { "version": "3.2.0", + "resolved": false, "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", "dev": true, "requires": { @@ -4422,6 +5607,7 @@ }, "validate-npm-package-license": { "version": "3.0.4", + "resolved": false, "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { @@ -4431,11 +5617,24 @@ }, "value-or-function": { "version": "3.0.0", + "resolved": false, "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", "dev": true }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "vinyl": { "version": "2.2.1", + "resolved": false, "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", "dev": true, "requires": { @@ -4449,6 +5648,7 @@ }, "vinyl-file": { "version": "3.0.0", + "resolved": false, "integrity": "sha1-sQTZ5ECf+jJfqt1SBkLQo7SIs2U=", "dev": true, "requires": { @@ -4461,6 +5661,7 @@ }, "vinyl-fs": { "version": "3.0.3", + "resolved": false, "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", "dev": true, "requires": { @@ -4485,6 +5686,7 @@ }, "vinyl-sourcemap": { "version": "1.1.0", + "resolved": false, "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", "dev": true, "requires": { @@ -4499,6 +5701,7 @@ "dependencies": { "normalize-path": { "version": "2.1.1", + "resolved": false, "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { @@ -4509,14 +5712,57 @@ }, "vinyl-sourcemaps-apply": { "version": "0.2.1", + "resolved": false, "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", "dev": true, "requires": { "source-map": "^0.5.1" } }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "which": { "version": "1.3.1", + "resolved": false, "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { @@ -4525,11 +5771,13 @@ }, "which-module": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, "wide-align": { "version": "1.1.3", + "resolved": false, "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "requires": { @@ -4538,16 +5786,19 @@ }, "word-wrap": { "version": "1.2.3", + "resolved": false, "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wordwrap": { "version": "1.0.0", + "resolved": false, "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "wrap-ansi": { "version": "2.1.0", + "resolved": false, "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { @@ -4557,21 +5808,40 @@ }, "wrappy": { "version": "1.0.2", + "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, "xtend": { "version": "4.0.2", + "resolved": false, "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, "y18n": { "version": "3.2.1", + "resolved": false, "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, "yargs": { "version": "7.1.1", + "resolved": false, "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", "dev": true, "requires": { @@ -4592,6 +5862,7 @@ }, "yargs-parser": { "version": "5.0.0-security.0", + "resolved": false, "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", "dev": true, "requires": { @@ -4601,6 +5872,7 @@ }, "yargs-unparser": { "version": "1.6.0", + "resolved": false, "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, "requires": { @@ -4611,16 +5883,19 @@ "dependencies": { "ansi-regex": { "version": "4.1.0", + "resolved": false, "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "camelcase": { "version": "5.3.1", + "resolved": false, "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "cliui": { "version": "5.0.0", + "resolved": false, "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { @@ -4631,6 +5906,7 @@ }, "find-up": { "version": "3.0.0", + "resolved": false, "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { @@ -4639,21 +5915,25 @@ }, "get-caller-file": { "version": "2.0.5", + "resolved": false, "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "require-main-filename": { "version": "2.0.0", + "resolved": false, "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "string-width": { "version": "3.1.0", + "resolved": false, "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { @@ -4664,6 +5944,7 @@ }, "strip-ansi": { "version": "5.2.0", + "resolved": false, "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { @@ -4672,11 +5953,13 @@ }, "which-module": { "version": "2.0.0", + "resolved": false, "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "wrap-ansi": { "version": "5.1.0", + "resolved": false, "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { @@ -4687,11 +5970,13 @@ }, "y18n": { "version": "4.0.0", + "resolved": false, "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, "yargs": { "version": "13.3.2", + "resolved": false, "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { @@ -4709,6 +5994,7 @@ }, "yargs-parser": { "version": "13.1.2", + "resolved": false, "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { diff --git a/package.json b/package.json index 6bf93a08..3444160f 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "types": "src/index.d.ts", "repository": { "type": "git", - "url": "git+https://github.com/aws/amazon-connect-streams.git" + "url": "git+https://github.com/amazon-connect/amazon-connect-streams.git" }, "keywords": [ "streams", @@ -51,6 +51,7 @@ "gulp-uglify": "^3.0.0", "gulp-watch": "^5.0.1", "jshint": "^2.9.7", + "mocha-jsdom": "^2.0.0", "pump": "^3.0.0", "sinon": "^9.0.0", "typescript": "3.0.1" diff --git a/release/connect-streams-min.js b/release/connect-streams-min.js index 13b23f1e..0cabd284 100644 --- a/release/connect-streams-min.js +++ b/release/connect-streams-min.js @@ -1 +1 @@ -!function r(o,i,s){function a(t,e){if(!i[t]){if(!o[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(c)return c(t,!0);throw(n=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",n}n=i[t]={exports:{}},o[t][0].call(n.exports,function(e){return a(o[t][1][e]||e)},n,n.exports,r,o,i,s)}return i[t].exports}for(var c="function"==typeof require&&require,e=0;ee.BLOCK_SIZE&&((t=new e).update(n),n=t.digest())}e=new Uint8Array(e.BLOCK_SIZE);return e.set(n),e}(e,t),r=new Uint8Array(e.BLOCK_SIZE);r.set(n);for(var o=0;o>>32-o)+n&4294967295}function c(e,t,n,r,o,i,s){return a(t&n|~t&r,e,t,o,i,s)}function u(e,t,n,r,o,i,s){return a(t&r|n&~r,e,t,o,i,s)}function l(e,t,n,r,o,i,s){return a(t^n^r,e,t,o,i,s)}function p(e,t,n,r,o,i,s){return a(n^(t|~r),e,t,o,i,s)}(t.exports=r).BLOCK_SIZE=64,r.prototype.update=function(e){if(o.isEmptyData(e))return this;if(this.finished)throw new Error("Attempted to update an already finished hash.");var t=o.convertToBuffer(e),n=0,r=t.byteLength;for(this.bytesHashed+=r;0>>0,!0),t.setUint32(60,Math.floor(r/4294967296),!0),this.hashBuffer(),this.finished=!0}for(var i=new DataView(new ArrayBuffer(16)),o=0;o<4;o++)i.setUint32(4*o,this.state[o],!0);r=new s(i.buffer,i.byteOffset,i.byteLength);return e?r.toString(e):r},r.prototype.hashBuffer=function(){var e=this.buffer,t=this.state,n=c(n=t[0],i=t[1],o=t[2],r=t[3],e.getUint32(0,!0),7,3614090360),r=c(r,n,i,o,e.getUint32(4,!0),12,3905402710),o=c(o,r,n,i,e.getUint32(8,!0),17,606105819),i=c(i,o,r,n,e.getUint32(12,!0),22,3250441966);n=c(n,i,o,r,e.getUint32(16,!0),7,4118548399),r=c(r,n,i,o,e.getUint32(20,!0),12,1200080426),o=c(o,r,n,i,e.getUint32(24,!0),17,2821735955),i=c(i,o,r,n,e.getUint32(28,!0),22,4249261313),n=c(n,i,o,r,e.getUint32(32,!0),7,1770035416),r=c(r,n,i,o,e.getUint32(36,!0),12,2336552879),o=c(o,r,n,i,e.getUint32(40,!0),17,4294925233),i=c(i,o,r,n,e.getUint32(44,!0),22,2304563134),n=c(n,i,o,r,e.getUint32(48,!0),7,1804603682),r=c(r,n,i,o,e.getUint32(52,!0),12,4254626195),o=c(o,r,n,i,e.getUint32(56,!0),17,2792965006),n=u(n,i=c(i,o,r,n,e.getUint32(60,!0),22,1236535329),o,r,e.getUint32(4,!0),5,4129170786),r=u(r,n,i,o,e.getUint32(24,!0),9,3225465664),o=u(o,r,n,i,e.getUint32(44,!0),14,643717713),i=u(i,o,r,n,e.getUint32(0,!0),20,3921069994),n=u(n,i,o,r,e.getUint32(20,!0),5,3593408605),r=u(r,n,i,o,e.getUint32(40,!0),9,38016083),o=u(o,r,n,i,e.getUint32(60,!0),14,3634488961),i=u(i,o,r,n,e.getUint32(16,!0),20,3889429448),n=u(n,i,o,r,e.getUint32(36,!0),5,568446438),r=u(r,n,i,o,e.getUint32(56,!0),9,3275163606),o=u(o,r,n,i,e.getUint32(12,!0),14,4107603335),i=u(i,o,r,n,e.getUint32(32,!0),20,1163531501),n=u(n,i,o,r,e.getUint32(52,!0),5,2850285829),r=u(r,n,i,o,e.getUint32(8,!0),9,4243563512),o=u(o,r,n,i,e.getUint32(28,!0),14,1735328473),n=l(n,i=u(i,o,r,n,e.getUint32(48,!0),20,2368359562),o,r,e.getUint32(20,!0),4,4294588738),r=l(r,n,i,o,e.getUint32(32,!0),11,2272392833),o=l(o,r,n,i,e.getUint32(44,!0),16,1839030562),i=l(i,o,r,n,e.getUint32(56,!0),23,4259657740),n=l(n,i,o,r,e.getUint32(4,!0),4,2763975236),r=l(r,n,i,o,e.getUint32(16,!0),11,1272893353),o=l(o,r,n,i,e.getUint32(28,!0),16,4139469664),i=l(i,o,r,n,e.getUint32(40,!0),23,3200236656),n=l(n,i,o,r,e.getUint32(52,!0),4,681279174),r=l(r,n,i,o,e.getUint32(0,!0),11,3936430074),o=l(o,r,n,i,e.getUint32(12,!0),16,3572445317),i=l(i,o,r,n,e.getUint32(24,!0),23,76029189),n=l(n,i,o,r,e.getUint32(36,!0),4,3654602809),r=l(r,n,i,o,e.getUint32(48,!0),11,3873151461),o=l(o,r,n,i,e.getUint32(60,!0),16,530742520),n=p(n,i=l(i,o,r,n,e.getUint32(8,!0),23,3299628645),o,r,e.getUint32(0,!0),6,4096336452),r=p(r,n,i,o,e.getUint32(28,!0),10,1126891415),o=p(o,r,n,i,e.getUint32(56,!0),15,2878612391),i=p(i,o,r,n,e.getUint32(20,!0),21,4237533241),n=p(n,i,o,r,e.getUint32(48,!0),6,1700485571),r=p(r,n,i,o,e.getUint32(12,!0),10,2399980690),o=p(o,r,n,i,e.getUint32(40,!0),15,4293915773),i=p(i,o,r,n,e.getUint32(4,!0),21,2240044497),n=p(n,i,o,r,e.getUint32(32,!0),6,1873313359),r=p(r,n,i,o,e.getUint32(60,!0),10,4264355552),o=p(o,r,n,i,e.getUint32(24,!0),15,2734768916),i=p(i,o,r,n,e.getUint32(52,!0),21,1309151649),n=p(n,i,o,r,e.getUint32(16,!0),6,4149444226),r=p(r,n,i,o,e.getUint32(44,!0),10,3174756917),o=p(o,r,n,i,e.getUint32(8,!0),15,718787259),i=p(i,o,r,n,e.getUint32(36,!0),21,3951481745),t[0]=n+t[0]&4294967295,t[1]=i+t[1]&4294967295,t[2]=o+t[2]&4294967295,t[3]=r+t[3]&4294967295}},{"./browserHashUtils":11,"buffer/":80}],14:[function(e,t,n){var o=e("buffer/").Buffer,r=e("./browserHashUtils");new Uint32Array([1518500249,1859775393,-1894007588,-899497514]),Math.pow(2,53);function i(){this.h0=1732584193,this.h1=4023233417,this.h2=2562383102,this.h3=271733878,this.h4=3285377520,this.block=new Uint32Array(80),this.offset=0,this.shift=24,this.totalLength=0}(t.exports=i).BLOCK_SIZE=64,i.prototype.update=function(e){if(this.finished)throw new Error("Attempted to update an already finished hash.");if(r.isEmptyData(e))return this;var t=(e=r.convertToBuffer(e)).length;this.totalLength+=8*t;for(var n=0;n>t);var n=new o(20),r=new DataView(n.buffer);return r.setUint32(0,this.h0,!1),r.setUint32(4,this.h1,!1),r.setUint32(8,this.h2,!1),r.setUint32(12,this.h3,!1),r.setUint32(16,this.h4,!1),e?n.toString(e):n},i.prototype.processBlock=function(){for(var e=16;e<80;e++){var t=this.block[e-3]^this.block[e-8]^this.block[e-14]^this.block[e-16];this.block[e]=t<<1|t>>>31}for(var n,r=this.h0,o=this.h1,i=this.h2,s=this.h3,a=this.h4,e=0;e<80;e++){c=e<20?(n=s^o&(i^s),1518500249):e<40?(n=o^i^s,1859775393):e<60?(n=o&i|s&(o|i),2400959708):(n=o^i^s,3395469782);var c=(r<<5|r>>>27)+n+a+c+(0|this.block[e]),a=s,s=i,i=o<<30|o>>>2,o=r,r=c}for(this.h0=this.h0+r|0,this.h1=this.h1+o|0,this.h2=this.h2+i|0,this.h3=this.h3+s|0,this.h4=this.h4+a|0,e=this.offset=0;e<16;e++)this.block[e]=0}},{"./browserHashUtils":11,"buffer/":80}],15:[function(e,t,n){var s=e("buffer/").Buffer,r=e("./browserHashUtils"),f=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),o=Math.pow(2,53)-1;function i(){this.state=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],this.temp=new Int32Array(64),this.buffer=new Uint8Array(64),this.bufferLength=0,this.bytesHashed=0,this.finished=!1}(t.exports=i).BLOCK_SIZE=64,i.prototype.update=function(e){if(this.finished)throw new Error("Attempted to update an already finished hash.");if(r.isEmptyData(e))return this;var t=0,n=(e=r.convertToBuffer(e)).byteLength;if(this.bytesHashed+=n,8*this.bytesHashed>o)throw new Error("Cannot hash more than 2^53 - 1 bits");for(;0>>24&255,i[4*o+1]=this.state[o]>>>16&255,i[4*o+2]=this.state[o]>>>8&255,i[4*o+3]=this.state[o]>>>0&255;return e?i.toString(e):i},i.prototype.hashBuffer=function(){for(var e=this.buffer,t=this.state,n=t[0],r=t[1],o=t[2],i=t[3],s=t[4],a=t[5],c=t[6],u=t[7],l=0;l<64;l++){l<16?this.temp[l]=(255&e[4*l])<<24|(255&e[4*l+1])<<16|(255&e[4*l+2])<<8|255&e[4*l+3]:(p=((h=this.temp[l-2])>>>17|h<<15)^(h>>>19|h<<13)^h>>>10,h=((h=this.temp[l-15])>>>7|h<<25)^(h>>>18|h<<14)^h>>>3,this.temp[l]=(p+this.temp[l-7]|0)+(h+this.temp[l-16]|0));var p=(((s>>>6|s<<26)^(s>>>11|s<<21)^(s>>>25|s<<7))+(s&a^~s&c)|0)+(u+(f[l]+this.temp[l]|0)|0)|0,h=((n>>>2|n<<30)^(n>>>13|n<<19)^(n>>>22|n<<10))+(n&r^n&o^r&o)|0,u=c,c=a,a=s,s=i+p|0,i=o,o=r,r=n,n=p+h|0}t[0]+=n,t[1]+=r,t[2]+=o,t[3]+=i,t[4]+=s,t[5]+=a,t[6]+=c,t[7]+=u}},{"./browserHashUtils":11,"buffer/":80}],16:[function(n,r,e){(function(e){var t=n("./util");t.crypto.lib=n("./browserCryptoLib"),t.Buffer=n("buffer/").Buffer,t.url=n("url/"),t.querystring=n("querystring/"),t.realClock=n("./realclock/browserClock"),t.environment="js",t.createEventStream=n("./event-stream/buffered-create-event-stream").createEventStream,t.isBrowser=function(){return!0},t.isNode=function(){return!1};t=n("./core");r.exports=t,n("./credentials"),n("./credentials/credential_provider_chain"),n("./credentials/temporary_credentials"),n("./credentials/chainable_temporary_credentials"),n("./credentials/web_identity_credentials"),n("./credentials/cognito_identity_credentials"),n("./credentials/saml_credentials"),t.XML.Parser=n("./xml/browser_parser"),n("./http/xhr"),void 0===e&&(e={browser:!0})}).call(this,n("_process"))},{"./browserCryptoLib":10,"./core":18,"./credentials":19,"./credentials/chainable_temporary_credentials":20,"./credentials/cognito_identity_credentials":21,"./credentials/credential_provider_chain":22,"./credentials/saml_credentials":23,"./credentials/temporary_credentials":24,"./credentials/web_identity_credentials":25,"./event-stream/buffered-create-event-stream":27,"./http/xhr":35,"./realclock/browserClock":52,"./util":71,"./xml/browser_parser":72,_process:85,"buffer/":80,"querystring/":92,"url/":94}],17:[function(e,t,n){var r,i=e("./core");e("./credentials"),e("./credentials/credential_provider_chain"),i.Config=i.util.inherit({constructor:function(n){void 0===n&&(n={}),n=this.extractCredentials(n),i.util.each.call(this,this.keys,function(e,t){this.set(e,n[e],t)})},getCredentials:function(t){var e,n=this;function r(e){t(e,e?null:n.credentials)}function o(e,t){return new i.util.error(t||new Error,{code:"CredentialsError",message:e,name:"CredentialsError"})}n.credentials?"function"==typeof n.credentials.get?n.credentials.get(function(e){r(e=e&&o("Could not load credentials from "+n.credentials.constructor.name,e))}):(e=null,n.credentials.accessKeyId&&n.credentials.secretAccessKey||(e=o("Missing credentials")),r(e)):n.credentialProvider?n.credentialProvider.resolve(function(e,t){e=e&&o("Could not load credentials from any providers",e),n.credentials=t,r(e)}):r(o("No credentials to load"))},update:function(e,n){n=n||!1,e=this.extractCredentials(e),i.util.each.call(this,e,function(e,t){(n||Object.prototype.hasOwnProperty.call(this.keys,e)||i.Service.hasService(e))&&this.set(e,t)})},loadFromPath:function(e){this.clear();var n=JSON.parse(i.util.readFileSync(e)),t=new i.FileSystemCredentials(e),e=new i.CredentialProviderChain;return e.providers.unshift(t),e.resolve(function(e,t){if(e)throw e;n.credentials=t}),this.constructor(n),this},clear:function(){i.util.each.call(this,this.keys,function(e){delete this[e]}),this.set("credentials",void 0),this.set("credentialProvider",void 0)},set:function(e,t,n){void 0===t?(void 0===n&&(n=this.keys[e]),this[e]="function"==typeof n?n.call(this):n):"httpOptions"===e&&this[e]?this[e]=i.util.merge(this[e],t):this[e]=t},keys:{credentials:null,credentialProvider:null,region:null,logger:null,apiVersions:{},apiVersion:null,endpoint:void 0,httpOptions:{timeout:12e4},maxRetries:void 0,maxRedirects:10,paramValidation:!0,sslEnabled:!0,s3ForcePathStyle:!1,s3BucketEndpoint:!1,s3DisableBodySigning:!0,computeChecksums:!0,convertResponseTypes:!0,correctClockSkew:!1,customUserAgent:null,dynamoDbCrc32:!0,systemClockOffset:0,signatureVersion:null,signatureCache:!0,retryDelayOptions:{},useAccelerateEndpoint:!1,clientSideMonitoring:!1,endpointDiscoveryEnabled:!1,endpointCacheSize:1e3,hostPrefixEnabled:!0,stsRegionalEndpoints:null},extractCredentials:function(e){return e.accessKeyId&&e.secretAccessKey&&((e=i.util.copy(e)).credentials=new i.Credentials(e)),e},setPromisesDependency:function(e){null===(r=e)&&"function"==typeof Promise&&(r=Promise);e=[i.Request,i.Credentials,i.CredentialProviderChain];i.S3&&(e.push(i.S3),i.S3.ManagedUpload&&e.push(i.S3.ManagedUpload)),i.util.addPromises(e,r)},getPromisesDependency:function(){return r}}),i.config=new i.Config},{"./core":18,"./credentials":19,"./credentials/credential_provider_chain":22}],18:[function(e,t,n){var r={util:e("./util")};({}).toString(),(t.exports=r).util.update(r,{VERSION:"2.553.0",Signers:{},Protocol:{Json:e("./protocol/json"),Query:e("./protocol/query"),Rest:e("./protocol/rest"),RestJson:e("./protocol/rest_json"),RestXml:e("./protocol/rest_xml")},XML:{Builder:e("./xml/builder"),Parser:null},JSON:{Builder:e("./json/builder"),Parser:e("./json/parser")},Model:{Api:e("./model/api"),Operation:e("./model/operation"),Shape:e("./model/shape"),Paginator:e("./model/paginator"),ResourceWaiter:e("./model/resource_waiter")},apiLoader:e("./api_loader"),EndpointCache:e("../vendor/endpoint-cache").EndpointCache}),e("./sequential_executor"),e("./service"),e("./config"),e("./http"),e("./event_listeners"),e("./request"),e("./response"),e("./resource_waiter"),e("./signers/request_signer"),e("./param_validator"),r.events=new r.SequentialExecutor,r.util.memoizedProperty(r,"endpointCache",function(){return new r.EndpointCache(r.config.endpointCacheSize)},!0)},{"../vendor/endpoint-cache":103,"./api_loader":9,"./config":17,"./event_listeners":33,"./http":34,"./json/builder":36,"./json/parser":37,"./model/api":38,"./model/operation":40,"./model/paginator":41,"./model/resource_waiter":42,"./model/shape":43,"./param_validator":44,"./protocol/json":46,"./protocol/query":47,"./protocol/rest":48,"./protocol/rest_json":49,"./protocol/rest_xml":50,"./request":55,"./resource_waiter":56,"./response":57,"./sequential_executor":58,"./service":59,"./signers/request_signer":63,"./util":71,"./xml/builder":73}],19:[function(e,t,n){var o=e("./core");o.Credentials=o.util.inherit({constructor:function(e,t,n){var r;o.util.hideProperties(this,["secretAccessKey"]),this.expired=!1,this.expireTime=null,this.refreshCallbacks=[],1===arguments.length&&"object"==typeof e?(r=e.credentials||e,this.accessKeyId=r.accessKeyId,this.secretAccessKey=r.secretAccessKey,this.sessionToken=r.sessionToken):(this.accessKeyId=e,this.secretAccessKey=t,this.sessionToken=n)},expiryWindow:15,needsRefresh:function(){var e=o.util.date.getDate().getTime(),e=new Date(e+1e3*this.expiryWindow);return!!(this.expireTime&&e>this.expireTime)||(this.expired||!this.accessKeyId||!this.secretAccessKey)},get:function(t){var n=this;this.needsRefresh()?this.refresh(function(e){e||(n.expired=!1),t&&t(e)}):t&&t()},refresh:function(e){this.expired=!1,e()},coalesceRefresh:function(e,n){var r=this;1===r.refreshCallbacks.push(e)&&r.load(function(t){o.util.arrayEach(r.refreshCallbacks,function(e){n?e(t):o.util.defer(function(){e(t)})}),r.refreshCallbacks.length=0})},load:function(e){e()}}),o.Credentials.addPromisesToClass=function(e){this.prototype.getPromise=o.util.promisifyMethod("get",e),this.prototype.refreshPromise=o.util.promisifyMethod("refresh",e)},o.Credentials.deletePromisesFromClass=function(){delete this.prototype.getPromise,delete this.prototype.refreshPromise},o.util.addPromises(o.Credentials)},{"./core":18}],20:[function(e,t,n){var i=e("../core"),r=e("../../clients/sts");i.ChainableTemporaryCredentials=i.util.inherit(i.Credentials,{constructor:function(e){i.Credentials.call(this),e=e||{},this.errorCode="ChainableTemporaryCredentialsProviderFailure",this.expired=!0,this.tokenCodeFn=null;var t=i.util.copy(e.params)||{};if(t.RoleArn&&(t.RoleSessionName=t.RoleSessionName||"temporary-credentials"),t.SerialNumber){if(!e.tokenCodeFn||"function"!=typeof e.tokenCodeFn)throw new i.util.error(new Error("tokenCodeFn must be a function when params.SerialNumber is given"),{code:this.errorCode});this.tokenCodeFn=e.tokenCodeFn}e=i.util.merge({params:t,credentials:e.masterCredentials||i.config.credentials},e.stsConfig||{});this.service=new r(e)},refresh:function(e){this.coalesceRefresh(e||i.util.fn.callback)},load:function(r){var o=this,i=o.service.config.params.RoleArn?"assumeRole":"getSessionToken";this.getTokenCode(function(e,t){var n={};e?r(e):(t&&(n.TokenCode=t),o.service[i](n,function(e,t){e||o.service.credentialsFrom(t,o),r(e)}))})},getTokenCode:function(r){var o=this;this.tokenCodeFn?this.tokenCodeFn(this.service.config.params.SerialNumber,function(e,t){if(e){var n=e;return e instanceof Error&&(n=e.message),void r(i.util.error(new Error("Error fetching MFA token: "+n),{code:o.errorCode}))}r(null,t)}):r(null)}})},{"../../clients/sts":8,"../core":18}],21:[function(e,t,n){var r=e("../core"),o=e("../../clients/cognitoidentity"),i=e("../../clients/sts");r.CognitoIdentityCredentials=r.util.inherit(r.Credentials,{localStorageKey:{id:"aws.cognito.identity-id.",providers:"aws.cognito.identity-providers."},constructor:function(e,t){r.Credentials.call(this),this.expired=!0,this.params=e,this.data=null,this._identityId=null,this._clientConfig=r.util.copy(t||{}),this.loadCachedId();var n=this;Object.defineProperty(this,"identityId",{get:function(){return n.loadCachedId(),n._identityId||n.params.IdentityId},set:function(e){n._identityId=e}})},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(t){var n=this;n.createClients(),n.data=null,n._identityId=null,n.getId(function(e){e?(n.clearIdOnNotAuthorized(e),t(e)):n.params.RoleArn?n.getCredentialsFromSTS(t):n.getCredentialsForIdentity(t)})},clearCachedId:function(){this._identityId=null,delete this.params.IdentityId;var e=this.params.IdentityPoolId,t=this.params.LoginId||"";delete this.storage[this.localStorageKey.id+e+t],delete this.storage[this.localStorageKey.providers+e+t]},clearIdOnNotAuthorized:function(e){"NotAuthorizedException"==e.code&&this.clearCachedId()},getId:function(n){var r=this;if("string"==typeof r.params.IdentityId)return n(null,r.params.IdentityId);r.cognito.getId(function(e,t){!e&&t.IdentityId?(r.params.IdentityId=t.IdentityId,n(null,t.IdentityId)):n(e)})},loadCredentials:function(e,t){e&&t&&(t.expired=!1,t.accessKeyId=e.Credentials.AccessKeyId,t.secretAccessKey=e.Credentials.SecretKey,t.sessionToken=e.Credentials.SessionToken,t.expireTime=e.Credentials.Expiration)},getCredentialsForIdentity:function(n){var r=this;r.cognito.getCredentialsForIdentity(function(e,t){e?r.clearIdOnNotAuthorized(e):(r.cacheId(t),r.data=t,r.loadCredentials(r.data,r)),n(e)})},getCredentialsFromSTS:function(n){var r=this;r.cognito.getOpenIdToken(function(e,t){e?(r.clearIdOnNotAuthorized(e),n(e)):(r.cacheId(t),r.params.WebIdentityToken=t.Token,r.webIdentityCredentials.refresh(function(e){e||(r.data=r.webIdentityCredentials.data,r.sts.credentialsFrom(r.data,r)),n(e)}))})},loadCachedId:function(){var e,t,n=this;r.util.isBrowser()&&!n.params.IdentityId&&((e=n.getStorage("id"))&&n.params.Logins?(t=Object.keys(n.params.Logins),0!==(n.getStorage("providers")||"").split(",").filter(function(e){return-1!==t.indexOf(e)}).length&&(n.params.IdentityId=e)):e&&(n.params.IdentityId=e))},createClients:function(){var e,t=this._clientConfig;this.webIdentityCredentials=this.webIdentityCredentials||new r.WebIdentityCredentials(this.params,t),this.cognito||((e=r.util.merge({},t)).params=this.params,this.cognito=new o(e)),this.sts=this.sts||new i(t)},cacheId:function(e){this._identityId=e.IdentityId,this.params.IdentityId=this._identityId,r.util.isBrowser()&&(this.setStorage("id",e.IdentityId),this.params.Logins&&this.setStorage("providers",Object.keys(this.params.Logins).join(",")))},getStorage:function(e){return this.storage[this.localStorageKey[e]+this.params.IdentityPoolId+(this.params.LoginId||"")]},setStorage:function(e,t){try{this.storage[this.localStorageKey[e]+this.params.IdentityPoolId+(this.params.LoginId||"")]=t}catch(e){}},storage:function(){try{var e=r.util.isBrowser()&&null!==window.localStorage&&"object"==typeof window.localStorage?window.localStorage:{};return e["aws.test-storage"]="foobar",delete e["aws.test-storage"],e}catch(e){return{}}}()})},{"../../clients/cognitoidentity":7,"../../clients/sts":8,"../core":18}],22:[function(e,t,n){var a=e("../core");a.CredentialProviderChain=a.util.inherit(a.Credentials,{constructor:function(e){this.providers=e||a.CredentialProviderChain.defaultProviders.slice(0),this.resolveCallbacks=[]},resolve:function(e){var o,i,s=this;return 0===s.providers.length?e(new Error("No providers")):1===s.resolveCallbacks.push(e)&&(o=0,i=s.providers.slice(0),function t(n,r){if(!n&&r||o===i.length)return a.util.arrayEach(s.resolveCallbacks,function(e){e(n,r)}),void(s.resolveCallbacks.length=0);var e=i[o++];(r="function"==typeof e?e.call():e).get?r.get(function(e){t(e,e?null:r)}):t(null,r)}()),s}}),a.CredentialProviderChain.defaultProviders=[],a.CredentialProviderChain.addPromisesToClass=function(e){this.prototype.resolvePromise=a.util.promisifyMethod("resolve",e)},a.CredentialProviderChain.deletePromisesFromClass=function(){delete this.prototype.resolvePromise},a.util.addPromises(a.CredentialProviderChain)},{"../core":18}],23:[function(e,t,n){var r=e("../core"),o=e("../../clients/sts");r.SAMLCredentials=r.util.inherit(r.Credentials,{constructor:function(e){r.Credentials.call(this),this.expired=!0,this.params=e},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(n){var r=this;r.createClients(),r.service.assumeRoleWithSAML(function(e,t){e||r.service.credentialsFrom(t,r),n(e)})},createClients:function(){this.service=this.service||new o({params:this.params})}})},{"../../clients/sts":8,"../core":18}],24:[function(e,t,n){var r=e("../core"),o=e("../../clients/sts");r.TemporaryCredentials=r.util.inherit(r.Credentials,{constructor:function(e,t){r.Credentials.call(this),this.loadMasterCredentials(t),this.expired=!0,this.params=e||{},this.params.RoleArn&&(this.params.RoleSessionName=this.params.RoleSessionName||"temporary-credentials")},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(n){var r=this;r.createClients(),r.masterCredentials.get(function(){r.service.config.credentials=r.masterCredentials,(r.params.RoleArn?r.service.assumeRole:r.service.getSessionToken).call(r.service,function(e,t){e||r.service.credentialsFrom(t,r),n(e)})})},loadMasterCredentials:function(e){for(this.masterCredentials=e||r.config.credentials;this.masterCredentials.masterCredentials;)this.masterCredentials=this.masterCredentials.masterCredentials;"function"!=typeof this.masterCredentials.get&&(this.masterCredentials=new r.Credentials(this.masterCredentials))},createClients:function(){this.service=this.service||new o({params:this.params})}})},{"../../clients/sts":8,"../core":18}],25:[function(e,t,n){var r=e("../core"),o=e("../../clients/sts");r.WebIdentityCredentials=r.util.inherit(r.Credentials,{constructor:function(e,t){r.Credentials.call(this),this.expired=!0,this.params=e,this.params.RoleSessionName=this.params.RoleSessionName||"web-identity",this.data=null,this._clientConfig=r.util.copy(t||{})},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(n){var r=this;r.createClients(),r.service.assumeRoleWithWebIdentity(function(e,t){r.data=null,e||(r.data=t,r.service.credentialsFrom(t,r)),n(e)})},createClients:function(){var e;this.service||((e=r.util.merge({},this._clientConfig)).params=this.params,this.service=new o(e))}})},{"../../clients/sts":8,"../core":18}],26:[function(e,t,n){(function(o){var u=e("./core"),l=e("./util"),i=["AWS_ENABLE_ENDPOINT_DISCOVERY","AWS_ENDPOINT_DISCOVERY_ENABLED"];function p(e){var t=e.service,n=t.api||{},e={};return t.config.region&&(e.region=t.config.region),n.serviceId&&(e.serviceId=n.serviceId),t.config.credentials.accessKeyId&&(e.accessKeyId=t.config.credentials.accessKeyId),e}function h(e,t){var n={};return function r(o,i,s){s&&null!=i&&"structure"===s.type&&s.required&&0=this.HEADERS_RECEIVED&&!u&&(s.statusCode=c.status,s.headers=o.parseHeaders(c.getAllResponseHeaders()),s.emit("headers",s.statusCode,s.headers,c.statusText),u=!0),this.readyState===this.DONE&&o.finishRequest(c,s)},!1),c.upload.addEventListener("progress",function(e){s.emit("sendProgress",e)}),c.addEventListener("progress",function(e){s.emit("receiveProgress",e)},!1),c.addEventListener("timeout",function(){r(l.util.error(new Error("Timeout"),{code:"TimeoutError"}))},!1),c.addEventListener("error",function(){r(l.util.error(new Error("Network Failure"),{code:"NetworkingError"}))},!1),c.addEventListener("abort",function(){r(l.util.error(new Error("Request aborted"),{code:"RequestAbortedError"}))},!1),n(s),c.open(t.method,a,!1!==e.xhrAsync),l.util.each(t.headers,function(e,t){"Content-Length"!==e&&"User-Agent"!==e&&"Host"!==e&&c.setRequestHeader(e,t)}),e.timeout&&!1!==e.xhrAsync&&(c.timeout=e.timeout),e.xhrWithCredentials&&(c.withCredentials=!0);try{c.responseType="arraybuffer"}catch(e){}try{t.body?c.send(t.body):c.send()}catch(e){if(!t.body||"object"!=typeof t.body.buffer)throw e;c.send(t.body.buffer)}return s},parseHeaders:function(e){var n={};return l.util.arrayEach(e.split(/\r?\n/),function(e){var t=e.split(":",1)[0],e=e.substring(t.length+2);0= 1, but found "'+t+'" for '+n)},validatePattern:function(e,t,n){this.validation.pattern&&void 0!==e.pattern&&(new RegExp(e.pattern).test(t)||this.fail("PatternMatchError",'Provided value "'+t+'" does not match regex pattern /'+e.pattern+"/ for "+n))},validateRange:function(e,t,n,r){this.validation.min&&void 0!==e.min&&t= "+e.min+", but found "+t+" for "+n),this.validation.max&&void 0!==e.max&&t>e.max&&this.fail("MaxRangeError","Expected "+r+" <= "+e.max+", but found "+t+" for "+n)},validateEnum:function(e,t,n){this.validation.enum&&void 0!==e.enum&&-1===e.enum.indexOf(t)&&this.fail("EnumError","Found string value of "+t+", but expected "+e.enum.join("|")+" for "+n)},validateType:function(e,t,n,r){if(null==e)return!1;for(var o=!1,i=0;i=e.maxRetries&&(t.MaxRetriesExceeded=1),u.emit("apiCall",[t]))})},setupRequestListeners:function(){},getSignerClass:function(e){var t=null,n="";return e&&(n=(t=(e.service.api.operations||{})[e.operation]||null)?t.authtype:""),n=this.config.signatureVersion||("v4"===n||"v4-unsigned-body"===n?"v4":this.api.signatureVersion),l.Signers.RequestSigner.getVersion(n)},serviceInterface:function(){switch(this.api.protocol){case"ec2":case"query":return l.EventListeners.Query;case"json":return l.EventListeners.Json;case"rest-json":return l.EventListeners.RestJson;case"rest-xml":return l.EventListeners.RestXml}if(this.api.protocol)throw new Error("Invalid service `protocol' "+this.api.protocol+" in API config")},successfulResponse:function(e){return e.httpResponse.statusCode<300},numRetries:function(){return void 0!==this.config.maxRetries?this.config.maxRetries:this.defaultRetryCount},retryDelays:function(e){return l.util.calculateRetryDelay(e,this.config.retryDelayOptions)},retryableError:function(e){return!!this.timeoutError(e)||(!!this.networkingError(e)||(!!this.expiredCredentialsError(e)||(!!this.throttledError(e)||500<=e.statusCode)))},networkingError:function(e){return"NetworkingError"===e.code},timeoutError:function(e){return"TimeoutError"===e.code},expiredCredentialsError:function(e){return"ExpiredTokenException"===e.code},clockSkewError:function(e){switch(e.code){case"RequestTimeTooSkewed":case"RequestExpired":case"InvalidSignatureException":case"SignatureDoesNotMatch":case"AuthFailure":case"RequestInTheFuture":return!0;default:return!1}},getSkewCorrectedDate:function(){return new Date(Date.now()+this.config.systemClockOffset)},applyClockOffset:function(e){e&&(this.config.systemClockOffset=e-Date.now())},isClockSkewed:function(e){if(e)return 3e4<=Math.abs(this.getSkewCorrectedDate().getTime()-e)},throttledError:function(e){if(429===e.statusCode)return!0;switch(e.code){case"ProvisionedThroughputExceededException":case"Throttling":case"ThrottlingException":case"RequestLimitExceeded":case"RequestThrottled":case"RequestThrottledException":case"TooManyRequestsException":case"TransactionInProgressException":return!0;default:return!1}},endpointFromTemplate:function(e){if("string"!=typeof e)return e;return e=(e=(e=e.replace(/\{service\}/g,this.api.endpointPrefix)).replace(/\{region\}/g,this.config.region)).replace(/\{scheme\}/g,this.config.sslEnabled?"https":"http")},setEndpoint:function(e){this.endpoint=new l.Endpoint(e,this.config)},paginationConfig:function(e,t){var n=this.api.operations[e].paginator;if(n)return n;if(t){t=new Error;throw l.util.error(t,"No pagination configuration for "+e)}return null}}),l.util.update(l.Service,{defineMethods:function(e){l.util.each(e.prototype.api.operations,function(n){e.prototype[n]||("none"===e.prototype.api.operations[n].authtype?e.prototype[n]=function(e,t){return this.makeUnauthenticatedRequest(n,e,t)}:e.prototype[n]=function(e,t){return this.makeRequest(n,e,t)})})},defineService:function(e,t,n){l.Service._serviceMap[e]=!0,Array.isArray(t)||(n=t,t=[]);var r,n=s(l.Service,n||{});return"string"==typeof e?(l.Service.addVersions(n,t),r=n.serviceIdentifier||e,n.serviceIdentifier=r):(n.prototype.api=e,l.Service.defineMethods(n)),l.SequentialExecutor.call(this.prototype),!this.prototype.publisher&&l.util.clientSideMonitoring&&(r=l.util.clientSideMonitoring.Publisher,e=(0,l.util.clientSideMonitoring.configProvider)(),this.prototype.publisher=new r(e),e.enabled&&(l.Service._clientSideMonitoring=!0)),l.SequentialExecutor.call(n.prototype),l.Service.addDefaultMonitoringListeners(n.prototype),n},addVersions:function(e,t){Array.isArray(t)||(t=[t]),e.services=e.services||{};for(var n=0;n=t.length)return n.push(null);e=r+e;e>t.length&&(e=t.length),n.push(t.slice(r,e)),r=e},n},concat:function(e){for(var t,n=0,r=0,o=0;o>>8^t[255&(n^e.readUInt8(r))];return(-1^n)>>>0},hmac:function(e,t,n,r){return"buffer"===(n=n||"binary")&&(n=void 0),r=r||"sha256","string"==typeof t&&(t=u.buffer.toBuffer(t)),u.crypto.lib.createHmac(r,e).update(t).digest(n)},md5:function(e,t,n){return u.crypto.hash("md5",e,t,n)},sha256:function(e,t,n){return u.crypto.hash("sha256",e,t,n)},hash:function(e,t,n,r){var o=u.crypto.createHash(e);"buffer"===(n=n||"binary")&&(n=void 0),"string"==typeof t&&(t=u.buffer.toBuffer(t));var i=u.arraySliceFn(t),e=u.Buffer.isBuffer(t);if(u.isBrowser()&&"undefined"!=typeof ArrayBuffer&&t&&t.buffer instanceof ArrayBuffer&&(e=!0),r&&"object"==typeof t&&"function"==typeof t.on&&!e)t.on("data",function(e){o.update(e)}),t.on("error",function(e){r(e)}),t.on("end",function(){r(null,o.digest(n))});else{if(!r||!i||e||"undefined"==typeof FileReader){u.isBrowser()&&"object"==typeof t&&!e&&(t=new u.Buffer(new Uint8Array(t)));e=o.update(t).digest(n);return r&&r(null,e),e}var s=0,a=new FileReader;a.onerror=function(){r(new Error("Failed to read data."))},a.onload=function(){var e=new u.Buffer(new Uint8Array(a.result));o.update(e),s+=e.length,a._continueReading()},a._continueReading=function(){var e;s>=t.size?r(null,o.digest(n)):((e=s+524288)>t.size&&(e=t.size),a.readAsArrayBuffer(i.call(t,s,e)))},a._continueReading()}},toHex:function(e){for(var t=[],n=0;n/g,">").replace(/"/g,""")}}},{}],75:[function(e,t,n){t.exports={escapeElement:function(e){return e.replace(/&/g,"&").replace(//g,">")}}},{}],76:[function(e,t,n){var a=e("./escape-attribute").escapeAttribute;function r(e,t){void 0===t&&(t=[]),this.name=e,this.children=t,this.attributes={}}r.prototype.addAttribute=function(e,t){return this.attributes[e]=t,this},r.prototype.addChildNode=function(e){return this.children.push(e),this},r.prototype.removeAttribute=function(e){return delete this.attributes[e],this},r.prototype.toString=function(){for(var e=Boolean(this.children.length),t="<"+this.name,n=this.attributes,r=0,o=Object.keys(n);r"+this.children.map(function(e){return e.toString()}).join("")+"":"/>")},t.exports={XmlNode:r}},{"./escape-attribute":74}],77:[function(e,t,n){var r=e("./escape-element").escapeElement;function o(e){this.value=e}o.prototype.toString=function(){return r(""+this.value)},t.exports={XmlText:o}},{"./escape-element":75}],78:[function(e,t,n){"use strict";n.byteLength=function(e){var t=l(e),e=t[0],t=t[1];return 3*(e+t)/4-t},n.toByteArray=function(e){var t,n,r=l(e),o=r[0],r=r[1],i=new u(function(e,t){return 3*(e+t)/4-t}(o,r)),s=0,a=0>16&255,i[s++]=t>>8&255,i[s++]=255&t;2===r&&(t=c[e.charCodeAt(n)]<<2|c[e.charCodeAt(n+1)]>>4,i[s++]=255&t);1===r&&(t=c[e.charCodeAt(n)]<<10|c[e.charCodeAt(n+1)]<<4|c[e.charCodeAt(n+2)]>>2,i[s++]=t>>8&255,i[s++]=255&t);return i},n.fromByteArray=function(e){for(var t,n=e.length,r=n%3,o=[],i=0,s=n-r;i>18&63]+a[e>>12&63]+a[e>>6&63]+a[63&e]}(r));return o.join("")}(e,i,s>2]+a[t<<4&63]+"==")):2==r&&(t=(e[n-2]<<8)+e[n-1],o.push(a[t>>10]+a[t>>4&63]+a[t<<2&63]+"="));return o.join("")};for(var a=[],c=[],u="undefined"!=typeof Uint8Array?Uint8Array:Array,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",o=0,i=r.length;o=n())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+n().toString(16)+" bytes");return 0|e}function f(e,t){if(p.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return k(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return N(e).length;default:if(r)return k(e).length;t=(""+t).toLowerCase(),r=!0}}function t(e,t,n){var r,o,i,s=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return function(e,t,n){var r=e.length;(!t||t<0)&&(t=0);(!n||n<0||r=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=p.from(t,r)),p.isBuffer(t))return 0===t.length?-1:m(e,t,n,r,o);if("number"==typeof t)return t&=255,p.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?(o?Uint8Array.prototype.indexOf:Uint8Array.prototype.lastIndexOf).call(e,t,n):m(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function m(e,t,n,r,o){var i=1,s=e.length,a=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;s/=i=2,a/=2,n/=2}function c(e,t){return 1===i?e[t]:e.readUInt16BE(t*i)}if(o)for(var u=-1,l=n;l>8,r=r%256,o.push(r),o.push(n);return o}(t,e.length-n),e,n,r)}function b(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o>>10&1023|55296),l=56320|1023&l),r.push(l),o+=p}return function(e){var t=e.length;if(t<=E)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rt&&(e+=" ... ")),""},p.prototype.compare=function(e,t,n,r,o){if(!p.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(o<=r&&n<=t)return 0;if(o<=r)return-1;if(n<=t)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),s=(n>>>=0)-(t>>>=0),a=Math.min(i,s),c=this.slice(r,o),u=e.slice(t,n),l=0;lthis.length)throw new RangeError("Attempt to write outside buffer bounds");r=r||"utf8";for(var i,s,a,c=!1;;)switch(r){case"hex":return function(e,t,n,r){n=Number(n)||0;var o=e.length-n;if((!r||o<(r=Number(r)))&&(r=o),(o=t.length)%2!=0)throw new TypeError("Invalid hex string");o/2e.length)throw new RangeError("Index out of range")}function T(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function w(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function _(e,t,n,r){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function A(e,t,n,r,o){return o||_(e,0,n,4),i.write(e,t,n,r,23,4),n+4}function I(e,t,n,r,o){return o||_(e,0,n,8),i.write(e,t,n,r,52,8),n+8}p.prototype.slice=function(e,t){var n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):T(this,e,t,!0),t+2},p.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,2,65535,0),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):T(this,e,t,!1),t+2},p.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,4294967295,0),p.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):w(this,e,t,!0),t+4},p.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,4294967295,0),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):w(this,e,t,!1),t+4},p.prototype.writeIntLE=function(e,t,n,r){e=+e,t|=0,r||C(this,e,t,n,(r=Math.pow(2,8*n-1))-1,-r);var o=0,i=1,s=0;for(this[t]=255&e;++o>0)-s&255;return t+n},p.prototype.writeIntBE=function(e,t,n,r){e=+e,t|=0,r||C(this,e,t,n,(r=Math.pow(2,8*n-1))-1,-r);var o=n-1,i=1,s=0;for(this[t+o]=255&e;0<=--o&&(i*=256);)e<0&&0===s&&0!==this[t+o+1]&&(s=1),this[t+o]=(e/i>>0)-s&255;return t+n},p.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,1,127,-128),p.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},p.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,2,32767,-32768),p.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):T(this,e,t,!0),t+2},p.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,2,32767,-32768),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):T(this,e,t,!1),t+2},p.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,2147483647,-2147483648),p.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):w(this,e,t,!0),t+4},p.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):w(this,e,t,!1),t+4},p.prototype.writeFloatLE=function(e,t,n){return A(this,e,t,!0,n)},p.prototype.writeFloatBE=function(e,t,n){return A(this,e,t,!1,n)},p.prototype.writeDoubleLE=function(e,t,n){return I(this,e,t,!0,n)},p.prototype.writeDoubleBE=function(e,t,n){return I(this,e,t,!1,n)},p.prototype.copy=function(e,t,n,r){if(n=n||0,r||0===r||(r=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(a=t;a>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function N(e){return a.toByteArray(function(e){var t;if((e=((t=e).trim?t.trim():t.replace(/^\s+|\s+$/g,"")).replace(R,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function O(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},x("buffer").Buffer)},{"base64-js":78,buffer:80,ieee754:82,isarray:83}],81:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function a(e){return"function"==typeof e}function c(e){return"object"==typeof e&&null!==e}function u(e){return void 0===e}((t.exports=r).EventEmitter=r).prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,o,i;if(this._events||(this._events={}),"error"===e&&(!this._events.error||c(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var s=new Error('Uncaught, unspecified "error" event. ('+t+")");throw s.context=t,s}if(u(s=this._events[e]))return!1;if(a(s))switch(arguments.length){case 1:s.call(this);break;case 2:s.call(this,arguments[1]);break;case 3:s.call(this,arguments[1],arguments[2]);break;default:r=Array.prototype.slice.call(arguments,1),s.apply(this,r)}else if(c(s))for(r=Array.prototype.slice.call(arguments,1),n=(i=s.slice()).length,o=0;on&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},r.prototype.once=function(e,t){if(!a(t))throw TypeError("listener must be a function");var n=!1;function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,o,i;if(!a(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(o=(n=this._events[e]).length,r=-1,n===t||a(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(c(n)){for(i=o;0>1,l=-7,p=n?o-1:0,h=n?-1:1,n=e[t+p];for(p+=h,i=n&(1<<-l)-1,n>>=-l,l+=a;0>=-l,l+=r;0>1,p=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:i-1,f=r?1:-1,i=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=u):(s=Math.floor(Math.log(t)/Math.LN2),t*(r=Math.pow(2,-s))<1&&(s--,r*=2),2<=(t+=1<=s+l?p/r:p*Math.pow(2,1-l))*r&&(s++,r/=2),u<=s+l?(a=0,s=u):1<=s+l?(a=(t*r-1)*Math.pow(2,o),s+=l):(a=t*Math.pow(2,l-1)*Math.pow(2,o),s=0));8<=o;e[n+h]=255&a,h+=f,a/=256,o-=8);for(s=s<":!0,"=":!0,"!":!0},U={" ":!0,"\t":!0,"\n":!0};function q(e){return"0"<=e&&e<="9"||"-"===e}function F(){}F.prototype={tokenize:function(e){var t,n,r,o,i=[];for(this._current=0;this._current"===n?"="===e[this._current]?(this._current++,{type:N,value:">=",start:t}):{type:"GT",value:">",start:t}:"="===n&&"="===e[this._current]?(this._current++,{type:"EQ",value:"==",start:t}):void 0},_consumeLiteral:function(e){this._current++;for(var t=this._current,n=e.length;"`"!==e[this._current]&&this._current= 0x80 (not a basic code point)","invalid-input":"Invalid input"},h=v-b,w=Math.floor,_=String.fromCharCode;function A(e){throw RangeError(p[e])}function f(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function d(e,t){var n=e.split("@"),r="";return 1>>10&1023|55296),e=56320|1023&e),t+=_(e)}).join("")}function R(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function k(e,t,n){var r=0;for(e=n?w(e/a):e>>1,e+=w(e/t);h*E>>1w((y-l)/i))&&A("overflow"),l+=a*i,!(a<(a=s<=h?b:h+E<=s?E:s-h));s+=v)i>w(y/(a=v-a))&&A("overflow"),i*=a;h=k(l-o,t=c.length+1,0==o),w(l/t)>y-p&&A("overflow"),p+=w(l/t),l%=t,c.splice(l++,0,p)}return g(c)}function N(e){for(var t,n,r,o,i,s,a,c,u,l,p,h=[],f=(e=I(e)).length,d=C,g=S,m=t=0;mw((y-t)/(u=n+1))&&A("overflow"),t+=(o-d)*u,d=o,m=0;my&&A("overflow"),c==d){for(i=t,s=v;!(i<(a=s<=g?b:g+E<=s?E:s-g));s+=v)p=i-a,l=v-a,h.push(_(R(a+p%l,0))),i=w(p/l);h.push(_(R(i,0))),g=k(t,u,n==r),t=0,++n}++t,++d}return h.join("")}if(o={version:"1.3.2",ucs2:{decode:I,encode:g},decode:m,encode:N,toASCII:function(e){return d(e,function(e){return u.test(e)?"xn--"+N(e):e})},toUnicode:function(e){return d(e,function(e){return c.test(e)?m(e.slice(4).toLowerCase()):e})}},"function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",function(){return o});else if(t&&n)if(x.exports==t)n.exports=o;else for(i in o)o.hasOwnProperty(i)&&(t[i]=o[i]);else e.punycode=o}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],87:[function(e,t,n){"use strict";t.exports=function(e,t,n,r){t=t||"&",n=n||"=";var o={};if("string"!=typeof e||0===e.length)return o;var i=/\+/g;e=e.split(t);t=1e3;r&&"number"==typeof r.maxKeys&&(t=r.maxKeys);var s=e.length;0",'"',"`"," ","\r","\n","\t"]),R=["'"].concat(n),k=["%","/","?",";","#"].concat(R),N=["/","?","#"],O=/^[a-z0-9A-Z_-]{0,63}$/,x=/^([a-z0-9A-Z_-]{0,63})(.*)$/,L={javascript:!0,"javascript:":!0},P={javascript:!0,"javascript:":!0},M={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},D=e("querystring");function o(e,t,n){if(e&&s(e)&&e instanceof h)return e;var r=new h;return r.parse(e,t,n),r}function U(e){return"string"==typeof e}function s(e){return"object"==typeof e&&null!==e}function f(e){return null===e}h.prototype.parse=function(e,t,n){if(!U(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var r,o,i=(i=e).trim(),e=I.exec(i);if(e&&(r=(e=e[0]).toLowerCase(),this.protocol=r,i=i.substr(e.length)),(n||e||i.match(/^\/\/[^@\/]+@[^@\/]+/))&&(!(o="//"===i.substr(0,2))||e&&P[e]||(i=i.substr(2),this.slashes=!0)),!P[e]&&(o||e&&!M[e])){for(var s=-1,a=0;a>>((3&t)<<3)&255;return o})},{}],101:[function(e,t,n){var l,p,h=e("./lib/rng"),f=e("./lib/bytesToUuid"),d=0,g=0;t.exports=function(e,t,n){var r=t&&n||0,o=t||[],i=(e=e||{}).node||l,s=void 0!==e.clockseq?e.clockseq:p;null!=i&&null!=s||(c=h(),null==i&&(i=l=[1|c[0],c[1],c[2],c[3],c[4],c[5]]),null==s&&(s=p=16383&(c[6]<<8|c[7])));var a=void 0!==e.msecs?e.msecs:(new Date).getTime(),n=void 0!==e.nsecs?e.nsecs:g+1,c=a-d+(n-g)/1e4;if(c<0&&void 0===e.clockseq&&(s=s+1&16383),(c<0||d>>24&255,o[r++]=n>>>16&255,o[r++]=n>>>8&255,o[r++]=255&n,a=a/4294967296*1e4&268435455,o[r++]=a>>>8&255,o[r++]=255&a,o[r++]=a>>>24&15|16,o[r++]=a>>>16&255,o[r++]=s>>>8|128,o[r++]=255&s;for(var u=0;u<6;++u)o[r+u]=i[u];return t||f(o)}},{"./lib/bytesToUuid":99,"./lib/rng":100}],102:[function(e,t,n){var s=e("./lib/rng"),a=e("./lib/bytesToUuid");t.exports=function(e,t,n){var r=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var o=(e=e||{}).random||(e.rng||s)();if(o[6]=15&o[6]|64,o[8]=63&o[8]|128,t)for(var i=0;i<16;++i)t[r+i]=o[i];return t||a(o)}},{"./lib/bytesToUuid":99,"./lib/rng":100}],103:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./utils/LRU"),e=(Object.defineProperty(i.prototype,"size",{get:function(){return this.cache.length},enumerable:!0,configurable:!0}),i.prototype.put=function(e,t){e="string"!=typeof e?i.getKeyString(e):e,t=this.populateValue(t);this.cache.put(e,t)},i.prototype.get=function(e){var t="string"!=typeof e?i.getKeyString(e):e,n=Date.now(),r=this.cache.get(t);if(r)for(var o=0;o>>=0;break;case"x":r=r.toString(16);break;case"X":r=r.toString(16).toUpperCase()}r=/[def]/.test(i[8])&&i[3]&&0<=r?"+"+r:r,s=i[4]?"0"==i[4]?"0":i[4].charAt(1):" ",a=i[6]-String(r).length,a=i[6]?function(e,t){for(var n=[];0=this._logLevel&&(s[e.level]>=this._echoLevel&&a[e.getLevel()](e.toString()),e.line=this._lineCount++)},u.prototype.clearObjects=function(){for(var e=0;e=r._logLevel}));n=new o.Blob([JSON.stringify(e,void 0,4)],["text/plain"]),e=document.createElement("a"),t=t||"agent-log";e.href=o.URL.createObjectURL(n),e.download=t+".txt",document.body.appendChild(e),e.click(),document.body.removeChild(e)},u.prototype.scheduleUpstreamLogPush=function(e){connect.upstreamLogPushScheduled||(connect.upstreamLogPushScheduled=!0,o.setInterval(connect.hitch(this,this.reportMasterLogsUpStream,e),5e3))},u.prototype.reportMasterLogsUpStream=function(e){var t=this._logsToPush.slice();this._logsToPush=[],connect.ifMaster(connect.MasterTopics.SEND_LOGS,function(){0=connect.HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR||e.status===connect.HTTP_STATUS_CODES.TOO_MANY_REQUESTS)?setTimeout(function(){t(--n)},s):o(e)}).catch(function(e){o(e)})}(t)})},connect.backoff=function(r,o,i,s){connect.assertTrue(connect.isFunction(r),"func must be a Function");var a=this;r({success:function(e){s&&s.success&&s.success(e)},failure:function(e,t){var n;0>",e)},u.prototype.getSubscriptions=function(e){return this.subMap.getSubscriptions(e)},u.prototype.trigger=function(t,n){connect.assertNotNull(t,"eventName");var r=this,e=this.subMap.getSubscriptions("<>"),o=this.subMap.getSubscriptions(t);this.logEvents&&t!==connect.EventType.LOG&&t!==connect.EventType.MASTER_RESPONSE&&t!==connect.EventType.API_METRIC&&connect.getLog().trace("Publishing event: %s",t),e.concat(o).forEach(function(e){try{e.f(n||null,t,r)}catch(e){connect.getLog().error("'%s' event handler failed.",t).withException(e)}})},u.prototype.bridge=function(){var n=this;return function(e,t){n.trigger(t,e)}},u.prototype.unsubscribeAll=function(){this.subMap.getAllSubscriptions().forEach(function(e){e.unsubscribe()})},connect.EventBus=u,connect.EventFactory=e,connect.EventType=t,connect.AgentEvents=r,connect.ConnnectionEvents=s,connect.ContactEvents=i,connect.WebSocketEvents=o,connect.MasterTopics=n}(),function(){connect=this.connect||{},this.connect=connect,this.lily=connect;function r(){}r.prototype.send=function(e){throw new connect.NotImplementedError},r.prototype.onMessage=function(e){throw new connect.NotImplementedError};function o(){r.call(this)}((o.prototype=Object.create(r.prototype)).constructor=o).prototype.onMessage=function(e){},o.prototype.send=function(e){};function e(e,t){r.call(this),this.window=e,this.domain=t||"*"}((e.prototype=Object.create(r.prototype)).constructor=e).prototype.send=function(e){this.window.postMessage(e,this.domain)},e.prototype.onMessage=function(e){this.window.addEventListener("message",e)};function i(e,t,n){r.call(this),this.input=e,this.output=t,this.domain=n||"*"}((i.prototype=Object.create(r.prototype)).constructor=i).prototype.send=function(e){this.output.postMessage(e,this.domain)},i.prototype.onMessage=function(e){this.input.addEventListener("message",e)};function t(e){r.call(this),this.port=e,this.id=connect.randomId()}((t.prototype=Object.create(r.prototype)).constructor=t).prototype.send=function(e){this.port.postMessage(e)},t.prototype.onMessage=function(e){this.port.addEventListener("message",e)},t.prototype.getId=function(){return this.id};function n(e){r.call(this),this.streamMap=e?connect.index(e,function(e){return e.getId()}):{},this.messageListeners=[]}((n.prototype=Object.create(r.prototype)).constructor=n).prototype.send=function(t){this.getStreams().forEach(function(e){try{e.send(t)}catch(e){}})},n.prototype.onMessage=function(t){this.messageListeners.push(t),this.getStreams().forEach(function(e){e.onMessage(t)})},n.prototype.addStream=function(t){this.streamMap[t.getId()]=t,this.messageListeners.forEach(function(e){t.onMessage(e)})},n.prototype.removeStream=function(e){delete this.streamMap[e.getId()]},n.prototype.getStreams=function(e){return connect.values(this.streamMap)},n.prototype.getStreamForPort=function(t){return connect.find(this.getStreams(),function(e){return e.port===t})};function s(e,t,n){this.name=e,this.upstream=t||new o,this.downstream=n||new o,this.downstreamBus=new connect.EventBus,this.upstreamBus=new connect.EventBus,this.upstream.onMessage(connect.hitch(this,this._dispatchEvent,this.upstreamBus)),this.downstream.onMessage(connect.hitch(this,this._dispatchEvent,this.downstreamBus))}s.prototype.onUpstream=function(e,t){return connect.assertNotNull(e,"eventName"),connect.assertNotNull(t,"f"),connect.assertTrue(connect.isFunction(t),"f must be a function"),this.upstreamBus.subscribe(e,t)},s.prototype.onAllUpstream=function(e){return connect.assertNotNull(e,"f"),connect.assertTrue(connect.isFunction(e),"f must be a function"),this.upstreamBus.subscribeAll(e)},s.prototype.onDownstream=function(e,t){return connect.assertNotNull(e,"eventName"),connect.assertNotNull(t,"f"),connect.assertTrue(connect.isFunction(t),"f must be a function"),this.downstreamBus.subscribe(e,t)},s.prototype.onAllDownstream=function(e){return connect.assertNotNull(e,"f"),connect.assertTrue(connect.isFunction(e),"f must be a function"),this.downstreamBus.subscribeAll(e)},s.prototype.sendUpstream=function(e,t){connect.assertNotNull(e,"eventName"),this.upstream.send({event:e,data:t})},s.prototype.sendDownstream=function(e,t){connect.assertNotNull(e,"eventName"),this.downstream.send({event:e,data:t})},s.prototype._dispatchEvent=function(e,t){t=t.data;t.event&&e.trigger(t.event,t.data)},s.prototype.passUpstream=function(){var n=this;return function(e,t){n.upstream.send({event:t,data:e})}},s.prototype.passDownstream=function(){var n=this;return function(e,t){n.downstream.send({event:t,data:e})}},s.prototype.shutdown=function(){this.upstreamBus.unsubscribeAll(),this.downstreamBus.unsubscribeAll()};function a(e,t,n,r){s.call(this,e,new i(t,n.contentWindow,r||"*"),null)}(a.prototype=Object.create(s.prototype)).constructor=a,connect.Stream=r,connect.NullStream=o,connect.WindowStream=e,connect.WindowIOStream=i,connect.PortStream=t,connect.StreamMultiplexer=n,connect.Conduit=s,connect.IFrameConduit=a}(),function(){connect=this.connect||{},this.connect=connect,this.lily=connect,connect.ClientMethods=connect.makeEnum(["getAgentSnapshot","putAgentState","getAgentStates","getDialableCountryCodes","getRoutingProfileQueues","getAgentPermissions","getAgentConfiguration","updateAgentConfiguration","acceptContact","createOutboundContact","clearContact","completeContact","notifyContactIssue","updateContactAttributes","createAdditionalConnection","destroyConnection","holdConnection","resumeConnection","toggleActiveConnections","conferenceConnections","sendClientLogs","sendDigits","sendSoftphoneCallReport","sendSoftphoneCallMetrics","getEndpoints","getNewAuthToken","createTransport"]),connect.MasterMethods=connect.makeEnum(["becomeMaster","checkMaster"]);function r(){}r.EMPTY_CALLBACKS={success:function(){},failure:function(){}},r.prototype.call=function(e,t,n){connect.assertNotNull(e,"method");t=t||{},n=n||r.EMPTY_CALLBACKS;this._callImpl(e,t,n)},r.prototype._callImpl=function(e,t,n){throw new connect.NotImplementedError};function e(){r.call(this)}((e.prototype=Object.create(r.prototype)).constructor=e).prototype._callImpl=function(e,t,n){n&&n.failure&&(e=connect.sprintf("No such method exists on NULL client: %s",e),n.failure(new connect.ValueError(e),{message:e}))};function t(e,t,n){r.call(this),this.conduit=e,this.requestEvent=t,this.responseEvent=n,this._requestIdCallbacksMap={},this.conduit.onUpstream(n,connect.hitch(this,this._handleResponse))}((t.prototype=Object.create(r.prototype)).constructor=t).prototype._callImpl=function(e,t,n){t=connect.EventFactory.createRequest(this.requestEvent,e,t);this._requestIdCallbacksMap[t.requestId]=n,this.conduit.sendUpstream(t.event,t)},t.prototype._getCallbacksForRequest=function(e){var t=this._requestIdCallbacksMap[e]||null;return null!=t&&delete this._requestIdCallbacksMap[e],t},t.prototype._handleResponse=function(e){var t=this._getCallbacksForRequest(e.requestId);null!=t&&(e.err&&t.failure?t.failure(e.err,e.data):t.success&&t.success(e.data))};function n(e){t.call(this,e,connect.EventType.API_REQUEST,connect.EventType.API_RESPONSE)}(n.prototype=Object.create(t.prototype)).constructor=n;function o(e){t.call(this,e,connect.EventType.MASTER_REQUEST,connect.EventType.MASTER_RESPONSE)}(o.prototype=Object.create(t.prototype)).constructor=o;function i(e,t,n){connect.assertNotNull(e,"authToken"),connect.assertNotNull(t,"region"),r.call(this),AWS.config.credentials=new AWS.Credentials({}),AWS.config.region=t,this.authToken=e,e=connect.getBaseUrl(),e=n||(e.includes(".awsapps.com")?e+"/connect/api":e+"/api"),e=new AWS.Endpoint(e),this.client=new AWS.Connect({endpoint:e})}((i.prototype=Object.create(r.prototype)).constructor=i).prototype._callImpl=function(r,e,o){var t=this,i=connect.getLog();connect.contains(this.client,r)?(e=this._translateParams(r,e),i.trace("AWSClient: --\x3e Calling operation '%s'",r),this.client[r](e).on("build",function(e){e.httpRequest.headers["X-Amz-Bearer"]=t.authToken}).send(function(e,t){try{var n;e?(e.code===connect.CTIExceptions.UNAUTHORIZED_EXCEPTION?o.authFailure():!o.accessDenied||e.code!==connect.CTIExceptions.ACCESS_DENIED_EXCEPTION&&403!==e.statusCode?((n={}).type=e.code,n.message=e.message,n.stack=e.stack?e.stack.split("\n"):[],o.failure(n,t)):o.accessDenied(),i.trace("AWSClient: <-- Operation '%s' failed: %s",r,JSON.stringify(e))):(i.trace("AWSClient: <-- Operation '%s' succeeded.",r).withObject(t),o.success(t))}catch(e){connect.getLog().error("Failed to handle AWS API request for method %s",r).withException(e)}})):(e=connect.sprintf("No such method exists on AWS client: %s",r),o.failure(new connect.ValueError(e),{message:e}))},i.prototype._requiresAuthenticationParam=function(e){return e!==connect.ClientMethods.COMPLETE_CONTACT&&e!==connect.ClientMethods.CLEAR_CONTACT&&e!==connect.ClientMethods.REJECT_CONTACT},i.prototype._translateParams=function(e,t){switch(e){case connect.ClientMethods.UPDATE_AGENT_CONFIGURATION:t.configuration=this._translateAgentConfiguration(t.configuration);break;case connect.ClientMethods.SEND_SOFTPHONE_CALL_METRICS:t.softphoneStreamStatistics=this._translateSoftphoneStreamStatistics(t.softphoneStreamStatistics);break;case connect.ClientMethods.SEND_SOFTPHONE_CALL_REPORT:t.report=this._translateSoftphoneCallReport(t.report)}return this._requiresAuthenticationParam(e)&&(t.authentication={authToken:this.authToken}),t},i.prototype._translateAgentConfiguration=function(e){return{name:e.name,softphoneEnabled:e.softphoneEnabled,softphoneAutoAccept:e.softphoneAutoAccept,extension:e.extension,routingProfile:this._translateRoutingProfile(e.routingProfile),agentPreferences:e.agentPreferences}},i.prototype._translateRoutingProfile=function(e){return{name:e.name,routingProfileARN:e.routingProfileARN,defaultOutboundQueue:this._translateQueue(e.defaultOutboundQueue)}},i.prototype._translateQueue=function(e){return{queueARN:e.queueARN,name:e.name}},i.prototype._translateSoftphoneStreamStatistics=function(e){return e.forEach(function(e){"packetsCount"in e&&(e.packetCount=e.packetsCount,delete e.packetsCount)}),e},i.prototype._translateSoftphoneCallReport=function(e){return"handshakingTimeMillis"in e&&(e.handshakeTimeMillis=e.handshakingTimeMillis,delete e.handshakingTimeMillis),"preTalkingTimeMillis"in e&&(e.preTalkTimeMillis=e.preTalkingTimeMillis,delete e.preTalkingTimeMillis),"handshakingFailure"in e&&(e.handshakeFailure=e.handshakingFailure,delete e.handshakingFailure),"talkingTimeMillis"in e&&(e.talkTimeMillis=e.talkingTimeMillis,delete e.talkingTimeMillis),e.softphoneStreamStatistics=this._translateSoftphoneStreamStatistics(e.softphoneStreamStatistics),e},connect.ClientBase=r,connect.NullClient=e,connect.UpstreamConduitClient=n,connect.UpstreamConduitMasterClient=o,connect.AWSClient=i}(),function(){connect=this.connect||{},this.connect=connect,this.lily=connect;function r(e,t){connect.assertNotNull(e,"fromState"),connect.assertNotNull(t,"toState"),this.fromState=e,this.toState=t}r.prototype.getAssociations=function(e){throw connect.NotImplementedError()},r.prototype.getFromState=function(){return this.fromState},r.prototype.getToState=function(){return this.toState};function e(e,t,n){connect.assertNotNull(e,"fromState"),connect.assertNotNull(t,"toState"),connect.assertNotNull(n,"associations"),r.call(this,e,t),this.associations=n}((e.prototype=Object.create(r.prototype)).constructor=e).prototype.getAssociations=function(e){return this.associations};function i(e,t,n){connect.assertNotNull(e,"fromState"),connect.assertNotNull(t,"toState"),connect.assertNotNull(n,"closure"),connect.assertTrue(connect.isFunction(n),"closure must be a function"),r.call(this,e,t),this.closure=n}((i.prototype=Object.create(r.prototype)).constructor=i).prototype.getAssociations=function(e){return this.closure(e,this.getFromState(),this.getToState())};function s(){this.fromMap={}}s.ANY="<>",s.prototype.assoc=function(t,n,r){var o=this;if(!t)throw new Error("fromStateObj is not defined.");if(!n)throw new Error("toStateObj is not defined.");if(!r)throw new Error("assocObj is not defined.");return t instanceof Array?t.forEach(function(e){o.assoc(e,n,r)}):n instanceof Array?n.forEach(function(e){o.assoc(t,e,r)}):"function"==typeof r?this._addAssociation(new i(t,n,r)):r instanceof Array?this._addAssociation(new e(t,n,r)):this._addAssociation(new e(t,n,[r])),this},s.prototype.getAssociations=function(e,t,n){connect.assertNotNull(t,"fromState"),connect.assertNotNull(n,"toState");var r=[],o=this.fromMap[s.ANY]||{},i=this.fromMap[t]||{};return r=(r=r.concat(this._getAssociationsFromMap(o,e,t,n))).concat(this._getAssociationsFromMap(i,e,t,n))},s.prototype._addAssociation=function(e){var t=this.fromMap[e.getFromState()];((t=t||(this.fromMap[e.getFromState()]={}))[e.getToState()]||(t[e.getToState()]=[])).push(e)},s.prototype._getAssociationsFromMap=function(e,n,t,r){return(e[s.ANY]||[]).concat(e[r]||[]).reduce(function(e,t){return e.concat(t.getAssociations(n))},[])},connect.EventGraph=s}(),function(){var n=this;connect=n.connect||{},n.connect=connect,n.lily=connect,connect.AgentStateType=connect.makeEnum(["init","routable","not_routable","offline"]),connect.AgentStatusType=connect.AgentStateType,connect.AgentAvailStates=connect.makeEnum(["Init","Busy","AfterCallWork","CallingCustomer","Dialing","Joining","PendingAvailable","PendingBusy"]),connect.AgentErrorStates=connect.makeEnum(["Error","AgentHungUp","BadAddressAgent","BadAddressCustomer","Default","FailedConnectAgent","FailedConnectCustomer","LineEngagedAgent","LineEngagedCustomer","MissedCallAgent","MissedCallCustomer","MultipleCcpWindows","RealtimeCommunicationError"]),connect.EndpointType=connect.makeEnum(["phone_number","agent","queue"]),connect.AddressType=connect.EndpointType,connect.ConnectionType=connect.makeEnum(["agent","inbound","outbound","monitoring"]),connect.ConnectionStateType=connect.makeEnum(["init","connecting","connected","hold","disconnected"]),connect.ConnectionStatusType=connect.ConnectionStateType,connect.CONNECTION_ACTIVE_STATES=connect.set([connect.ConnectionStateType.CONNECTING,connect.ConnectionStateType.CONNECTED,connect.ConnectionStateType.HOLD]),connect.ContactStateType=connect.makeEnum(["init","incoming","pending","connecting","connected","missed","error","ended"]),connect.ContactStatusType=connect.ContactStateType,connect.CONTACT_ACTIVE_STATES=connect.makeEnum(["incoming","pending","connecting","connected"]),connect.ContactType=connect.makeEnum(["voice","queue_callback","chat"]),connect.ChannelType=connect.makeEnum(["VOICE","CHAT"]),connect.MediaType=connect.makeEnum(["softphone","chat"]),connect.SoftphoneCallType=connect.makeEnum(["audio_video","video_only","audio_only","none"]),connect.SoftphoneErrorTypes=connect.makeEnum(["unsupported_browser","microphone_not_shared","signalling_handshake_failure","signalling_connection_failure","ice_collection_timeout","user_busy_error","webrtc_error","realtime_communication_error","other"]),connect.CTIExceptions=connect.makeEnum(["AccessDeniedException","InvalidStateException","BadEndpointException","InvalidAgentARNException","InvalidConfigurationException","InvalidContactTypeException","PaginationException","RefreshTokenExpiredException","SendDataFailedException","UnauthorizedException"]);function e(){if(!connect.agent.initialized)throw new connect.StateError("The agent is not yet initialized!")}e.prototype._getData=function(){return connect.core.getAgentDataProvider().getAgentData()},e.prototype._createContactAPI=function(e){return new connect.Contact(e.contactId)},e.prototype.onContactPending=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.CONTACT_PENDING,e)},e.prototype.onRefresh=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.REFRESH,e)},e.prototype.onRoutable=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.ROUTABLE,e)},e.prototype.onNotRoutable=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.NOT_ROUTABLE,e)},e.prototype.onOffline=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.OFFLINE,e)},e.prototype.onError=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.ERROR,e)},e.prototype.onSoftphoneError=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.SOFTPHONE_ERROR,e)},e.prototype.onWebSocketConnectionLost=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.WEBSOCKET_CONNECTION_LOST,e)},e.prototype.onWebSocketConnectionGained=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.WEBSOCKET_CONNECTION_GAINED,e)},e.prototype.onAfterCallWork=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.ACW,e)},e.prototype.onStateChange=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.STATE_CHANGE,e)},e.prototype.onMuteToggle=function(e){connect.core.getUpstream().onUpstream(connect.AgentEvents.MUTE_TOGGLE,e)},e.prototype.onLocalMediaStreamCreated=function(e){connect.core.getUpstream().onUpstream(connect.AgentEvents.LOCAL_MEDIA_STREAM_CREATED,e)},e.prototype.mute=function(){connect.core.getUpstream().sendUpstream(connect.EventType.BROADCAST,{event:connect.EventType.MUTE,data:{mute:!0}})},e.prototype.unmute=function(){connect.core.getUpstream().sendUpstream(connect.EventType.BROADCAST,{event:connect.EventType.MUTE,data:{mute:!1}})},e.prototype.getState=function(){return this._getData().snapshot.state},e.prototype.getAvailabilityState=function(){return this._getData().snapshot.agentAvailabilityState},e.prototype.getStatus=e.prototype.getState,e.prototype.getStatusDuration=e.prototype.getStateDuration=function(){return connect.now()-this._getData().snapshot.state.startTimestamp.getTime()+connect.core.getSkew()},e.prototype.getPermissions=function(){return this.getConfiguration().permissions},e.prototype.getContacts=function(t){var n=this;return this._getData().snapshot.contacts.map(function(e){return n._createContactAPI(e)}).filter(function(e){return!t||e.getType()===t})},e.prototype.getConfiguration=function(){return this._getData().configuration},e.prototype.getAgentStates=function(){return this.getConfiguration().agentStates},e.prototype.getRoutingProfile=function(){return this.getConfiguration().routingProfile},e.prototype.getChannelConcurrency=function(e){var t=(t=this.getRoutingProfile().channelConcurrencyMap)||Object.keys(connect.ChannelType).reduce(function(e,t){return e[connect.ChannelType[t]]=1,e},{});return e?t[e]||0:t},e.prototype.getName=function(){return this.getConfiguration().name},e.prototype.getExtension=function(){return this.getConfiguration().extension},e.prototype.getDialableCountries=function(){return this.getConfiguration().dialableCountries},e.prototype.isSoftphoneEnabled=function(){return this.getConfiguration().softphoneEnabled},e.prototype.setConfiguration=function(e,t){connect.core.getClient().call(connect.ClientMethods.UPDATE_AGENT_CONFIGURATION,{configuration:connect.assertNotNull(e,"configuration")},{success:function(e){connect.core.getUpstream().sendUpstream(connect.EventType.RELOAD_AGENT_CONFIGURATION),t.success&&t.success(e)},failure:t&&t.failure})},e.prototype.setStatus=e.prototype.setState=function(e,t){connect.core.getClient().call(connect.ClientMethods.PUT_AGENT_STATE,{state:connect.assertNotNull(e,"state")},t)},e.prototype.connect=function(e,t){var n=connect.core.getClient(),e=new connect.Endpoint(e);delete e.endpointId,n.call(connect.ClientMethods.CREATE_OUTBOUND_CONTACT,{endpoint:connect.assertNotNull(e,"endpoint"),queueARN:t&&(t.queueARN||t.queueId)||this.getRoutingProfile().defaultOutboundQueue.queueARN},t&&{success:t.success,failure:t.failure})},e.prototype.getAllQueueARNs=function(){return this.getConfiguration().routingProfile.queues.map(function(e){return e.queueARN})},e.prototype.getAddresses=e.prototype.getEndpoints=function(t,n,e){var r=this,o=connect.core.getClient();connect.assertNotNull(n,"callbacks"),connect.assertNotNull(n.success,"callbacks.success");var i=e||{};i.endpoints=i.endpoints||[],i.maxResults=i.maxResults||connect.DEFAULT_BATCH_SIZE,connect.isArray(t)||(t=[t]),o.call(connect.ClientMethods.GET_ENDPOINTS,{queueARNs:t,nextToken:i.nextToken||null,maxResults:i.maxResults},{success:function(e){e.nextToken?r.getEndpoints(t,n,{nextToken:e.nextToken,maxResults:i.maxResults,endpoints:i.endpoints.concat(e.endpoints)}):(i.endpoints=i.endpoints.concat(e.endpoints),e=i.endpoints.map(function(e){return new connect.Endpoint(e)}),n.success({endpoints:e,addresses:e}))},failure:n.failure})},e.prototype.toSnapshot=function(){return new connect.AgentSnapshot(this._getData())};function t(e){connect.Agent.call(this),this.agentData=e}((t.prototype=Object.create(e.prototype)).constructor=t).prototype._getData=function(){return this.agentData},t.prototype._createContactAPI=function(e){return new connect.ContactSnapshot(e)};function r(e){this.contactId=e}r.prototype._getData=function(){return connect.core.getAgentDataProvider().getContactData(this.getContactId())},r.prototype._createConnectionAPI=function(e){return new(this.getType()===connect.ContactType.CHAT?connect.ChatConnection:connect.VoiceConnection)(this.contactId,e.connectionId)},r.prototype.getEventName=function(e){return connect.core.getContactEventName(e,this.getContactId())},r.prototype.onRefresh=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.REFRESH),e)},r.prototype.onIncoming=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.INCOMING),e)},r.prototype.onConnecting=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.CONNECTING),e)},r.prototype.onPending=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.PENDING),e)},r.prototype.onAccepted=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.ACCEPTED),e)},r.prototype.onMissed=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.MISSED),e)},r.prototype.onEnded=function(e){var t=connect.core.getEventBus();t.subscribe(this.getEventName(connect.ContactEvents.ENDED),e),t.subscribe(this.getEventName(connect.ContactEvents.DESTROYED),e)},r.prototype.onDestroy=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.DESTROYED),e)},r.prototype.onACW=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.ACW),e)},r.prototype.onConnected=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.CONNECTED),e)},r.prototype.onError=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.ERROR),e)},r.prototype.getContactId=function(){return this.contactId},r.prototype.getInitialContactId=r.prototype.getOriginalContactId=function(){return this._getData().initialContactId},r.prototype.getType=function(){return this._getData().type},r.prototype.getContactDuration=function(){return this._getData().contactDuration},r.prototype.getStatus=r.prototype.getState=function(){return this._getData().state},r.prototype.getStatusDuration=r.prototype.getStateDuration=function(){return connect.now()-this._getData().state.timestamp.getTime()+connect.core.getSkew()},r.prototype.getQueue=function(){return this._getData().queue},r.prototype.getQueueTimestamp=function(){return this._getData().queueTimestamp},r.prototype.getConnections=function(){var t=this;return this._getData().connections.map(function(e){return new(t.getType()===connect.ContactType.CHAT?connect.ChatConnection:connect.VoiceConnection)(t.contactId,e.connectionId)})},r.prototype.getInitialConnection=function(){return connect.find(this.getConnections(),function(e){return e.isInitialConnection()})||null},r.prototype.getActiveInitialConnection=function(){var e=this.getInitialConnection();return null!=e&&e.isActive()?e:null},r.prototype.getThirdPartyConnections=function(){return this.getConnections().filter(function(e){return!e.isInitialConnection()&&e.getType()!==connect.ConnectionType.AGENT})},r.prototype.getSingleActiveThirdPartyConnection=function(){return this.getThirdPartyConnections().filter(function(e){return e.isActive()})[0]||null},r.prototype.getAgentConnection=function(){return connect.find(this.getConnections(),function(e){e=e.getType();return e===connect.ConnectionType.AGENT||e===connect.ConnectionType.MONITORING})},r.prototype.getAttributes=function(){return this._getData().attributes},r.prototype.isSoftphoneCall=function(){return null!=connect.find(this.getConnections(),function(e){return null!=e.getSoftphoneMediaInfo()})},r.prototype.isInbound=function(){var e=this.getInitialConnection();return!!e&&e.getType()===connect.ConnectionType.INBOUND},r.prototype.isConnected=function(){return this.getStatus().type===connect.ContactStateType.CONNECTED},r.prototype.accept=function(n){var e=connect.core.getClient(),r=this,o=this.getContactId();e.call(connect.ClientMethods.ACCEPT_CONTACT,{contactId:o},{success:function(e){var t=connect.core.getUpstream();t.sendUpstream(connect.EventType.BROADCAST,{event:connect.ContactEvents.ACCEPTED,data:new connect.Contact(o)}),t.sendUpstream(connect.EventType.BROADCAST,{event:connect.core.getContactEventName(connect.ContactEvents.ACCEPTED,r.getContactId()),data:new connect.Contact(o)}),n&&n.success&&n.success(e)},failure:n?n.failure:null})},r.prototype.complete=function(e){connect.core.getClient().call(connect.ClientMethods.COMPLETE_CONTACT,{contactId:this.getContactId()},e)},r.prototype.clear=function(e){connect.core.getClient().call(connect.ClientMethods.CLEAR_CONTACT,{contactId:this.getContactId()},e)},r.prototype.clear=function(e){connect.core.getClient().call(connect.ClientMethods.CLEAR_CONTACT,{contactId:this.getContactId()},e)},r.prototype.notifyIssue=function(e,t,n){connect.core.getClient().call(connect.ClientMethods.NOTIFY_CONTACT_ISSUE,{contactId:this.getContactId(),issueCode:e,description:t},n)},r.prototype.addConnection=function(e,t){var n=connect.core.getClient(),e=new connect.Endpoint(e);delete e.endpointId,n.call(connect.ClientMethods.CREATE_ADDITIONAL_CONNECTION,{contactId:this.getContactId(),endpoint:e},t)},r.prototype.toggleActiveConnections=function(e){var t=connect.core.getClient(),n=null,r=connect.find(this.getConnections(),function(e){return e.getStatus().type===connect.ConnectionStateType.HOLD});null!=r?n=r.getConnectionId():0<(r=this.getConnections().filter(function(e){return e.isActive()})).length&&(n=r[0].getConnectionId()),t.call(connect.ClientMethods.TOGGLE_ACTIVE_CONNECTIONS,{contactId:this.getContactId(),connectionId:n},e)},r.prototype.sendSoftphoneMetrics=function(e,t){connect.core.getClient().call(connect.ClientMethods.SEND_SOFTPHONE_CALL_METRICS,{contactId:this.getContactId(),ccpVersion:n.ccpVersion,softphoneStreamStatistics:e},t)},r.prototype.sendSoftphoneReport=function(e,t){connect.core.getClient().call(connect.ClientMethods.SEND_SOFTPHONE_CALL_REPORT,{contactId:this.getContactId(),ccpVersion:n.ccpVersion,report:e},t)},r.prototype.conferenceConnections=function(e){connect.core.getClient().call(connect.ClientMethods.CONFERENCE_CONNECTIONS,{contactId:this.getContactId()},e)},r.prototype.toSnapshot=function(){return new connect.ContactSnapshot(this._getData())};function o(e){connect.Contact.call(this,e.contactId),this.contactData=e}((o.prototype=Object.create(r.prototype)).constructor=o).prototype._getData=function(){return this.contactData},o.prototype._createConnectionAPI=function(e){return new connect.ConnectionSnapshot(e)};function i(e,t){this.contactId=e,this.connectionId=t,this._initMediaController()}i.prototype._getData=function(){return connect.core.getAgentDataProvider().getConnectionData(this.getContactId(),this.getConnectionId())},i.prototype.getContactId=function(){return this.contactId},i.prototype.getConnectionId=function(){return this.connectionId},i.prototype.getAddress=i.prototype.getEndpoint=function(){return new connect.Endpoint(this._getData().endpoint)},i.prototype.getStatus=i.prototype.getState=function(){return this._getData().state},i.prototype.getStatusDuration=i.prototype.getStateDuration=function(){return connect.now()-this._getData().state.timestamp.getTime()+connect.core.getSkew()},i.prototype.getType=function(){return this._getData().type},i.prototype.isInitialConnection=function(){return this._getData().initial},i.prototype.isActive=function(){return connect.contains(connect.CONNECTION_ACTIVE_STATES,this.getStatus().type)},i.prototype.isConnected=function(){return this.getStatus().type===connect.ConnectionStateType.CONNECTED},i.prototype.isConnecting=function(){return this.getStatus().type===connect.ConnectionStateType.CONNECTING},i.prototype.isOnHold=function(){return this.getStatus().type===connect.ConnectionStateType.HOLD},i.prototype.getSoftphoneMediaInfo=function(){return this._getData().softphoneMediaInfo},i.prototype.getMonitorInfo=function(){return this._getData().monitoringInfo},i.prototype.destroy=function(e){connect.core.getClient().call(connect.ClientMethods.DESTROY_CONNECTION,{contactId:this.getContactId(),connectionId:this.getConnectionId()},e)},i.prototype.sendDigits=function(e,t){connect.core.getClient().call(connect.ClientMethods.SEND_DIGITS,{contactId:this.getContactId(),connectionId:this.getConnectionId(),digits:e},t)},i.prototype.hold=function(e){connect.core.getClient().call(connect.ClientMethods.HOLD_CONNECTION,{contactId:this.getContactId(),connectionId:this.getConnectionId()},e)},i.prototype.resume=function(e){connect.core.getClient().call(connect.ClientMethods.RESUME_CONNECTION,{contactId:this.getContactId(),connectionId:this.getConnectionId()},e)},i.prototype.toSnapshot=function(){return new connect.ConnectionSnapshot(this._getData())},i.prototype._initMediaController=function(){this.getMediaInfo()&&connect.core.mediaFactory.get(this).catch(function(){})},i.prototype._isAgentConnectionType=function(){var e=this.getType();return e===connect.ConnectionType.AGENT||e===connect.ConnectionType.MONITORING},i.prototype._isAgentConnectionType=function(){var e=this.getType();return e===connect.ConnectionType.AGENT||e===connect.ConnectionType.MONITORING};function s(e,t){i.call(this,e,t)}((s.prototype=Object.create(i.prototype)).constructor=s).prototype.getSoftphoneMediaInfo=function(){return this._getData().softphoneMediaInfo},s.prototype.getMediaInfo=function(){return this._getData().softphoneMediaInfo},s.prototype.getMediaType=function(){return connect.MediaType.SOFTPHONE},s.prototype.getMediaController=function(){return connect.core.mediaFactory.get(this)};function a(e,t){i.call(this,e,t)}((a.prototype=Object.create(i.prototype)).constructor=a).prototype.getMediaInfo=function(){var t=this._getData().chatMediaInfo;if(t){var e=connect.core.getAgentDataProvider().getContactData(this.contactId),n={contactId:this.contactId,initialContactId:e.initialContactId||this.contactId,participantId:this.connectionId,getConnectionToken:connect.hitch(this,this.getConnectionToken)};if(t.connectionData)try{n.participantToken=JSON.parse(t.connectionData).ConnectionAuthenticationToken}catch(e){connect.getLog().error(connect.LogComponent.CHAT,"Connection data is invalid").withObject(t).withException(e),n.participantToken=null}return n.participantToken=n.participantToken||null,n.originalInfo=this._getData().chatMediaInfo,n}return null},a.prototype.getConnectionToken=function(){client=connect.core.getClient();var e=connect.core.getAgentDataProvider().getContactData(this.contactId),r={transportType:connect.TRANSPORT_TYPES.CHAT_TOKEN,participantId:this.connectionId,contactId:e.initialContactId||this.contactId};return new Promise(function(t,n){client.call(connect.ClientMethods.CREATE_TRANSPORT,r,{success:function(e){connect.getLog().info("getConnectionToken succeeded"),t(e)},failure:function(e,t){connect.getLog().error("getConnectionToken failed").withObject({err:e,data:t}),n(Error("getConnectionToken failed"))}})})},a.prototype.getMediaType=function(){return connect.MediaType.CHAT},a.prototype.getMediaController=function(){return connect.core.mediaFactory.get(this)},a.prototype._initMediaController=function(){this._isAgentConnectionType()&&connect.core.mediaFactory.get(this).catch(function(){})};function c(e){connect.Connection.call(this,e.contactId,e.connectionId),this.connectionData=e}((c.prototype=Object.create(i.prototype)).constructor=c).prototype._getData=function(){return this.connectionData},c.prototype._initMediaController=function(){};function u(e){e=e||{},this.endpointARN=e.endpointId||e.endpointARN||null,this.endpointId=this.endpointARN,this.type=e.type||null,this.name=e.name||null,this.phoneNumber=e.phoneNumber||null,this.agentLogin=e.agentLogin||null,this.queue=e.queue||null}u.prototype.stripPhoneNumber=function(){return this.phoneNumber?this.phoneNumber.replace(/sip:([^@]*)@.*/,"$1"):""},u.byPhoneNumber=function(e,t){return new u({type:connect.EndpointType.PHONE_NUMBER,phoneNumber:e,name:t||null})};function l(e,t,n){this.errorType=e,this.errorMessage=t,this.endPointUrl=n}l.prototype.getErrorType=function(){return this.errorType},l.prototype.getErrorMessage=function(){return this.errorMessage},l.prototype.getEndPointUrl=function(){return this.endPointUrl},connect.agent=function(e){var t=connect.core.getEventBus().subscribe(connect.AgentEvents.INIT,e);return connect.agent.initialized&&e(new connect.Agent),t},connect.agent.initialized=!1,connect.contact=function(e){return connect.core.getEventBus().subscribe(connect.ContactEvents.INIT,e)},connect.onWebsocketInitFailure=function(e){var t=connect.core.getEventBus().subscribe(connect.WebSocketEvents.INIT_FAILURE,e);return connect.webSocketInitFailed&&e(),t},connect.ifMaster=function(e,t,n){if(connect.assertNotNull(e,"A topic must be provided."),connect.assertNotNull(t,"A true callback must be provided."),!connect.core.masterClient)return connect.getLog().warn("We can't be the master for topic '%s' because there is no master client!",e),void(n&&n());connect.core.getMasterClient().call(connect.MasterMethods.CHECK_MASTER,{topic:e},{success:function(e){e.isMaster?t():n&&n()}})},connect.becomeMaster=function(e){connect.assertNotNull(e,"A topic must be provided."),connect.core.getMasterClient().call(connect.MasterMethods.BECOME_MASTER,{topic:e})},connect.Agent=e,connect.AgentSnapshot=t,connect.Contact=r,connect.ContactSnapshot=o,connect.Connection=s,connect.BaseConnection=i,connect.VoiceConnection=s,connect.ChatConnection=a,connect.ConnectionSnapshot=c,connect.Endpoint=u,connect.Address=u,connect.SoftphoneError=l}(),function(n){var r={};function o(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=n,o.c=r,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)o.d(n,r,function(e){return t[e]}.bind(null,r));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=2)}([function(e,t,n){"use strict";var r=n(1);function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i={assertTrue:function(e,t){if(!e)throw new Error(t)},assertNotNull:function(e,t){return i.assertTrue(null!==e&&void 0!==o(e),Object(r.sprintf)("%s must be provided",t||"A value")),e},isNonEmptyString:function(e){return"string"==typeof e&&0=this._level}},{key:"hasClientLogger",value:function(){return null!==this._clientLogger}},{key:"getLogger",value:function(e){e=e.prefix||"";return"DEBUG"===this._logsDestination?this.consoleLoggerWrapper:new y(e)}},{key:"updateLoggerConfig",value:function(e){e=e||{};this._level=e.level||d.DEBUG,this._clientLogger=e.logger||null,this._logsDestination="NULL",e.debug&&(this._logsDestination="DEBUG"),e.logger&&(this._logsDestination="CLIENT_LOGGER")}}]),S),m=(h(E,[{key:"debug",value:function(){}},{key:"info",value:function(){}},{key:"warn",value:function(){}},{key:"error",value:function(){}}]),E),y=(function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}(b,m),h(b,[{key:"debug",value:function(){for(var e=arguments.length,t=new Array(e),n=0;n>>0).toString(8);break;case"s":n=String(n),n=o.precision?n.substring(0,o.precision):n;break;case"t":n=String(!!n),n=o.precision?n.substring(0,o.precision):n;break;case"T":n=Object.prototype.toString.call(n).slice(8,-1).toLowerCase(),n=o.precision?n.substring(0,o.precision):n;break;case"u":n=parseInt(n,10)>>>0;break;case"v":n=n.valueOf(),n=o.precision?n.substring(0,o.precision):n;break;case"x":n=(parseInt(n,10)>>>0).toString(16);break;case"X":n=(parseInt(n,10)>>>0).toString(16).toUpperCase()}f.json.test(o.type)?p+=n:(!f.number.test(o.type)||a&&!o.sign?c="":(c=a?"+":"-",n=n.toString().replace(f.sign,"")),i=o.pad_char?"0"===o.pad_char?"0":o.pad_char.charAt(1):" ",s=o.width-(c+n).length,s=o.width&&0t.packetsLost?e.packetsLost-t.packetsLost:0,t=e.packetsCount>t.packetsCount?e.packetsCount-t.packetsCount:0;return new x(e.timestamp,r,t,n,e.audioLevel,e.jbMilliseconds,e.rttMilliseconds)}return new x(e.timestamp,e.packetsLost,e.packetsCount,n,e.audioLevel,e.jbMilliseconds,e.rttMilliseconds)},O=function(e,t){u=r(u),l=r(l),function(e,t,n,r){t.streamStats=[L(n,i),L(r,s)];var o={callStartTime:t.sessionStartTime,callEndTime:t.sessionEndTime,gumTimeMillis:t.gumTimeMillis,initializationTimeMillis:t.initializationTimeMillis,iceCollectionTimeMillis:t.iceCollectionTimeMillis,signallingConnectTimeMillis:t.signallingConnectTimeMillis,handshakingTimeMillis:t.handshakingTimeMillis,preTalkingTimeMillis:t.preTalkingTimeMillis,talkingTimeMillis:t.talkingTimeMillis,cleanupTimeMillis:t.cleanupTimeMillis,iceCollectionFailure:t.iceCollectionFailure,signallingConnectionFailure:t.signallingConnectionFailure,handshakingFailure:t.handshakingFailure,gumOtherFailure:t.gumOtherFailure,gumTimeoutFailure:t.gumTimeoutFailure,createOfferFailure:t.createOfferFailure,setLocalDescriptionFailure:t.setLocalDescriptionFailure,userBusyFailure:t.userBusyFailure,invalidRemoteSDPFailure:t.invalidRemoteSDPFailure,noRemoteIceCandidateFailure:t.noRemoteIceCandidateFailure,setRemoteDescriptionFailure:t.setRemoteDescriptionFailure,softphoneStreamStatistics:t.streamStats};e.sendSoftphoneReport(o,{success:function(){p.info("sendSoftphoneReport success"+JSON.stringify(o))},failure:function(e){p.error("sendSoftphoneReport failed.").withObject(e)}})}(e,t,L(a,i),L(c,s)),n(e)},x=function(e,t,n,r,o,i,s){this.softphoneStreamType=r,this.timestamp=e,this.packetsLost=t,this.packetsCount=n,this.audioLevel=o,this.jitterBufferMillis=i,this.roundTripTimeMillis=s},L=function(e,t){return new x((e=e||{}).timestamp,e.packetsLost,e.packetsCount,t,e.audioLevel)},P=function(e){this._originalLogger=e;var r=this;this._tee=function(e,n){return function(){var e=Array.prototype.slice.call(arguments[0]),t="";e.forEach(function(){t+=" %s"}),n.apply(r._originalLogger,[connect.LogComponent.SOFTPHONE,t].concat(e))}}};P.prototype.debug=function(){this._tee(1,this._originalLogger.debug)(arguments)},P.prototype.info=function(){this._tee(2,this._originalLogger.info)(arguments)},P.prototype.log=function(){this._tee(3,this._originalLogger.log)(arguments)},P.prototype.warn=function(){this._tee(4,this._originalLogger.warn)(arguments)},P.prototype.error=function(){this._tee(5,this._originalLogger.error)(arguments)},connect.SoftphoneManager=function(e){var i;p=new P(connect.getLog()),connect.RtcPeerConnectionFactory&&(i=new connect.RtcPeerConnectionFactory(p,connect.core.getWebSocketManager(),d,connect.hitch(this,t,{transportType:"softphone",softphoneClientId:d}),connect.hitch(this,C))),A()||C(h.UNSUPPORTED_BROWSER,"Connect does not support this browser. Some functionality may not work. ","");S({success:function(e){connect.isFirefoxBrowser()&&connect.core.setSoftphoneUserMediaStream(e)},failure:function(e){C(e,"Your microphone is not enabled in your browser. ","")}});m(),this.ringtoneEngine=null;var s="true"===e.cleanMultipleSessions,a={},c={};this.getSession=function(e){return a[e]};function u(n){var r;a.hasOwnProperty(n)&&(r=a[n],new Promise(function(e,t){delete a[n],delete c[n],r.hangup()}).catch(function(e){lily.getLog().warn("Clean up the session locally "+n,e.message)}))}function n(n,r){var e,t,o;!a[r]||(t=n).getStatus().type!==connect.ContactStatusType.ENDED&&t.getStatus().type!==connect.ContactStatusType.ERROR&&t.getStatus().type!==connect.ContactStatusType.MISSED||u(r),!n.isSoftphoneCall()||c[r]||n.getStatus().type!==connect.ContactStatusType.CONNECTING&&n.getStatus().type!==connect.ContactStatusType.INCOMING||(c[r]=!0,p.info("Softphone call detected:","contactId "+n.getContactId(),"agent connectionId "+r),function(e){if(0e.BLOCK_SIZE&&((t=new e).update(n),n=t.digest());e=new Uint8Array(e.BLOCK_SIZE);return e.set(n),e}(e,t),r=new Uint8Array(e.BLOCK_SIZE);r.set(n);for(var o=0;o>>32-o)+n&4294967295}function a(e,t,n,r,o,i,s){return c(t&n|~t&r,e,t,o,i,s)}function u(e,t,n,r,o,i,s){return c(t&r|n&~r,e,t,o,i,s)}function l(e,t,n,r,o,i,s){return c(t^n^r,e,t,o,i,s)}function p(e,t,n,r,o,i,s){return c(n^(t|~r),e,t,o,i,s)}(t.exports=r).BLOCK_SIZE=64,r.prototype.update=function(e){if(o.isEmptyData(e))return this;if(this.finished)throw new Error("Attempted to update an already finished hash.");var t=o.convertToBuffer(e),n=0,r=t.byteLength;for(this.bytesHashed+=r;0>>0,!0),t.setUint32(60,Math.floor(r/4294967296),!0),this.hashBuffer(),this.finished=!0}for(var i=new DataView(new ArrayBuffer(16)),o=0;o<4;o++)i.setUint32(4*o,this.state[o],!0);r=new s(i.buffer,i.byteOffset,i.byteLength);return e?r.toString(e):r},r.prototype.hashBuffer=function(){var e=this.buffer,t=this.state,n=a(n=t[0],i=t[1],o=t[2],r=t[3],e.getUint32(0,!0),7,3614090360),r=a(r,n,i,o,e.getUint32(4,!0),12,3905402710),o=a(o,r,n,i,e.getUint32(8,!0),17,606105819),i=a(i,o,r,n,e.getUint32(12,!0),22,3250441966);n=a(n,i,o,r,e.getUint32(16,!0),7,4118548399),r=a(r,n,i,o,e.getUint32(20,!0),12,1200080426),o=a(o,r,n,i,e.getUint32(24,!0),17,2821735955),i=a(i,o,r,n,e.getUint32(28,!0),22,4249261313),n=a(n,i,o,r,e.getUint32(32,!0),7,1770035416),r=a(r,n,i,o,e.getUint32(36,!0),12,2336552879),o=a(o,r,n,i,e.getUint32(40,!0),17,4294925233),i=a(i,o,r,n,e.getUint32(44,!0),22,2304563134),n=a(n,i,o,r,e.getUint32(48,!0),7,1804603682),r=a(r,n,i,o,e.getUint32(52,!0),12,4254626195),o=a(o,r,n,i,e.getUint32(56,!0),17,2792965006),n=u(n,i=a(i,o,r,n,e.getUint32(60,!0),22,1236535329),o,r,e.getUint32(4,!0),5,4129170786),r=u(r,n,i,o,e.getUint32(24,!0),9,3225465664),o=u(o,r,n,i,e.getUint32(44,!0),14,643717713),i=u(i,o,r,n,e.getUint32(0,!0),20,3921069994),n=u(n,i,o,r,e.getUint32(20,!0),5,3593408605),r=u(r,n,i,o,e.getUint32(40,!0),9,38016083),o=u(o,r,n,i,e.getUint32(60,!0),14,3634488961),i=u(i,o,r,n,e.getUint32(16,!0),20,3889429448),n=u(n,i,o,r,e.getUint32(36,!0),5,568446438),r=u(r,n,i,o,e.getUint32(56,!0),9,3275163606),o=u(o,r,n,i,e.getUint32(12,!0),14,4107603335),i=u(i,o,r,n,e.getUint32(32,!0),20,1163531501),n=u(n,i,o,r,e.getUint32(52,!0),5,2850285829),r=u(r,n,i,o,e.getUint32(8,!0),9,4243563512),o=u(o,r,n,i,e.getUint32(28,!0),14,1735328473),n=l(n,i=u(i,o,r,n,e.getUint32(48,!0),20,2368359562),o,r,e.getUint32(20,!0),4,4294588738),r=l(r,n,i,o,e.getUint32(32,!0),11,2272392833),o=l(o,r,n,i,e.getUint32(44,!0),16,1839030562),i=l(i,o,r,n,e.getUint32(56,!0),23,4259657740),n=l(n,i,o,r,e.getUint32(4,!0),4,2763975236),r=l(r,n,i,o,e.getUint32(16,!0),11,1272893353),o=l(o,r,n,i,e.getUint32(28,!0),16,4139469664),i=l(i,o,r,n,e.getUint32(40,!0),23,3200236656),n=l(n,i,o,r,e.getUint32(52,!0),4,681279174),r=l(r,n,i,o,e.getUint32(0,!0),11,3936430074),o=l(o,r,n,i,e.getUint32(12,!0),16,3572445317),i=l(i,o,r,n,e.getUint32(24,!0),23,76029189),n=l(n,i,o,r,e.getUint32(36,!0),4,3654602809),r=l(r,n,i,o,e.getUint32(48,!0),11,3873151461),o=l(o,r,n,i,e.getUint32(60,!0),16,530742520),n=p(n,i=l(i,o,r,n,e.getUint32(8,!0),23,3299628645),o,r,e.getUint32(0,!0),6,4096336452),r=p(r,n,i,o,e.getUint32(28,!0),10,1126891415),o=p(o,r,n,i,e.getUint32(56,!0),15,2878612391),i=p(i,o,r,n,e.getUint32(20,!0),21,4237533241),n=p(n,i,o,r,e.getUint32(48,!0),6,1700485571),r=p(r,n,i,o,e.getUint32(12,!0),10,2399980690),o=p(o,r,n,i,e.getUint32(40,!0),15,4293915773),i=p(i,o,r,n,e.getUint32(4,!0),21,2240044497),n=p(n,i,o,r,e.getUint32(32,!0),6,1873313359),r=p(r,n,i,o,e.getUint32(60,!0),10,4264355552),o=p(o,r,n,i,e.getUint32(24,!0),15,2734768916),i=p(i,o,r,n,e.getUint32(52,!0),21,1309151649),n=p(n,i,o,r,e.getUint32(16,!0),6,4149444226),r=p(r,n,i,o,e.getUint32(44,!0),10,3174756917),o=p(o,r,n,i,e.getUint32(8,!0),15,718787259),i=p(i,o,r,n,e.getUint32(36,!0),21,3951481745),t[0]=n+t[0]&4294967295,t[1]=i+t[1]&4294967295,t[2]=o+t[2]&4294967295,t[3]=r+t[3]&4294967295}},{"./browserHashUtils":11,"buffer/":80}],14:[function(e,t,n){var o=e("buffer/").Buffer,r=e("./browserHashUtils");new Uint32Array([1518500249,1859775393,-1894007588,-899497514]),Math.pow(2,53);function i(){this.h0=1732584193,this.h1=4023233417,this.h2=2562383102,this.h3=271733878,this.h4=3285377520,this.block=new Uint32Array(80),this.offset=0,this.shift=24,this.totalLength=0}(t.exports=i).BLOCK_SIZE=64,i.prototype.update=function(e){if(this.finished)throw new Error("Attempted to update an already finished hash.");if(r.isEmptyData(e))return this;var t=(e=r.convertToBuffer(e)).length;this.totalLength+=8*t;for(var n=0;n>t);var n=new o(20),r=new DataView(n.buffer);return r.setUint32(0,this.h0,!1),r.setUint32(4,this.h1,!1),r.setUint32(8,this.h2,!1),r.setUint32(12,this.h3,!1),r.setUint32(16,this.h4,!1),e?n.toString(e):n},i.prototype.processBlock=function(){for(var e=16;e<80;e++){var t=this.block[e-3]^this.block[e-8]^this.block[e-14]^this.block[e-16];this.block[e]=t<<1|t>>>31}for(var n,r=this.h0,o=this.h1,i=this.h2,s=this.h3,c=this.h4,e=0;e<80;e++){a=e<20?(n=s^o&(i^s),1518500249):e<40?(n=o^i^s,1859775393):e<60?(n=o&i|s&(o|i),2400959708):(n=o^i^s,3395469782);var a=(r<<5|r>>>27)+n+c+a+(0|this.block[e]),c=s,s=i,i=o<<30|o>>>2,o=r,r=a}for(this.h0=this.h0+r|0,this.h1=this.h1+o|0,this.h2=this.h2+i|0,this.h3=this.h3+s|0,this.h4=this.h4+c|0,e=this.offset=0;e<16;e++)this.block[e]=0}},{"./browserHashUtils":11,"buffer/":80}],15:[function(e,t,n){var s=e("buffer/").Buffer,r=e("./browserHashUtils"),d=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),o=Math.pow(2,53)-1;function i(){this.state=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],this.temp=new Int32Array(64),this.buffer=new Uint8Array(64),this.bufferLength=0,this.bytesHashed=0,this.finished=!1}(t.exports=i).BLOCK_SIZE=64,i.prototype.update=function(e){if(this.finished)throw new Error("Attempted to update an already finished hash.");if(r.isEmptyData(e))return this;var t=0,n=(e=r.convertToBuffer(e)).byteLength;if(this.bytesHashed+=n,8*this.bytesHashed>o)throw new Error("Cannot hash more than 2^53 - 1 bits");for(;0>>24&255,i[4*o+1]=this.state[o]>>>16&255,i[4*o+2]=this.state[o]>>>8&255,i[4*o+3]=this.state[o]>>>0&255;return e?i.toString(e):i},i.prototype.hashBuffer=function(){for(var e=this.buffer,t=this.state,n=t[0],r=t[1],o=t[2],i=t[3],s=t[4],c=t[5],a=t[6],u=t[7],l=0;l<64;l++){l<16?this.temp[l]=(255&e[4*l])<<24|(255&e[4*l+1])<<16|(255&e[4*l+2])<<8|255&e[4*l+3]:(p=((h=this.temp[l-2])>>>17|h<<15)^(h>>>19|h<<13)^h>>>10,h=((h=this.temp[l-15])>>>7|h<<25)^(h>>>18|h<<14)^h>>>3,this.temp[l]=(p+this.temp[l-7]|0)+(h+this.temp[l-16]|0));var p=(((s>>>6|s<<26)^(s>>>11|s<<21)^(s>>>25|s<<7))+(s&c^~s&a)|0)+(u+(d[l]+this.temp[l]|0)|0)|0,h=((n>>>2|n<<30)^(n>>>13|n<<19)^(n>>>22|n<<10))+(n&r^n&o^r&o)|0,u=a,a=c,c=s,s=i+p|0,i=o,o=r,r=n,n=p+h|0}t[0]+=n,t[1]+=r,t[2]+=o,t[3]+=i,t[4]+=s,t[5]+=c,t[6]+=a,t[7]+=u}},{"./browserHashUtils":11,"buffer/":80}],16:[function(n,r,e){(function(e){var t=n("./util");t.crypto.lib=n("./browserCryptoLib"),t.Buffer=n("buffer/").Buffer,t.url=n("url/"),t.querystring=n("querystring/"),t.realClock=n("./realclock/browserClock"),t.environment="js",t.createEventStream=n("./event-stream/buffered-create-event-stream").createEventStream,t.isBrowser=function(){return!0},t.isNode=function(){return!1};t=n("./core");r.exports=t,n("./credentials"),n("./credentials/credential_provider_chain"),n("./credentials/temporary_credentials"),n("./credentials/chainable_temporary_credentials"),n("./credentials/web_identity_credentials"),n("./credentials/cognito_identity_credentials"),n("./credentials/saml_credentials"),t.XML.Parser=n("./xml/browser_parser"),n("./http/xhr"),void 0===e&&(e={browser:!0})}).call(this,n("_process"))},{"./browserCryptoLib":10,"./core":18,"./credentials":19,"./credentials/chainable_temporary_credentials":20,"./credentials/cognito_identity_credentials":21,"./credentials/credential_provider_chain":22,"./credentials/saml_credentials":23,"./credentials/temporary_credentials":24,"./credentials/web_identity_credentials":25,"./event-stream/buffered-create-event-stream":27,"./http/xhr":35,"./realclock/browserClock":52,"./util":71,"./xml/browser_parser":72,_process:85,"buffer/":80,"querystring/":92,"url/":94}],17:[function(e,t,n){var r,i=e("./core");e("./credentials"),e("./credentials/credential_provider_chain"),i.Config=i.util.inherit({constructor:function(n){void 0===n&&(n={}),n=this.extractCredentials(n),i.util.each.call(this,this.keys,function(e,t){this.set(e,n[e],t)})},getCredentials:function(t){var e,n=this;function r(e){t(e,e?null:n.credentials)}function o(e,t){return new i.util.error(t||new Error,{code:"CredentialsError",message:e,name:"CredentialsError"})}n.credentials?"function"==typeof n.credentials.get?n.credentials.get(function(e){r(e=e&&o("Could not load credentials from "+n.credentials.constructor.name,e))}):(e=null,n.credentials.accessKeyId&&n.credentials.secretAccessKey||(e=o("Missing credentials")),r(e)):n.credentialProvider?n.credentialProvider.resolve(function(e,t){e=e&&o("Could not load credentials from any providers",e),n.credentials=t,r(e)}):r(o("No credentials to load"))},update:function(e,n){n=n||!1,e=this.extractCredentials(e),i.util.each.call(this,e,function(e,t){(n||Object.prototype.hasOwnProperty.call(this.keys,e)||i.Service.hasService(e))&&this.set(e,t)})},loadFromPath:function(e){this.clear();var n=JSON.parse(i.util.readFileSync(e)),t=new i.FileSystemCredentials(e),e=new i.CredentialProviderChain;return e.providers.unshift(t),e.resolve(function(e,t){if(e)throw e;n.credentials=t}),this.constructor(n),this},clear:function(){i.util.each.call(this,this.keys,function(e){delete this[e]}),this.set("credentials",void 0),this.set("credentialProvider",void 0)},set:function(e,t,n){void 0===t?(void 0===n&&(n=this.keys[e]),this[e]="function"==typeof n?n.call(this):n):"httpOptions"===e&&this[e]?this[e]=i.util.merge(this[e],t):this[e]=t},keys:{credentials:null,credentialProvider:null,region:null,logger:null,apiVersions:{},apiVersion:null,endpoint:void 0,httpOptions:{timeout:12e4},maxRetries:void 0,maxRedirects:10,paramValidation:!0,sslEnabled:!0,s3ForcePathStyle:!1,s3BucketEndpoint:!1,s3DisableBodySigning:!0,computeChecksums:!0,convertResponseTypes:!0,correctClockSkew:!1,customUserAgent:null,dynamoDbCrc32:!0,systemClockOffset:0,signatureVersion:null,signatureCache:!0,retryDelayOptions:{},useAccelerateEndpoint:!1,clientSideMonitoring:!1,endpointDiscoveryEnabled:!1,endpointCacheSize:1e3,hostPrefixEnabled:!0,stsRegionalEndpoints:null},extractCredentials:function(e){return e.accessKeyId&&e.secretAccessKey&&((e=i.util.copy(e)).credentials=new i.Credentials(e)),e},setPromisesDependency:function(e){null===(r=e)&&"function"==typeof Promise&&(r=Promise);e=[i.Request,i.Credentials,i.CredentialProviderChain];i.S3&&(e.push(i.S3),i.S3.ManagedUpload&&e.push(i.S3.ManagedUpload)),i.util.addPromises(e,r)},getPromisesDependency:function(){return r}}),i.config=new i.Config},{"./core":18,"./credentials":19,"./credentials/credential_provider_chain":22}],18:[function(e,t,n){var r={util:e("./util")};({}).toString(),(t.exports=r).util.update(r,{VERSION:"2.553.0",Signers:{},Protocol:{Json:e("./protocol/json"),Query:e("./protocol/query"),Rest:e("./protocol/rest"),RestJson:e("./protocol/rest_json"),RestXml:e("./protocol/rest_xml")},XML:{Builder:e("./xml/builder"),Parser:null},JSON:{Builder:e("./json/builder"),Parser:e("./json/parser")},Model:{Api:e("./model/api"),Operation:e("./model/operation"),Shape:e("./model/shape"),Paginator:e("./model/paginator"),ResourceWaiter:e("./model/resource_waiter")},apiLoader:e("./api_loader"),EndpointCache:e("../vendor/endpoint-cache").EndpointCache}),e("./sequential_executor"),e("./service"),e("./config"),e("./http"),e("./event_listeners"),e("./request"),e("./response"),e("./resource_waiter"),e("./signers/request_signer"),e("./param_validator"),r.events=new r.SequentialExecutor,r.util.memoizedProperty(r,"endpointCache",function(){return new r.EndpointCache(r.config.endpointCacheSize)},!0)},{"../vendor/endpoint-cache":103,"./api_loader":9,"./config":17,"./event_listeners":33,"./http":34,"./json/builder":36,"./json/parser":37,"./model/api":38,"./model/operation":40,"./model/paginator":41,"./model/resource_waiter":42,"./model/shape":43,"./param_validator":44,"./protocol/json":46,"./protocol/query":47,"./protocol/rest":48,"./protocol/rest_json":49,"./protocol/rest_xml":50,"./request":55,"./resource_waiter":56,"./response":57,"./sequential_executor":58,"./service":59,"./signers/request_signer":63,"./util":71,"./xml/builder":73}],19:[function(e,t,n){var o=e("./core");o.Credentials=o.util.inherit({constructor:function(e,t,n){var r;o.util.hideProperties(this,["secretAccessKey"]),this.expired=!1,this.expireTime=null,this.refreshCallbacks=[],1===arguments.length&&"object"==typeof e?(r=e.credentials||e,this.accessKeyId=r.accessKeyId,this.secretAccessKey=r.secretAccessKey,this.sessionToken=r.sessionToken):(this.accessKeyId=e,this.secretAccessKey=t,this.sessionToken=n)},expiryWindow:15,needsRefresh:function(){var e=o.util.date.getDate().getTime(),e=new Date(e+1e3*this.expiryWindow);return!!(this.expireTime&&e>this.expireTime)||(this.expired||!this.accessKeyId||!this.secretAccessKey)},get:function(t){var n=this;this.needsRefresh()?this.refresh(function(e){e||(n.expired=!1),t&&t(e)}):t&&t()},refresh:function(e){this.expired=!1,e()},coalesceRefresh:function(e,n){var r=this;1===r.refreshCallbacks.push(e)&&r.load(function(t){o.util.arrayEach(r.refreshCallbacks,function(e){n?e(t):o.util.defer(function(){e(t)})}),r.refreshCallbacks.length=0})},load:function(e){e()}}),o.Credentials.addPromisesToClass=function(e){this.prototype.getPromise=o.util.promisifyMethod("get",e),this.prototype.refreshPromise=o.util.promisifyMethod("refresh",e)},o.Credentials.deletePromisesFromClass=function(){delete this.prototype.getPromise,delete this.prototype.refreshPromise},o.util.addPromises(o.Credentials)},{"./core":18}],20:[function(e,t,n){var i=e("../core"),r=e("../../clients/sts");i.ChainableTemporaryCredentials=i.util.inherit(i.Credentials,{constructor:function(e){i.Credentials.call(this),e=e||{},this.errorCode="ChainableTemporaryCredentialsProviderFailure",this.expired=!0,this.tokenCodeFn=null;var t=i.util.copy(e.params)||{};if(t.RoleArn&&(t.RoleSessionName=t.RoleSessionName||"temporary-credentials"),t.SerialNumber){if(!e.tokenCodeFn||"function"!=typeof e.tokenCodeFn)throw new i.util.error(new Error("tokenCodeFn must be a function when params.SerialNumber is given"),{code:this.errorCode});this.tokenCodeFn=e.tokenCodeFn}e=i.util.merge({params:t,credentials:e.masterCredentials||i.config.credentials},e.stsConfig||{});this.service=new r(e)},refresh:function(e){this.coalesceRefresh(e||i.util.fn.callback)},load:function(r){var o=this,i=o.service.config.params.RoleArn?"assumeRole":"getSessionToken";this.getTokenCode(function(e,t){var n={};e?r(e):(t&&(n.TokenCode=t),o.service[i](n,function(e,t){e||o.service.credentialsFrom(t,o),r(e)}))})},getTokenCode:function(r){var o=this;this.tokenCodeFn?this.tokenCodeFn(this.service.config.params.SerialNumber,function(e,t){if(e){var n=e;return e instanceof Error&&(n=e.message),void r(i.util.error(new Error("Error fetching MFA token: "+n),{code:o.errorCode}))}r(null,t)}):r(null)}})},{"../../clients/sts":8,"../core":18}],21:[function(e,t,n){var r=e("../core"),o=e("../../clients/cognitoidentity"),i=e("../../clients/sts");r.CognitoIdentityCredentials=r.util.inherit(r.Credentials,{localStorageKey:{id:"aws.cognito.identity-id.",providers:"aws.cognito.identity-providers."},constructor:function(e,t){r.Credentials.call(this),this.expired=!0,this.params=e,this.data=null,this._identityId=null,this._clientConfig=r.util.copy(t||{}),this.loadCachedId();var n=this;Object.defineProperty(this,"identityId",{get:function(){return n.loadCachedId(),n._identityId||n.params.IdentityId},set:function(e){n._identityId=e}})},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(t){var n=this;n.createClients(),n.data=null,n._identityId=null,n.getId(function(e){e?(n.clearIdOnNotAuthorized(e),t(e)):n.params.RoleArn?n.getCredentialsFromSTS(t):n.getCredentialsForIdentity(t)})},clearCachedId:function(){this._identityId=null,delete this.params.IdentityId;var e=this.params.IdentityPoolId,t=this.params.LoginId||"";delete this.storage[this.localStorageKey.id+e+t],delete this.storage[this.localStorageKey.providers+e+t]},clearIdOnNotAuthorized:function(e){"NotAuthorizedException"==e.code&&this.clearCachedId()},getId:function(n){var r=this;if("string"==typeof r.params.IdentityId)return n(null,r.params.IdentityId);r.cognito.getId(function(e,t){!e&&t.IdentityId?(r.params.IdentityId=t.IdentityId,n(null,t.IdentityId)):n(e)})},loadCredentials:function(e,t){e&&t&&(t.expired=!1,t.accessKeyId=e.Credentials.AccessKeyId,t.secretAccessKey=e.Credentials.SecretKey,t.sessionToken=e.Credentials.SessionToken,t.expireTime=e.Credentials.Expiration)},getCredentialsForIdentity:function(n){var r=this;r.cognito.getCredentialsForIdentity(function(e,t){e?r.clearIdOnNotAuthorized(e):(r.cacheId(t),r.data=t,r.loadCredentials(r.data,r)),n(e)})},getCredentialsFromSTS:function(n){var r=this;r.cognito.getOpenIdToken(function(e,t){e?(r.clearIdOnNotAuthorized(e),n(e)):(r.cacheId(t),r.params.WebIdentityToken=t.Token,r.webIdentityCredentials.refresh(function(e){e||(r.data=r.webIdentityCredentials.data,r.sts.credentialsFrom(r.data,r)),n(e)}))})},loadCachedId:function(){var e,t,n=this;r.util.isBrowser()&&!n.params.IdentityId&&((e=n.getStorage("id"))&&n.params.Logins?(t=Object.keys(n.params.Logins),0!==(n.getStorage("providers")||"").split(",").filter(function(e){return-1!==t.indexOf(e)}).length&&(n.params.IdentityId=e)):e&&(n.params.IdentityId=e))},createClients:function(){var e,t=this._clientConfig;this.webIdentityCredentials=this.webIdentityCredentials||new r.WebIdentityCredentials(this.params,t),this.cognito||((e=r.util.merge({},t)).params=this.params,this.cognito=new o(e)),this.sts=this.sts||new i(t)},cacheId:function(e){this._identityId=e.IdentityId,this.params.IdentityId=this._identityId,r.util.isBrowser()&&(this.setStorage("id",e.IdentityId),this.params.Logins&&this.setStorage("providers",Object.keys(this.params.Logins).join(",")))},getStorage:function(e){return this.storage[this.localStorageKey[e]+this.params.IdentityPoolId+(this.params.LoginId||"")]},setStorage:function(e,t){try{this.storage[this.localStorageKey[e]+this.params.IdentityPoolId+(this.params.LoginId||"")]=t}catch(e){}},storage:function(){try{var e=r.util.isBrowser()&&null!==window.localStorage&&"object"==typeof window.localStorage?window.localStorage:{};return e["aws.test-storage"]="foobar",delete e["aws.test-storage"],e}catch(e){return{}}}()})},{"../../clients/cognitoidentity":7,"../../clients/sts":8,"../core":18}],22:[function(e,t,n){var c=e("../core");c.CredentialProviderChain=c.util.inherit(c.Credentials,{constructor:function(e){this.providers=e||c.CredentialProviderChain.defaultProviders.slice(0),this.resolveCallbacks=[]},resolve:function(e){var o,i,s=this;return 0===s.providers.length?e(new Error("No providers")):1===s.resolveCallbacks.push(e)&&(o=0,i=s.providers.slice(0),function t(n,r){if(!n&&r||o===i.length)return c.util.arrayEach(s.resolveCallbacks,function(e){e(n,r)}),void(s.resolveCallbacks.length=0);var e=i[o++];(r="function"==typeof e?e.call():e).get?r.get(function(e){t(e,e?null:r)}):t(null,r)}()),s}}),c.CredentialProviderChain.defaultProviders=[],c.CredentialProviderChain.addPromisesToClass=function(e){this.prototype.resolvePromise=c.util.promisifyMethod("resolve",e)},c.CredentialProviderChain.deletePromisesFromClass=function(){delete this.prototype.resolvePromise},c.util.addPromises(c.CredentialProviderChain)},{"../core":18}],23:[function(e,t,n){var r=e("../core"),o=e("../../clients/sts");r.SAMLCredentials=r.util.inherit(r.Credentials,{constructor:function(e){r.Credentials.call(this),this.expired=!0,this.params=e},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(n){var r=this;r.createClients(),r.service.assumeRoleWithSAML(function(e,t){e||r.service.credentialsFrom(t,r),n(e)})},createClients:function(){this.service=this.service||new o({params:this.params})}})},{"../../clients/sts":8,"../core":18}],24:[function(e,t,n){var r=e("../core"),o=e("../../clients/sts");r.TemporaryCredentials=r.util.inherit(r.Credentials,{constructor:function(e,t){r.Credentials.call(this),this.loadMasterCredentials(t),this.expired=!0,this.params=e||{},this.params.RoleArn&&(this.params.RoleSessionName=this.params.RoleSessionName||"temporary-credentials")},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(n){var r=this;r.createClients(),r.masterCredentials.get(function(){r.service.config.credentials=r.masterCredentials,(r.params.RoleArn?r.service.assumeRole:r.service.getSessionToken).call(r.service,function(e,t){e||r.service.credentialsFrom(t,r),n(e)})})},loadMasterCredentials:function(e){for(this.masterCredentials=e||r.config.credentials;this.masterCredentials.masterCredentials;)this.masterCredentials=this.masterCredentials.masterCredentials;"function"!=typeof this.masterCredentials.get&&(this.masterCredentials=new r.Credentials(this.masterCredentials))},createClients:function(){this.service=this.service||new o({params:this.params})}})},{"../../clients/sts":8,"../core":18}],25:[function(e,t,n){var r=e("../core"),o=e("../../clients/sts");r.WebIdentityCredentials=r.util.inherit(r.Credentials,{constructor:function(e,t){r.Credentials.call(this),this.expired=!0,this.params=e,this.params.RoleSessionName=this.params.RoleSessionName||"web-identity",this.data=null,this._clientConfig=r.util.copy(t||{})},refresh:function(e){this.coalesceRefresh(e||r.util.fn.callback)},load:function(n){var r=this;r.createClients(),r.service.assumeRoleWithWebIdentity(function(e,t){r.data=null,e||(r.data=t,r.service.credentialsFrom(t,r)),n(e)})},createClients:function(){var e;this.service||((e=r.util.merge({},this._clientConfig)).params=this.params,this.service=new o(e))}})},{"../../clients/sts":8,"../core":18}],26:[function(e,t,n){(function(o){var u=e("./core"),l=e("./util"),i=["AWS_ENABLE_ENDPOINT_DISCOVERY","AWS_ENDPOINT_DISCOVERY_ENABLED"];function p(e){var t=e.service,n=t.api||{},e={};return t.config.region&&(e.region=t.config.region),n.serviceId&&(e.serviceId=n.serviceId),t.config.credentials.accessKeyId&&(e.accessKeyId=t.config.credentials.accessKeyId),e}function h(e,t){var n={};return function r(o,i,s){s&&null!=i&&"structure"===s.type&&s.required&&0=this.HEADERS_RECEIVED&&!u&&(s.statusCode=a.status,s.headers=o.parseHeaders(a.getAllResponseHeaders()),s.emit("headers",s.statusCode,s.headers,a.statusText),u=!0),this.readyState===this.DONE&&o.finishRequest(a,s)},!1),a.upload.addEventListener("progress",function(e){s.emit("sendProgress",e)}),a.addEventListener("progress",function(e){s.emit("receiveProgress",e)},!1),a.addEventListener("timeout",function(){r(l.util.error(new Error("Timeout"),{code:"TimeoutError"}))},!1),a.addEventListener("error",function(){r(l.util.error(new Error("Network Failure"),{code:"NetworkingError"}))},!1),a.addEventListener("abort",function(){r(l.util.error(new Error("Request aborted"),{code:"RequestAbortedError"}))},!1),n(s),a.open(t.method,c,!1!==e.xhrAsync),l.util.each(t.headers,function(e,t){"Content-Length"!==e&&"User-Agent"!==e&&"Host"!==e&&a.setRequestHeader(e,t)}),e.timeout&&!1!==e.xhrAsync&&(a.timeout=e.timeout),e.xhrWithCredentials&&(a.withCredentials=!0);try{a.responseType="arraybuffer"}catch(e){}try{t.body?a.send(t.body):a.send()}catch(e){if(!t.body||"object"!=typeof t.body.buffer)throw e;a.send(t.body.buffer)}return s},parseHeaders:function(e){var n={};return l.util.arrayEach(e.split(/\r?\n/),function(e){var t=e.split(":",1)[0],e=e.substring(t.length+2);0= 1, but found "'+t+'" for '+n)},validatePattern:function(e,t,n){this.validation.pattern&&void 0!==e.pattern&&(new RegExp(e.pattern).test(t)||this.fail("PatternMatchError",'Provided value "'+t+'" does not match regex pattern /'+e.pattern+"/ for "+n))},validateRange:function(e,t,n,r){this.validation.min&&void 0!==e.min&&t= "+e.min+", but found "+t+" for "+n),this.validation.max&&void 0!==e.max&&t>e.max&&this.fail("MaxRangeError","Expected "+r+" <= "+e.max+", but found "+t+" for "+n)},validateEnum:function(e,t,n){this.validation.enum&&void 0!==e.enum&&-1===e.enum.indexOf(t)&&this.fail("EnumError","Found string value of "+t+", but expected "+e.enum.join("|")+" for "+n)},validateType:function(e,t,n,r){if(null==e)return!1;for(var o=!1,i=0;i=e.maxRetries&&(t.MaxRetriesExceeded=1),u.emit("apiCall",[t]))})},setupRequestListeners:function(){},getSignerClass:function(e){var t=null,n="";return e&&(n=(t=(e.service.api.operations||{})[e.operation]||null)?t.authtype:""),n=this.config.signatureVersion||("v4"===n||"v4-unsigned-body"===n?"v4":this.api.signatureVersion),l.Signers.RequestSigner.getVersion(n)},serviceInterface:function(){switch(this.api.protocol){case"ec2":case"query":return l.EventListeners.Query;case"json":return l.EventListeners.Json;case"rest-json":return l.EventListeners.RestJson;case"rest-xml":return l.EventListeners.RestXml}if(this.api.protocol)throw new Error("Invalid service `protocol' "+this.api.protocol+" in API config")},successfulResponse:function(e){return e.httpResponse.statusCode<300},numRetries:function(){return void 0!==this.config.maxRetries?this.config.maxRetries:this.defaultRetryCount},retryDelays:function(e){return l.util.calculateRetryDelay(e,this.config.retryDelayOptions)},retryableError:function(e){return!!this.timeoutError(e)||(!!this.networkingError(e)||(!!this.expiredCredentialsError(e)||(!!this.throttledError(e)||500<=e.statusCode)))},networkingError:function(e){return"NetworkingError"===e.code},timeoutError:function(e){return"TimeoutError"===e.code},expiredCredentialsError:function(e){return"ExpiredTokenException"===e.code},clockSkewError:function(e){switch(e.code){case"RequestTimeTooSkewed":case"RequestExpired":case"InvalidSignatureException":case"SignatureDoesNotMatch":case"AuthFailure":case"RequestInTheFuture":return!0;default:return!1}},getSkewCorrectedDate:function(){return new Date(Date.now()+this.config.systemClockOffset)},applyClockOffset:function(e){e&&(this.config.systemClockOffset=e-Date.now())},isClockSkewed:function(e){if(e)return 3e4<=Math.abs(this.getSkewCorrectedDate().getTime()-e)},throttledError:function(e){if(429===e.statusCode)return!0;switch(e.code){case"ProvisionedThroughputExceededException":case"Throttling":case"ThrottlingException":case"RequestLimitExceeded":case"RequestThrottled":case"RequestThrottledException":case"TooManyRequestsException":case"TransactionInProgressException":return!0;default:return!1}},endpointFromTemplate:function(e){if("string"!=typeof e)return e;return e=(e=(e=e.replace(/\{service\}/g,this.api.endpointPrefix)).replace(/\{region\}/g,this.config.region)).replace(/\{scheme\}/g,this.config.sslEnabled?"https":"http")},setEndpoint:function(e){this.endpoint=new l.Endpoint(e,this.config)},paginationConfig:function(e,t){var n=this.api.operations[e].paginator;if(n)return n;if(t){t=new Error;throw l.util.error(t,"No pagination configuration for "+e)}return null}}),l.util.update(l.Service,{defineMethods:function(e){l.util.each(e.prototype.api.operations,function(n){e.prototype[n]||("none"===e.prototype.api.operations[n].authtype?e.prototype[n]=function(e,t){return this.makeUnauthenticatedRequest(n,e,t)}:e.prototype[n]=function(e,t){return this.makeRequest(n,e,t)})})},defineService:function(e,t,n){l.Service._serviceMap[e]=!0,Array.isArray(t)||(n=t,t=[]);var r,n=s(l.Service,n||{});return"string"==typeof e?(l.Service.addVersions(n,t),r=n.serviceIdentifier||e,n.serviceIdentifier=r):(n.prototype.api=e,l.Service.defineMethods(n)),l.SequentialExecutor.call(this.prototype),!this.prototype.publisher&&l.util.clientSideMonitoring&&(r=l.util.clientSideMonitoring.Publisher,e=(0,l.util.clientSideMonitoring.configProvider)(),this.prototype.publisher=new r(e),e.enabled&&(l.Service._clientSideMonitoring=!0)),l.SequentialExecutor.call(n.prototype),l.Service.addDefaultMonitoringListeners(n.prototype),n},addVersions:function(e,t){Array.isArray(t)||(t=[t]),e.services=e.services||{};for(var n=0;n=t.length)return n.push(null);e=r+e;e>t.length&&(e=t.length),n.push(t.slice(r,e)),r=e},n},concat:function(e){for(var t,n=0,r=0,o=0;o>>8^t[255&(n^e.readUInt8(r))];return(-1^n)>>>0},hmac:function(e,t,n,r){return"buffer"===(n=n||"binary")&&(n=void 0),r=r||"sha256","string"==typeof t&&(t=u.buffer.toBuffer(t)),u.crypto.lib.createHmac(r,e).update(t).digest(n)},md5:function(e,t,n){return u.crypto.hash("md5",e,t,n)},sha256:function(e,t,n){return u.crypto.hash("sha256",e,t,n)},hash:function(e,t,n,r){var o=u.crypto.createHash(e);"buffer"===(n=n||"binary")&&(n=void 0),"string"==typeof t&&(t=u.buffer.toBuffer(t));var i=u.arraySliceFn(t),e=u.Buffer.isBuffer(t);if(u.isBrowser()&&"undefined"!=typeof ArrayBuffer&&t&&t.buffer instanceof ArrayBuffer&&(e=!0),r&&"object"==typeof t&&"function"==typeof t.on&&!e)t.on("data",function(e){o.update(e)}),t.on("error",function(e){r(e)}),t.on("end",function(){r(null,o.digest(n))});else{if(!r||!i||e||"undefined"==typeof FileReader){u.isBrowser()&&"object"==typeof t&&!e&&(t=new u.Buffer(new Uint8Array(t)));e=o.update(t).digest(n);return r&&r(null,e),e}var s=0,c=new FileReader;c.onerror=function(){r(new Error("Failed to read data."))},c.onload=function(){var e=new u.Buffer(new Uint8Array(c.result));o.update(e),s+=e.length,c._continueReading()},c._continueReading=function(){var e;s>=t.size?r(null,o.digest(n)):((e=s+524288)>t.size&&(e=t.size),c.readAsArrayBuffer(i.call(t,s,e)))},c._continueReading()}},toHex:function(e){for(var t=[],n=0;n/g,">").replace(/"/g,""")}}},{}],75:[function(e,t,n){t.exports={escapeElement:function(e){return e.replace(/&/g,"&").replace(//g,">")}}},{}],76:[function(e,t,n){var c=e("./escape-attribute").escapeAttribute;function r(e,t){void 0===t&&(t=[]),this.name=e,this.children=t,this.attributes={}}r.prototype.addAttribute=function(e,t){return this.attributes[e]=t,this},r.prototype.addChildNode=function(e){return this.children.push(e),this},r.prototype.removeAttribute=function(e){return delete this.attributes[e],this},r.prototype.toString=function(){for(var e=Boolean(this.children.length),t="<"+this.name,n=this.attributes,r=0,o=Object.keys(n);r"+this.children.map(function(e){return e.toString()}).join("")+"":"/>")},t.exports={XmlNode:r}},{"./escape-attribute":74}],77:[function(e,t,n){var r=e("./escape-element").escapeElement;function o(e){this.value=e}o.prototype.toString=function(){return r(""+this.value)},t.exports={XmlText:o}},{"./escape-element":75}],78:[function(e,t,n){"use strict";n.byteLength=function(e){var t=l(e),e=t[0],t=t[1];return 3*(e+t)/4-t},n.toByteArray=function(e){var t,n,r=l(e),o=r[0],r=r[1],i=new u(function(e,t){return 3*(e+t)/4-t}(o,r)),s=0,c=0>16&255,i[s++]=t>>8&255,i[s++]=255&t;2===r&&(t=a[e.charCodeAt(n)]<<2|a[e.charCodeAt(n+1)]>>4,i[s++]=255&t);1===r&&(t=a[e.charCodeAt(n)]<<10|a[e.charCodeAt(n+1)]<<4|a[e.charCodeAt(n+2)]>>2,i[s++]=t>>8&255,i[s++]=255&t);return i},n.fromByteArray=function(e){for(var t,n=e.length,r=n%3,o=[],i=0,s=n-r;i>18&63]+c[e>>12&63]+c[e>>6&63]+c[63&e]}(r));return o.join("")}(e,i,s>2]+c[t<<4&63]+"==")):2==r&&(t=(e[n-2]<<8)+e[n-1],o.push(c[t>>10]+c[t>>4&63]+c[t<<2&63]+"="));return o.join("")};for(var c=[],a=[],u="undefined"!=typeof Uint8Array?Uint8Array:Array,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",o=0,i=r.length;o=n())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+n().toString(16)+" bytes");return 0|e}function d(e,t){if(p.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return k(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return N(e).length;default:if(r)return k(e).length;t=(""+t).toLowerCase(),r=!0}}function t(e,t,n){var r,o,i,s=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return function(e,t,n){var r=e.length;(!t||t<0)&&(t=0);(!n||n<0||r=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=p.from(t,r)),p.isBuffer(t))return 0===t.length?-1:m(e,t,n,r,o);if("number"==typeof t)return t&=255,p.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?(o?Uint8Array.prototype.indexOf:Uint8Array.prototype.lastIndexOf).call(e,t,n):m(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function m(e,t,n,r,o){var i=1,s=e.length,c=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;s/=i=2,c/=2,n/=2}function a(e,t){return 1===i?e[t]:e.readUInt16BE(t*i)}if(o)for(var u=-1,l=n;l>8,r=r%256,o.push(r),o.push(n);return o}(t,e.length-n),e,n,r)}function b(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o>>10&1023|55296),l=56320|1023&l),r.push(l),o+=p}return function(e){var t=e.length;if(t<=E)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rt&&(e+=" ... ")),""},p.prototype.compare=function(e,t,n,r,o){if(!p.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(o<=r&&n<=t)return 0;if(o<=r)return-1;if(n<=t)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),s=(n>>>=0)-(t>>>=0),c=Math.min(i,s),a=this.slice(r,o),u=e.slice(t,n),l=0;lthis.length)throw new RangeError("Attempt to write outside buffer bounds");r=r||"utf8";for(var i,s,c,a=!1;;)switch(r){case"hex":return function(e,t,n,r){n=Number(n)||0;var o=e.length-n;if((!r||o<(r=Number(r)))&&(r=o),(o=t.length)%2!=0)throw new TypeError("Invalid hex string");o/2e.length)throw new RangeError("Index out of range")}function T(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function I(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function w(e,t,n,r){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function A(e,t,n,r,o){return o||w(e,0,n,4),i.write(e,t,n,r,23,4),n+4}function _(e,t,n,r,o){return o||w(e,0,n,8),i.write(e,t,n,r,52,8),n+8}p.prototype.slice=function(e,t){var n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):T(this,e,t,!0),t+2},p.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,2,65535,0),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):T(this,e,t,!1),t+2},p.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,4294967295,0),p.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):I(this,e,t,!0),t+4},p.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,4294967295,0),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):I(this,e,t,!1),t+4},p.prototype.writeIntLE=function(e,t,n,r){e=+e,t|=0,r||C(this,e,t,n,(r=Math.pow(2,8*n-1))-1,-r);var o=0,i=1,s=0;for(this[t]=255&e;++o>0)-s&255;return t+n},p.prototype.writeIntBE=function(e,t,n,r){e=+e,t|=0,r||C(this,e,t,n,(r=Math.pow(2,8*n-1))-1,-r);var o=n-1,i=1,s=0;for(this[t+o]=255&e;0<=--o&&(i*=256);)e<0&&0===s&&0!==this[t+o+1]&&(s=1),this[t+o]=(e/i>>0)-s&255;return t+n},p.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,1,127,-128),p.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},p.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,2,32767,-32768),p.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):T(this,e,t,!0),t+2},p.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,2,32767,-32768),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):T(this,e,t,!1),t+2},p.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,2147483647,-2147483648),p.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):I(this,e,t,!0),t+4},p.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||C(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),p.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):I(this,e,t,!1),t+4},p.prototype.writeFloatLE=function(e,t,n){return A(this,e,t,!0,n)},p.prototype.writeFloatBE=function(e,t,n){return A(this,e,t,!1,n)},p.prototype.writeDoubleLE=function(e,t,n){return _(this,e,t,!0,n)},p.prototype.writeDoubleBE=function(e,t,n){return _(this,e,t,!1,n)},p.prototype.copy=function(e,t,n,r){if(n=n||0,r||0===r||(r=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(c=t;c>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function N(e){return c.toByteArray(function(e){var t;if((e=((t=e).trim?t.trim():t.replace(/^\s+|\s+$/g,"")).replace(R,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function O(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},L("buffer").Buffer)},{"base64-js":78,buffer:80,ieee754:82,isarray:83}],81:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function a(e){return"function"==typeof e}function u(e){return"object"==typeof e&&null!==e}function l(e){return void 0===e}((t.exports=r).EventEmitter=r).prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,o,i,s;if(this._events||(this._events={}),"error"===e&&(!this._events.error||u(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var c=new Error('Uncaught, unspecified "error" event. ('+t+")");throw c.context=t,c}if(l(n=this._events[e]))return!1;if(a(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:o=Array.prototype.slice.call(arguments,1),n.apply(this,o)}else if(u(n))for(o=Array.prototype.slice.call(arguments,1),r=(s=n.slice()).length,i=0;in&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},r.prototype.once=function(e,t){if(!a(t))throw TypeError("listener must be a function");var n=!1;function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,o,i;if(!a(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(o=(n=this._events[e]).length,r=-1,n===t||a(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(u(n)){for(i=o;0>1,l=-7,p=n?o-1:0,h=n?-1:1,n=e[t+p];for(p+=h,i=n&(1<<-l)-1,n>>=-l,l+=c;0>=-l,l+=r;0>1,p=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:i-1,d=r?1:-1,i=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(c=isNaN(t)?1:0,s=u):(s=Math.floor(Math.log(t)/Math.LN2),t*(r=Math.pow(2,-s))<1&&(s--,r*=2),2<=(t+=1<=s+l?p/r:p*Math.pow(2,1-l))*r&&(s++,r/=2),u<=s+l?(c=0,s=u):1<=s+l?(c=(t*r-1)*Math.pow(2,o),s+=l):(c=t*Math.pow(2,l-1)*Math.pow(2,o),s=0));8<=o;e[n+h]=255&c,h+=d,c/=256,o-=8);for(s=s<":!0,"=":!0,"!":!0},U={" ":!0,"\t":!0,"\n":!0};function q(e){return"0"<=e&&e<="9"||"-"===e}function F(){}F.prototype={tokenize:function(e){var t,n,r,o,i=[];for(this._current=0;this._current"===n?"="===e[this._current]?(this._current++,{type:N,value:">=",start:t}):{type:"GT",value:">",start:t}:"="===n&&"="===e[this._current]?(this._current++,{type:"EQ",value:"==",start:t}):void 0},_consumeLiteral:function(e){this._current++;for(var t=this._current,n=e.length;"`"!==e[this._current]&&this._current= 0x80 (not a basic code point)","invalid-input":"Invalid input"},h=v-b,I=Math.floor,w=String.fromCharCode;function A(e){throw RangeError(p[e])}function d(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function f(e,t){var n=e.split("@"),r="";return 1>>10&1023|55296),e=56320|1023&e),t+=w(e)}).join("")}function R(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function k(e,t,n){var r=0;for(e=n?I(e/c):e>>1,e+=I(e/t);h*E>>1I((y-l)/i))&&A("overflow"),l+=c*i,!(c<(c=s<=h?b:h+E<=s?E:s-h));s+=v)i>I(y/(c=v-c))&&A("overflow"),i*=c;h=k(l-o,t=a.length+1,0==o),I(l/t)>y-p&&A("overflow"),p+=I(l/t),l%=t,a.splice(l++,0,p)}return g(a)}function N(e){for(var t,n,r,o,i,s,c,a,u,l,p,h=[],d=(e=_(e)).length,f=C,g=S,m=t=0;mI((y-t)/(u=n+1))&&A("overflow"),t+=(o-f)*u,f=o,m=0;my&&A("overflow"),a==f){for(i=t,s=v;!(i<(c=s<=g?b:g+E<=s?E:s-g));s+=v)p=i-c,l=v-c,h.push(w(R(c+p%l,0))),i=I(p/l);h.push(w(R(i,0))),g=k(t,u,n==r),t=0,++n}++t,++f}return h.join("")}if(o={version:"1.3.2",ucs2:{decode:_,encode:g},decode:m,encode:N,toASCII:function(e){return f(e,function(e){return u.test(e)?"xn--"+N(e):e})},toUnicode:function(e){return f(e,function(e){return a.test(e)?m(e.slice(4).toLowerCase()):e})}},"function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",function(){return o});else if(t&&n)if(L.exports==t)n.exports=o;else for(i in o)o.hasOwnProperty(i)&&(t[i]=o[i]);else e.punycode=o}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],87:[function(e,t,n){"use strict";t.exports=function(e,t,n,r){t=t||"&",n=n||"=";var o={};if("string"!=typeof e||0===e.length)return o;var i=/\+/g;e=e.split(t);t=1e3;r&&"number"==typeof r.maxKeys&&(t=r.maxKeys);var s=e.length;0",'"',"`"," ","\r","\n","\t"]),R=["'"].concat(n),k=["%","/","?",";","#"].concat(R),N=["/","?","#"],O=/^[a-z0-9A-Z_-]{0,63}$/,L=/^([a-z0-9A-Z_-]{0,63})(.*)$/,x={javascript:!0,"javascript:":!0},P={javascript:!0,"javascript:":!0},D={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},M=e("querystring");function o(e,t,n){if(e&&s(e)&&e instanceof h)return e;var r=new h;return r.parse(e,t,n),r}function U(e){return"string"==typeof e}function s(e){return"object"==typeof e&&null!==e}function d(e){return null===e}h.prototype.parse=function(e,t,n){if(!U(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var r,o,i=(i=e).trim(),e=_.exec(i);if(e&&(r=(e=e[0]).toLowerCase(),this.protocol=r,i=i.substr(e.length)),(n||e||i.match(/^\/\/[^@\/]+@[^@\/]+/))&&(!(o="//"===i.substr(0,2))||e&&P[e]||(i=i.substr(2),this.slashes=!0)),!P[e]&&(o||e&&!D[e])){for(var s=-1,c=0;c>>((3&t)<<3)&255;return o})},{}],101:[function(e,t,n){var l,p,h=e("./lib/rng"),d=e("./lib/bytesToUuid"),f=0,g=0;t.exports=function(e,t,n){var r=t&&n||0,o=t||[],i=(e=e||{}).node||l,s=void 0!==e.clockseq?e.clockseq:p;null!=i&&null!=s||(a=h(),null==i&&(i=l=[1|a[0],a[1],a[2],a[3],a[4],a[5]]),null==s&&(s=p=16383&(a[6]<<8|a[7])));var c=void 0!==e.msecs?e.msecs:(new Date).getTime(),n=void 0!==e.nsecs?e.nsecs:g+1,a=c-f+(n-g)/1e4;if(a<0&&void 0===e.clockseq&&(s=s+1&16383),(a<0||f>>24&255,o[r++]=n>>>16&255,o[r++]=n>>>8&255,o[r++]=255&n,c=c/4294967296*1e4&268435455,o[r++]=c>>>8&255,o[r++]=255&c,o[r++]=c>>>24&15|16,o[r++]=c>>>16&255,o[r++]=s>>>8|128,o[r++]=255&s;for(var u=0;u<6;++u)o[r+u]=i[u];return t||d(o)}},{"./lib/bytesToUuid":99,"./lib/rng":100}],102:[function(e,t,n){var s=e("./lib/rng"),c=e("./lib/bytesToUuid");t.exports=function(e,t,n){var r=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var o=(e=e||{}).random||(e.rng||s)();if(o[6]=15&o[6]|64,o[8]=63&o[8]|128,t)for(var i=0;i<16;++i)t[r+i]=o[i];return t||c(o)}},{"./lib/bytesToUuid":99,"./lib/rng":100}],103:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./utils/LRU"),e=(Object.defineProperty(i.prototype,"size",{get:function(){return this.cache.length},enumerable:!0,configurable:!0}),i.prototype.put=function(e,t){e="string"!=typeof e?i.getKeyString(e):e,t=this.populateValue(t);this.cache.put(e,t)},i.prototype.get=function(e){var t="string"!=typeof e?i.getKeyString(e):e,n=Date.now(),r=this.cache.get(t);if(r)for(var o=0;o>>=0;break;case"x":r=r.toString(16);break;case"X":r=r.toString(16).toUpperCase()}r=/[def]/.test(i[8])&&i[3]&&0<=r?"+"+r:r,s=i[4]?"0"==i[4]?"0":i[4].charAt(1):" ",c=i[6]-String(r).length,c=i[6]?function(e,t){for(var n=[];0=this._logLevel&&(s[e.level]>=this._echoLevel&&c[e.getLevel()](e.toString()),e.line=this._lineCount++)},u.prototype.sendInternalLogEntryToServer=function(e){this._serverBoundInternalLogs.push(e),e.level in s&&s[e.level]>=this._logLevel&&(s[e.level]>=this._echoLevel&&c[e.getLevel()](e.toString()),e.line=this._lineCount++)},u.prototype.clearObjects=function(){for(var e=0;e=r._logLevel}));n=new o.Blob([JSON.stringify(e,void 0,4)],["text/plain"]),e=document.createElement("a"),t=t||"agent-log";e.href=o.URL.createObjectURL(n),e.download=t+".txt",document.body.appendChild(e),e.click(),document.body.removeChild(e)},u.prototype.scheduleUpstreamLogPush=function(e){connect.upstreamLogPushScheduled||(connect.upstreamLogPushScheduled=!0,o.setInterval(connect.hitch(this,this.reportMasterLogsUpStream,e),5e3))},u.prototype.reportMasterLogsUpStream=function(e){var t=this._logsToPush.slice();this._logsToPush=[],connect.ifMaster(connect.MasterTopics.SEND_LOGS,function(){0=connect.HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR||e.status===connect.HTTP_STATUS_CODES.TOO_MANY_REQUESTS)?setTimeout(function(){t(--n)},s):o(e)}).catch(function(e){o(e)})}(t)})},connect.backoff=function(r,o,i,s){connect.assertTrue(connect.isFunction(r),"func must be a Function");var c=this;r({success:function(e){s&&s.success&&s.success(e)},failure:function(e,t){var n;0>",e)},u.prototype.getSubscriptions=function(e){return this.subMap.getSubscriptions(e)},u.prototype.trigger=function(t,n){connect.assertNotNull(t,"eventName");var r=this,e=this.subMap.getSubscriptions("<>"),o=this.subMap.getSubscriptions(t);this.logEvents&&t!==connect.EventType.LOG&&t!==connect.EventType.MASTER_RESPONSE&&t!==connect.EventType.API_METRIC&&t!==connect.EventType.SERVER_BOUND_INTERNAL_LOG&&connect.getLog().trace("Publishing event: %s",t).sendInternalLogToServer(),e.concat(o).forEach(function(e){try{e.f(n||null,t,r)}catch(e){connect.getLog().error("'%s' event handler failed.",t).withException(e).sendInternalLogToServer()}})},u.prototype.bridge=function(){var n=this;return function(e,t){n.trigger(t,e)}},u.prototype.unsubscribeAll=function(){this.subMap.getAllSubscriptions().forEach(function(e){e.unsubscribe()})},connect.EventBus=u,connect.EventFactory=e,connect.EventType=t,connect.AgentEvents=r,connect.ConnnectionEvents=s,connect.ContactEvents=i,connect.WebSocketEvents=o,connect.MasterTopics=n}(),function(){connect=this.connect||{},this.connect=connect,this.lily=connect;function r(){}r.prototype.send=function(e){throw new connect.NotImplementedError},r.prototype.onMessage=function(e){throw new connect.NotImplementedError};function o(){r.call(this)}((o.prototype=Object.create(r.prototype)).constructor=o).prototype.onMessage=function(e){},o.prototype.send=function(e){};function e(e,t){r.call(this),this.window=e,this.domain=t||"*"}((e.prototype=Object.create(r.prototype)).constructor=e).prototype.send=function(e){this.window.postMessage(e,this.domain)},e.prototype.onMessage=function(e){this.window.addEventListener("message",e)};function i(e,t,n){r.call(this),this.input=e,this.output=t,this.domain=n||"*"}((i.prototype=Object.create(r.prototype)).constructor=i).prototype.send=function(e){this.output.postMessage(e,this.domain)},i.prototype.onMessage=function(e){this.input.addEventListener("message",e)};function t(e){r.call(this),this.port=e,this.id=connect.randomId()}((t.prototype=Object.create(r.prototype)).constructor=t).prototype.send=function(e){this.port.postMessage(e)},t.prototype.onMessage=function(e){this.port.addEventListener("message",e)},t.prototype.getId=function(){return this.id};function n(e){r.call(this),this.streamMap=e?connect.index(e,function(e){return e.getId()}):{},this.messageListeners=[]}((n.prototype=Object.create(r.prototype)).constructor=n).prototype.send=function(t){this.getStreams().forEach(function(e){try{e.send(t)}catch(e){}})},n.prototype.onMessage=function(t){this.messageListeners.push(t),this.getStreams().forEach(function(e){e.onMessage(t)})},n.prototype.addStream=function(t){this.streamMap[t.getId()]=t,this.messageListeners.forEach(function(e){t.onMessage(e)})},n.prototype.removeStream=function(e){delete this.streamMap[e.getId()]},n.prototype.getStreams=function(e){return connect.values(this.streamMap)},n.prototype.getStreamForPort=function(t){return connect.find(this.getStreams(),function(e){return e.port===t})};function s(e,t,n){this.name=e,this.upstream=t||new o,this.downstream=n||new o,this.downstreamBus=new connect.EventBus,this.upstreamBus=new connect.EventBus,this.upstream.onMessage(connect.hitch(this,this._dispatchEvent,this.upstreamBus)),this.downstream.onMessage(connect.hitch(this,this._dispatchEvent,this.downstreamBus))}s.prototype.onUpstream=function(e,t){return connect.assertNotNull(e,"eventName"),connect.assertNotNull(t,"f"),connect.assertTrue(connect.isFunction(t),"f must be a function"),this.upstreamBus.subscribe(e,t)},s.prototype.onAllUpstream=function(e){return connect.assertNotNull(e,"f"),connect.assertTrue(connect.isFunction(e),"f must be a function"),this.upstreamBus.subscribeAll(e)},s.prototype.onDownstream=function(e,t){return connect.assertNotNull(e,"eventName"),connect.assertNotNull(t,"f"),connect.assertTrue(connect.isFunction(t),"f must be a function"),this.downstreamBus.subscribe(e,t)},s.prototype.onAllDownstream=function(e){return connect.assertNotNull(e,"f"),connect.assertTrue(connect.isFunction(e),"f must be a function"),this.downstreamBus.subscribeAll(e)},s.prototype.sendUpstream=function(e,t){connect.assertNotNull(e,"eventName"),this.upstream.send({event:e,data:t})},s.prototype.sendDownstream=function(e,t){connect.assertNotNull(e,"eventName"),this.downstream.send({event:e,data:t})},s.prototype._dispatchEvent=function(e,t){t=t.data;t.event&&e.trigger(t.event,t.data)},s.prototype.passUpstream=function(){var n=this;return function(e,t){n.upstream.send({event:t,data:e})}},s.prototype.passDownstream=function(){var n=this;return function(e,t){n.downstream.send({event:t,data:e})}},s.prototype.shutdown=function(){this.upstreamBus.unsubscribeAll(),this.downstreamBus.unsubscribeAll()};function c(e,t,n,r){s.call(this,e,new i(t,n.contentWindow,r||"*"),null)}(c.prototype=Object.create(s.prototype)).constructor=c,connect.Stream=r,connect.NullStream=o,connect.WindowStream=e,connect.WindowIOStream=i,connect.PortStream=t,connect.StreamMultiplexer=n,connect.Conduit=s,connect.IFrameConduit=c}(),function(){connect=this.connect||{},this.connect=connect,this.lily=connect,connect.ClientMethods=connect.makeEnum(["getAgentSnapshot","putAgentState","getAgentStates","getDialableCountryCodes","getRoutingProfileQueues","getAgentPermissions","getAgentConfiguration","updateAgentConfiguration","acceptContact","createOutboundContact","createTaskContact","clearContact","completeContact","destroyContact","rejectContact","notifyContactIssue","updateContactAttributes","createAdditionalConnection","destroyConnection","holdConnection","resumeConnection","toggleActiveConnections","conferenceConnections","sendClientLogs","sendDigits","sendSoftphoneCallReport","sendSoftphoneCallMetrics","getEndpoints","getNewAuthToken","createTransport"]),connect.AgentAppClientMethods={GET_SPEAKER_ID:"AgentAppService.Lcms.getContact",ENROLL_SPEAKER_IN_VOICEID:"AgentAppService.VoiceId.enrollBySession",EVALUATE_SPEAKER_WITH_VOICEID:"AgentAppService.VoiceId.evaluateSession",GET_SPEAKER_STATUS:"AgentAppService.VoiceId.describeSpeaker",OPT_OUT_VOICEID_SPEAKER:"AgentAppService.VoiceId.optOutSpeaker",DESCRIBE_VOICEID_SESSION:"AgentAppService.VoiceId.describeSession",UPDATE_VOICEID_SESSION:"AgentAppService.VoiceId.updateSession",START_VOICEID_SESSION:"AgentAppService.Nasa.startVoiceIdSession"},connect.MasterMethods=connect.makeEnum(["becomeMaster","checkMaster"]);function r(){}r.EMPTY_CALLBACKS={success:function(){},failure:function(){}},r.prototype.call=function(e,t,n){connect.assertNotNull(e,"method");t=t||{},n=n||r.EMPTY_CALLBACKS;this._callImpl(e,t,n)},r.prototype._callImpl=function(e,t,n){throw new connect.NotImplementedError};function e(){r.call(this)}((e.prototype=Object.create(r.prototype)).constructor=e).prototype._callImpl=function(e,t,n){n&&n.failure&&(e=connect.sprintf("No such method exists on NULL client: %s",e),n.failure(new connect.ValueError(e),{message:e}))};function t(e,t,n){r.call(this),this.conduit=e,this.requestEvent=t,this.responseEvent=n,this._requestIdCallbacksMap={},this.conduit.onUpstream(n,connect.hitch(this,this._handleResponse))}((t.prototype=Object.create(r.prototype)).constructor=t).prototype._callImpl=function(e,t,n){t=connect.EventFactory.createRequest(this.requestEvent,e,t);this._requestIdCallbacksMap[t.requestId]=n,this.conduit.sendUpstream(t.event,t)},t.prototype._getCallbacksForRequest=function(e){var t=this._requestIdCallbacksMap[e]||null;return null!=t&&delete this._requestIdCallbacksMap[e],t},t.prototype._handleResponse=function(e){var t=this._getCallbacksForRequest(e.requestId);null!=t&&(e.err&&t.failure?t.failure(e.err,e.data):t.success&&t.success(e.data))};function n(e){t.call(this,e,connect.EventType.API_REQUEST,connect.EventType.API_RESPONSE)}(n.prototype=Object.create(t.prototype)).constructor=n;function o(e){t.call(this,e,connect.EventType.MASTER_REQUEST,connect.EventType.MASTER_RESPONSE)}(o.prototype=Object.create(t.prototype)).constructor=o;function i(e,t,n){connect.assertNotNull(e,"authCookieName"),connect.assertNotNull(t,"authToken"),connect.assertNotNull(n,"endpoint"),r.call(this),this.endpointUrl=connect.getUrlWithProtocol(n),this.authToken=t,this.authCookieName=e}((i.prototype=Object.create(r.prototype)).constructor=i).prototype._callImpl=function(e,t,n){var r={};r[this.authCookieName]=this.authToken;r={method:"post",body:JSON.stringify(t||{}),headers:{Accept:"application/json","Content-Type":"application/json","X-Amz-target":e,"X-Amz-Bearer":JSON.stringify(r)}};connect.fetch(this.endpointUrl,r).then(function(e){n.success(e)}).catch(function(e){n.failure(e)})};function s(e,t,n){connect.assertNotNull(e,"authToken"),connect.assertNotNull(t,"region"),r.call(this),AWS.config.credentials=new AWS.Credentials({}),AWS.config.region=t,this.authToken=e,e=connect.getBaseUrl(),e=n||(e.includes(".awsapps.com")?e+"/connect/api":e+"/api"),e=new AWS.Endpoint(e),this.client=new AWS.Connect({endpoint:e})}((s.prototype=Object.create(r.prototype)).constructor=s).prototype._callImpl=function(r,e,o){var t=this,i=connect.getLog();connect.contains(this.client,r)?(e=this._translateParams(r,e),i.trace("AWSClient: --\x3e Calling operation '%s'",r).sendInternalLogToServer(),this.client[r](e).on("build",function(e){e.httpRequest.headers["X-Amz-Bearer"]=t.authToken}).send(function(e,t){try{var n;e?(e.code===connect.CTIExceptions.UNAUTHORIZED_EXCEPTION?o.authFailure():!o.accessDenied||e.code!==connect.CTIExceptions.ACCESS_DENIED_EXCEPTION&&403!==e.statusCode?((n={}).type=e.code,n.message=e.message,n.stack=e.stack?e.stack.split("\n"):[],o.failure(n,t)):o.accessDenied(),i.trace("AWSClient: <-- Operation '%s' failed: %s",r,JSON.stringify(e)).sendInternalLogToServer()):(i.trace("AWSClient: <-- Operation '%s' succeeded.",r).withObject(t).sendInternalLogToServer(),o.success(t))}catch(e){connect.getLog().error("Failed to handle AWS API request for method %s",r).withException(e).sendInternalLogToServer()}})):(e=connect.sprintf("No such method exists on AWS client: %s",r),o.failure(new connect.ValueError(e),{message:e}))},s.prototype._requiresAuthenticationParam=function(e){return e!==connect.ClientMethods.COMPLETE_CONTACT&&e!==connect.ClientMethods.CLEAR_CONTACT&&e!==connect.ClientMethods.REJECT_CONTACT&&e!==connect.ClientMethods.CREATE_TASK_CONTACT},s.prototype._translateParams=function(e,t){switch(e){case connect.ClientMethods.UPDATE_AGENT_CONFIGURATION:t.configuration=this._translateAgentConfiguration(t.configuration);break;case connect.ClientMethods.SEND_SOFTPHONE_CALL_METRICS:t.softphoneStreamStatistics=this._translateSoftphoneStreamStatistics(t.softphoneStreamStatistics);break;case connect.ClientMethods.SEND_SOFTPHONE_CALL_REPORT:t.report=this._translateSoftphoneCallReport(t.report)}return this._requiresAuthenticationParam(e)&&(t.authentication={authToken:this.authToken}),t},s.prototype._translateAgentConfiguration=function(e){return{name:e.name,softphoneEnabled:e.softphoneEnabled,softphoneAutoAccept:e.softphoneAutoAccept,extension:e.extension,routingProfile:this._translateRoutingProfile(e.routingProfile),agentPreferences:e.agentPreferences}},s.prototype._translateRoutingProfile=function(e){return{name:e.name,routingProfileARN:e.routingProfileARN,defaultOutboundQueue:this._translateQueue(e.defaultOutboundQueue)}},s.prototype._translateQueue=function(e){return{queueARN:e.queueARN,name:e.name}},s.prototype._translateSoftphoneStreamStatistics=function(e){return e.forEach(function(e){"packetsCount"in e&&(e.packetCount=e.packetsCount,delete e.packetsCount)}),e},s.prototype._translateSoftphoneCallReport=function(e){return"handshakingTimeMillis"in e&&(e.handshakeTimeMillis=e.handshakingTimeMillis,delete e.handshakingTimeMillis),"preTalkingTimeMillis"in e&&(e.preTalkTimeMillis=e.preTalkingTimeMillis,delete e.preTalkingTimeMillis),"handshakingFailure"in e&&(e.handshakeFailure=e.handshakingFailure,delete e.handshakingFailure),"talkingTimeMillis"in e&&(e.talkTimeMillis=e.talkingTimeMillis,delete e.talkingTimeMillis),e.softphoneStreamStatistics=this._translateSoftphoneStreamStatistics(e.softphoneStreamStatistics),e},connect.ClientBase=r,connect.NullClient=e,connect.UpstreamConduitClient=n,connect.UpstreamConduitMasterClient=o,connect.AWSClient=s,connect.AgentAppClient=i}(),function(){connect=this.connect||{},this.connect=connect,this.lily=connect;function r(e,t){connect.assertNotNull(e,"fromState"),connect.assertNotNull(t,"toState"),this.fromState=e,this.toState=t}r.prototype.getAssociations=function(e){throw connect.NotImplementedError()},r.prototype.getFromState=function(){return this.fromState},r.prototype.getToState=function(){return this.toState};function e(e,t,n){connect.assertNotNull(e,"fromState"),connect.assertNotNull(t,"toState"),connect.assertNotNull(n,"associations"),r.call(this,e,t),this.associations=n}((e.prototype=Object.create(r.prototype)).constructor=e).prototype.getAssociations=function(e){return this.associations};function i(e,t,n){connect.assertNotNull(e,"fromState"),connect.assertNotNull(t,"toState"),connect.assertNotNull(n,"closure"),connect.assertTrue(connect.isFunction(n),"closure must be a function"),r.call(this,e,t),this.closure=n}((i.prototype=Object.create(r.prototype)).constructor=i).prototype.getAssociations=function(e){return this.closure(e,this.getFromState(),this.getToState())};function s(){this.fromMap={}}s.ANY="<>",s.prototype.assoc=function(t,n,r){var o=this;if(!t)throw new Error("fromStateObj is not defined.");if(!n)throw new Error("toStateObj is not defined.");if(!r)throw new Error("assocObj is not defined.");return t instanceof Array?t.forEach(function(e){o.assoc(e,n,r)}):n instanceof Array?n.forEach(function(e){o.assoc(t,e,r)}):"function"==typeof r?this._addAssociation(new i(t,n,r)):r instanceof Array?this._addAssociation(new e(t,n,r)):this._addAssociation(new e(t,n,[r])),this},s.prototype.getAssociations=function(e,t,n){connect.assertNotNull(t,"fromState"),connect.assertNotNull(n,"toState");var r=[],o=this.fromMap[s.ANY]||{},i=this.fromMap[t]||{};return r=(r=r.concat(this._getAssociationsFromMap(o,e,t,n))).concat(this._getAssociationsFromMap(i,e,t,n))},s.prototype._addAssociation=function(e){var t=this.fromMap[e.getFromState()];((t=t||(this.fromMap[e.getFromState()]={}))[e.getToState()]||(t[e.getToState()]=[])).push(e)},s.prototype._getAssociationsFromMap=function(e,n,t,r){return(e[s.ANY]||[]).concat(e[r]||[]).reduce(function(e,t){return e.concat(t.getAssociations(n))},[])},connect.EventGraph=s}(),function(){var n=this;connect=n.connect||{},n.connect=connect,n.lily=connect,connect.AgentStateType=connect.makeEnum(["init","routable","not_routable","offline"]),connect.AgentStatusType=connect.AgentStateType,connect.AgentAvailStates=connect.makeEnum(["Init","Busy","AfterCallWork","CallingCustomer","Dialing","Joining","PendingAvailable","PendingBusy"]),connect.AgentErrorStates=connect.makeEnum(["Error","AgentHungUp","BadAddressAgent","BadAddressCustomer","Default","FailedConnectAgent","FailedConnectCustomer","LineEngagedAgent","LineEngagedCustomer","MissedCallAgent","MissedCallCustomer","MultipleCcpWindows","RealtimeCommunicationError"]),connect.EndpointType=connect.makeEnum(["phone_number","agent","queue"]),connect.AddressType=connect.EndpointType,connect.ConnectionType=connect.makeEnum(["agent","inbound","outbound","monitoring"]),connect.ConnectionStateType=connect.makeEnum(["init","connecting","connected","hold","disconnected"]),connect.ConnectionStatusType=connect.ConnectionStateType,connect.CONNECTION_ACTIVE_STATES=connect.set([connect.ConnectionStateType.CONNECTING,connect.ConnectionStateType.CONNECTED,connect.ConnectionStateType.HOLD]),connect.ContactStateType=connect.makeEnum(["init","incoming","pending","connecting","connected","missed","error","ended"]),connect.ContactStatusType=connect.ContactStateType,connect.CONTACT_ACTIVE_STATES=connect.makeEnum(["incoming","pending","connecting","connected"]),connect.ContactType=connect.makeEnum(["voice","queue_callback","chat","task"]),connect.ContactInitiationMethod=connect.makeEnum(["inbound","outbound","transfer","queue_transfer","callback","api"]),connect.ChannelType=connect.makeEnum(["VOICE","CHAT","TASK"]),connect.MediaType=connect.makeEnum(["softphone","chat","task"]),connect.SoftphoneCallType=connect.makeEnum(["audio_video","video_only","audio_only","none"]),connect.SoftphoneErrorTypes=connect.makeEnum(["unsupported_browser","microphone_not_shared","signalling_handshake_failure","signalling_connection_failure","ice_collection_timeout","user_busy_error","webrtc_error","realtime_communication_error","other"]),connect.VoiceIdErrorTypes=connect.makeEnum(["no_speaker_id_found","get_speaker_id_failed","get_speaker_status_failed","opt_out_speaker_failed","start_session_failed","evaluate_speaker_failed","describe_session_failed","enroll_speaker_failed","update_speaker_id_failed","not_supported_on_conference_calls","timeout"]),connect.CTIExceptions=connect.makeEnum(["AccessDeniedException","InvalidStateException","BadEndpointException","InvalidAgentARNException","InvalidConfigurationException","InvalidContactTypeException","PaginationException","RefreshTokenExpiredException","SendDataFailedException","UnauthorizedException","QuotaExceededException"]),connect.VoiceIdStreamingStatus=connect.makeEnum(["ONGOING","ENDED"]),connect.VoiceIdAuthenticationDecision=connect.makeEnum(["ACCEPT","REJECT","NOT_ENOUGH_SPEECH","SPEAKER_NOT_ENROLLED","SPEAKER_OPTED_OUT","SPEAKER_ID_NOT_PROVIDED"]),connect.ContactFlowAuthenticationDecision=connect.makeEnum(["Authenticated","NotAuthenticated","Inconclusive","NotEnrolled","OptedOut","Error"]),connect.VoiceIdEnrollmentRequestStatus=connect.makeEnum(["NOT_ENOUGH_SPEECH","IN_PROGRESS","COMPLETED","FAILED"]);function e(){if(!connect.agent.initialized)throw new connect.StateError("The agent is not yet initialized!")}e.prototype._getData=function(){return connect.core.getAgentDataProvider().getAgentData()},e.prototype._createContactAPI=function(e){return new connect.Contact(e.contactId)},e.prototype.onContactPending=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.CONTACT_PENDING,e)},e.prototype.onRefresh=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.REFRESH,e)},e.prototype.onRoutable=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.ROUTABLE,e)},e.prototype.onNotRoutable=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.NOT_ROUTABLE,e)},e.prototype.onOffline=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.OFFLINE,e)},e.prototype.onError=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.ERROR,e)},e.prototype.onSoftphoneError=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.SOFTPHONE_ERROR,e)},e.prototype.onWebSocketConnectionLost=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.WEBSOCKET_CONNECTION_LOST,e)},e.prototype.onWebSocketConnectionGained=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.WEBSOCKET_CONNECTION_GAINED,e)},e.prototype.onAfterCallWork=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.ACW,e)},e.prototype.onStateChange=function(e){connect.core.getEventBus().subscribe(connect.AgentEvents.STATE_CHANGE,e)},e.prototype.onMuteToggle=function(e){connect.core.getUpstream().onUpstream(connect.AgentEvents.MUTE_TOGGLE,e)},e.prototype.onLocalMediaStreamCreated=function(e){connect.core.getUpstream().onUpstream(connect.AgentEvents.LOCAL_MEDIA_STREAM_CREATED,e)},e.prototype.mute=function(){connect.core.getUpstream().sendUpstream(connect.EventType.BROADCAST,{event:connect.EventType.MUTE,data:{mute:!0}})},e.prototype.unmute=function(){connect.core.getUpstream().sendUpstream(connect.EventType.BROADCAST,{event:connect.EventType.MUTE,data:{mute:!1}})},e.prototype.getState=function(){return this._getData().snapshot.state},e.prototype.getAvailabilityState=function(){return this._getData().snapshot.agentAvailabilityState},e.prototype.getStatus=e.prototype.getState,e.prototype.getStatusDuration=e.prototype.getStateDuration=function(){return connect.now()-this._getData().snapshot.state.startTimestamp.getTime()+connect.core.getSkew()},e.prototype.getPermissions=function(){return this.getConfiguration().permissions},e.prototype.getContacts=function(t){var n=this;return this._getData().snapshot.contacts.map(function(e){return n._createContactAPI(e)}).filter(function(e){return!t||e.getType()===t})},e.prototype.getConfiguration=function(){return this._getData().configuration},e.prototype.getAgentStates=function(){return this.getConfiguration().agentStates},e.prototype.getRoutingProfile=function(){return this.getConfiguration().routingProfile},e.prototype.getChannelConcurrency=function(e){var t=(t=this.getRoutingProfile().channelConcurrencyMap)||Object.keys(connect.ChannelType).reduce(function(e,t){return"TASK"!==t&&(e[connect.ChannelType[t]]=1),e},{});return e?t[e]||0:t},e.prototype.getName=function(){return this.getConfiguration().name},e.prototype.getExtension=function(){return this.getConfiguration().extension},e.prototype.getDialableCountries=function(){return this.getConfiguration().dialableCountries},e.prototype.isSoftphoneEnabled=function(){return this.getConfiguration().softphoneEnabled},e.prototype.setConfiguration=function(e,t){connect.core.getClient().call(connect.ClientMethods.UPDATE_AGENT_CONFIGURATION,{configuration:connect.assertNotNull(e,"configuration")},{success:function(e){connect.core.getUpstream().sendUpstream(connect.EventType.RELOAD_AGENT_CONFIGURATION),t.success&&t.success(e)},failure:t&&t.failure})},e.prototype.setStatus=e.prototype.setState=function(e,t){connect.core.getClient().call(connect.ClientMethods.PUT_AGENT_STATE,{state:connect.assertNotNull(e,"state")},t)},e.prototype.connect=function(e,t){var n=connect.core.getClient(),e=new connect.Endpoint(e);delete e.endpointId,n.call(connect.ClientMethods.CREATE_OUTBOUND_CONTACT,{endpoint:connect.assertNotNull(e,"endpoint"),queueARN:t&&(t.queueARN||t.queueId)||this.getRoutingProfile().defaultOutboundQueue.queueARN},t&&{success:t.success,failure:t.failure})},e.prototype.getAllQueueARNs=function(){return this.getConfiguration().routingProfile.queues.map(function(e){return e.queueARN})},e.prototype.getAddresses=e.prototype.getEndpoints=function(t,n,e){var r=this,o=connect.core.getClient();connect.assertNotNull(n,"callbacks"),connect.assertNotNull(n.success,"callbacks.success");var i=e||{};i.endpoints=i.endpoints||[],i.maxResults=i.maxResults||connect.DEFAULT_BATCH_SIZE,connect.isArray(t)||(t=[t]),o.call(connect.ClientMethods.GET_ENDPOINTS,{queueARNs:t,nextToken:i.nextToken||null,maxResults:i.maxResults},{success:function(e){e.nextToken?r.getEndpoints(t,n,{nextToken:e.nextToken,maxResults:i.maxResults,endpoints:i.endpoints.concat(e.endpoints)}):(i.endpoints=i.endpoints.concat(e.endpoints),e=i.endpoints.map(function(e){return new connect.Endpoint(e)}),n.success({endpoints:e,addresses:e}))},failure:n.failure})},e.prototype.toSnapshot=function(){return new connect.AgentSnapshot(this._getData())};function t(e){connect.Agent.call(this),this.agentData=e}((t.prototype=Object.create(e.prototype)).constructor=t).prototype._getData=function(){return this.agentData},t.prototype._createContactAPI=function(e){return new connect.ContactSnapshot(e)};function r(e){this.contactId=e}r.prototype._getData=function(){return connect.core.getAgentDataProvider().getContactData(this.getContactId())},r.prototype._createConnectionAPI=function(e){return new(this.getType()===connect.ContactType.CHAT?connect.ChatConnection:this.getType()===connect.ContactType.TASK?connect.TaskConnection:connect.VoiceConnection)(this.contactId,e.connectionId)},r.prototype.getEventName=function(e){return connect.core.getContactEventName(e,this.getContactId())},r.prototype.onRefresh=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.REFRESH),e)},r.prototype.onIncoming=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.INCOMING),e)},r.prototype.onConnecting=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.CONNECTING),e)},r.prototype.onPending=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.PENDING),e)},r.prototype.onAccepted=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.ACCEPTED),e)},r.prototype.onMissed=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.MISSED),e)},r.prototype.onEnded=function(e){var t=connect.core.getEventBus();t.subscribe(this.getEventName(connect.ContactEvents.ENDED),e),t.subscribe(this.getEventName(connect.ContactEvents.DESTROYED),e)},r.prototype.onDestroy=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.DESTROYED),e)},r.prototype.onACW=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.ACW),e)},r.prototype.onConnected=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.CONNECTED),e)},r.prototype.onError=function(e){connect.core.getEventBus().subscribe(this.getEventName(connect.ContactEvents.ERROR),e)},r.prototype.getContactId=function(){return this.contactId},r.prototype.getInitialContactId=r.prototype.getOriginalContactId=function(){return this._getData().initialContactId},r.prototype.getType=function(){return this._getData().type},r.prototype.getContactDuration=function(){return this._getData().contactDuration},r.prototype.getStatus=r.prototype.getState=function(){return this._getData().state},r.prototype.getStatusDuration=r.prototype.getStateDuration=function(){return connect.now()-this._getData().state.timestamp.getTime()+connect.core.getSkew()},r.prototype.getQueue=function(){return this._getData().queue},r.prototype.getQueueTimestamp=function(){return this._getData().queueTimestamp},r.prototype.getConnections=function(){var t=this;return this._getData().connections.map(function(e){return new(t.getType()===connect.ContactType.CHAT?connect.ChatConnection:t.getType()===connect.ContactType.TASK?connect.TaskConnection:connect.VoiceConnection)(t.contactId,e.connectionId)})},r.prototype.getInitialConnection=function(){return connect.find(this.getConnections(),function(e){return e.isInitialConnection()})||null},r.prototype.getActiveInitialConnection=function(){var e=this.getInitialConnection();return null!=e&&e.isActive()?e:null},r.prototype.getThirdPartyConnections=function(){return this.getConnections().filter(function(e){return!e.isInitialConnection()&&e.getType()!==connect.ConnectionType.AGENT})},r.prototype.getSingleActiveThirdPartyConnection=function(){return this.getThirdPartyConnections().filter(function(e){return e.isActive()})[0]||null},r.prototype.getAgentConnection=function(){return connect.find(this.getConnections(),function(e){e=e.getType();return e===connect.ConnectionType.AGENT||e===connect.ConnectionType.MONITORING})},r.prototype.getName=function(){return this._getData().name},r.prototype.getContactMetadata=function(){return this._getData().contactMetadata},r.prototype.getDescription=function(){return this._getData().description},r.prototype.getReferences=function(){return this._getData().references},r.prototype.getAttributes=function(){return this._getData().attributes},r.prototype.getContactFeatures=function(){return this._getData().contactFeatures},r.prototype.isSoftphoneCall=function(){return null!=connect.find(this.getConnections(),function(e){return null!=e.getSoftphoneMediaInfo()})},r.prototype._isInbound=function(){return this._getData().initiationMethod!==connect.ContactInitiationMethod.OUTBOUND},r.prototype.isInbound=function(){var e=this.getInitialConnection();return e.getMediaType()===connect.MediaType.TASK?this._isInbound():!!e&&e.getType()===connect.ConnectionType.INBOUND},r.prototype.isConnected=function(){return this.getStatus().type===connect.ContactStateType.CONNECTED},r.prototype.accept=function(n){var e=connect.core.getClient(),r=this,o=this.getContactId();e.call(connect.ClientMethods.ACCEPT_CONTACT,{contactId:o},{success:function(e){var t=connect.core.getUpstream();t.sendUpstream(connect.EventType.BROADCAST,{event:connect.ContactEvents.ACCEPTED,data:new connect.Contact(o)}),t.sendUpstream(connect.EventType.BROADCAST,{event:connect.core.getContactEventName(connect.ContactEvents.ACCEPTED,r.getContactId()),data:new connect.Contact(o)}),n&&n.success&&n.success(e)},failure:n?n.failure:null})},r.prototype.destroy=function(){connect.getLog().warn("contact.destroy() has been deprecated.")},r.prototype.reject=function(e){connect.core.getClient().call(connect.ClientMethods.REJECT_CONTACT,{contactId:this.getContactId()},e)},r.prototype.complete=function(e){connect.core.getClient().call(connect.ClientMethods.COMPLETE_CONTACT,{contactId:this.getContactId()},e)},r.prototype.clear=function(e){connect.core.getClient().call(connect.ClientMethods.CLEAR_CONTACT,{contactId:this.getContactId()},e)},r.prototype.notifyIssue=function(e,t,n){connect.core.getClient().call(connect.ClientMethods.NOTIFY_CONTACT_ISSUE,{contactId:this.getContactId(),issueCode:e,description:t},n)},r.prototype.addConnection=function(e,t){var n=connect.core.getClient(),e=new connect.Endpoint(e);delete e.endpointId,n.call(connect.ClientMethods.CREATE_ADDITIONAL_CONNECTION,{contactId:this.getContactId(),endpoint:e},t)},r.prototype.toggleActiveConnections=function(e){var t=connect.core.getClient(),n=null,r=connect.find(this.getConnections(),function(e){return e.getStatus().type===connect.ConnectionStateType.HOLD});null!=r?n=r.getConnectionId():0<(r=this.getConnections().filter(function(e){return e.isActive()})).length&&(n=r[0].getConnectionId()),t.call(connect.ClientMethods.TOGGLE_ACTIVE_CONNECTIONS,{contactId:this.getContactId(),connectionId:n},e)},r.prototype.sendSoftphoneMetrics=function(e,t){connect.core.getClient().call(connect.ClientMethods.SEND_SOFTPHONE_CALL_METRICS,{contactId:this.getContactId(),ccpVersion:n.ccpVersion,softphoneStreamStatistics:e},t),connect.publishSoftphoneStats({contactId:this.getContactId(),ccpVersion:n.ccpVersion,stats:e})},r.prototype.sendSoftphoneReport=function(e,t){connect.core.getClient().call(connect.ClientMethods.SEND_SOFTPHONE_CALL_REPORT,{contactId:this.getContactId(),ccpVersion:n.ccpVersion,report:e},t),connect.publishSoftphoneReport({contactId:this.getContactId(),ccpVersion:n.ccpVersion,report:e})},r.prototype.conferenceConnections=function(e){connect.core.getClient().call(connect.ClientMethods.CONFERENCE_CONNECTIONS,{contactId:this.getContactId()},e)},r.prototype.toSnapshot=function(){return new connect.ContactSnapshot(this._getData())};function o(e){connect.Contact.call(this,e.contactId),this.contactData=e}((o.prototype=Object.create(r.prototype)).constructor=o).prototype._getData=function(){return this.contactData},o.prototype._createConnectionAPI=function(e){return new connect.ConnectionSnapshot(e)};function i(e,t){this.contactId=e,this.connectionId=t,this._initMediaController()}i.prototype._getData=function(){return connect.core.getAgentDataProvider().getConnectionData(this.getContactId(),this.getConnectionId())},i.prototype.getContactId=function(){return this.contactId},i.prototype.getConnectionId=function(){return this.connectionId},i.prototype.getAddress=i.prototype.getEndpoint=function(){return new connect.Endpoint(this._getData().endpoint)},i.prototype.getStatus=i.prototype.getState=function(){return this._getData().state},i.prototype.getStatusDuration=i.prototype.getStateDuration=function(){return connect.now()-this._getData().state.timestamp.getTime()+connect.core.getSkew()},i.prototype.getType=function(){return this._getData().type},i.prototype.isInitialConnection=function(){return this._getData().initial},i.prototype.isActive=function(){return connect.contains(connect.CONNECTION_ACTIVE_STATES,this.getStatus().type)},i.prototype.isConnected=function(){return this.getStatus().type===connect.ConnectionStateType.CONNECTED},i.prototype.isConnecting=function(){return this.getStatus().type===connect.ConnectionStateType.CONNECTING},i.prototype.isOnHold=function(){return this.getStatus().type===connect.ConnectionStateType.HOLD},i.prototype.getSoftphoneMediaInfo=function(){return this._getData().softphoneMediaInfo},i.prototype.getMonitorInfo=function(){return this._getData().monitoringInfo},i.prototype.destroy=function(e){connect.core.getClient().call(connect.ClientMethods.DESTROY_CONNECTION,{contactId:this.getContactId(),connectionId:this.getConnectionId()},e)},i.prototype.sendDigits=function(e,t){connect.core.getClient().call(connect.ClientMethods.SEND_DIGITS,{contactId:this.getContactId(),connectionId:this.getConnectionId(),digits:e},t)},i.prototype.hold=function(e){connect.core.getClient().call(connect.ClientMethods.HOLD_CONNECTION,{contactId:this.getContactId(),connectionId:this.getConnectionId()},e)},i.prototype.resume=function(e){connect.core.getClient().call(connect.ClientMethods.RESUME_CONNECTION,{contactId:this.getContactId(),connectionId:this.getConnectionId()},e)},i.prototype.toSnapshot=function(){return new connect.ConnectionSnapshot(this._getData())},i.prototype._initMediaController=function(){this.getMediaInfo()&&connect.core.mediaFactory.get(this).catch(function(){})},i.prototype._isAgentConnectionType=function(){var e=this.getType();return e===connect.ConnectionType.AGENT||e===connect.ConnectionType.MONITORING},i.prototype._isAgentConnectionType=function(){var e=this.getType();return e===connect.ConnectionType.AGENT||e===connect.ConnectionType.MONITORING};function s(e){this.contactId=e}s.prototype.getSpeakerId=function(){var e=this;e.checkConferenceCall();var t=connect.core.getClient();return new Promise(function(n,r){t.call(connect.AgentAppClientMethods.GET_SPEAKER_ID,{contactId:e.contactId,instanceId:connect.core.getAgentDataProvider().getInstanceId(),awsAccountId:connect.core.getAgentDataProvider().getAWSAccountId()},{success:function(e){var t;e.contactData.customerId?(t={speakerId:e.contactData.customerId},n(t)):(t=connect.VoiceIdError(connect.VoiceIdErrorTypes.NO_SPEAKER_ID_FOUND,"No speakerId assotiated with this call",err),r(t))},failure:function(e){connect.getLog().error("Get SpeakerId failed").withObject({err:e});e=connect.VoiceIdError(connect.VoiceIdErrorTypes.GET_SPEAKER_ID_FAILED,"Get SpeakerId failed",e);r(e)}})})},s.prototype.getSpeakerStatus=function(){var e=this;e.checkConferenceCall();var r=connect.core.getClient();return new Promise(function(t,n){e.getSpeakerId().then(function(e){r.call(connect.AgentAppClientMethods.GET_SPEAKER_STATUS,{SpeakerId:connect.assertNotNull(e.speakerId,"speakerId"),DomainId:"ConnectDefaultDomainId"},{success:function(e){t(e)},failure:function(e){connect.getLog().error("getSpeakerStatus failed").withObject({err:e});e=connect.VoiceIdError(connect.VoiceIdErrorTypes.GET_SPEAKER_STATUS_FAILED,"Get SpeakerStatus failed",e);n(e)}})}).catch(function(e){n(e)})})},s.prototype.optOutSpeaker=function(){var e=this;e.checkConferenceCall();var r=connect.core.getClient();return new Promise(function(t,n){e.getSpeakerId().then(function(e){r.call(connect.AgentAppClientMethods.OPT_OUT_VOICEID_SPEAKER,{SpeakerId:connect.assertNotNull(e.speakerId,"speakerId"),DomainId:"ConnectDefaultDomainId"},{success:function(e){connect.getLog().info("optOutSpeaker succeeded"),t(e)},failure:function(e){connect.getLog().error("optOutSpeaker failed").withObject({err:e});e=connect.VoiceIdError(connect.VoiceIdErrorTypes.OPT_OUT_SPEAKER_FAILED,"optOutSpeaker failed.",e);n(e)}})}).catch(function(e){n(e)})})},s.prototype.startSession=function(){var e=this;e.checkConferenceCall();var r=connect.core.getClient();return new Promise(function(t,n){r.call(connect.AgentAppClientMethods.START_VOICEID_SESSION,{contactId:e.contactId,instanceId:connect.core.getAgentDataProvider().getInstanceId(),customerAccountId:connect.core.getAgentDataProvider().getAWSAccountId(),clientToken:AWS.util.uuid.v4()},{success:function(e){e.sessionId?t(e):n(Error("No contact id is returned from start session api."))},failure:function(e){connect.getLog().error("startVoiceIdSession failed").withObject({err:e});e=connect.VoiceIdError(connect.VoiceIdErrorTypes.START_SESSION_FAILED,"startVoiceIdSession failed",e);n(e)}})})},s.prototype.evaluateSpeaker=function(e){var t=this;t.checkConferenceCall();var i=connect.core.getClient(),s=connect.core.getAgentDataProvider().getContactData(this.contactId),c=120;return new Promise(function(n,r){function o(){i.call(connect.AgentAppClientMethods.EVALUATE_SPEAKER_WITH_VOICEID,{SessionNameOrId:s.initialContactId||this.contactId},{success:function(e){if(1!=c--)if(e.StreamingStatus===connect.VoiceIdStreamingStatus.ENDED&&e.AuthenticationResult.Decision===connect.VoiceIdAuthenticationDecision.NOT_ENOUGH_SPEECH)e.AuthenticationResult.Decision=connect.ContactFlowAuthenticationDecision.INCONCLUSIVE,n(e);else if(e.AuthenticationResult.Decision!==connect.VoiceIdAuthenticationDecision.NOT_ENOUGH_SPEECH){switch(e.AuthenticationResult.Decision){case connect.VoiceIdAuthenticationDecision.ACCEPT:e.AuthenticationResult.Decision=connect.ContactFlowAuthenticationDecision.AUTHENTICATED;break;case connect.VoiceIdAuthenticationDecision.REJECT:e.AuthenticationResult.Decision=connect.ContactFlowAuthenticationDecision.NOT_AUTHENTICATED;break;case connect.VoiceIdAuthenticationDecision.SPEAKER_OPTED_OUT:e.AuthenticationResult.Decision=connect.ContactFlowAuthenticationDecision.OPT_OUT;break;case connect.VoiceIdAuthenticationDecision.SPEAKER_NOT_ENROLLED:e.AuthenticationResult.Decision=connect.ContactFlowAuthenticationDecision.NOT_ENROLLED;break;default:e.AuthenticationResult.Decision=connect.ContactFlowAuthenticationDecision.ERROR}n(e)}else setTimeout(function(){o()},1e3);else{connect.getLog().error("evaluateSpeaker timeout");var t=connect.VoiceIdError(connect.VoiceIdErrorTypes.TIMEOUT,"evaluateSpeaker timeout");r(t)}},failure:function(e){connect.getLog().error("evaluateSpeaker failed").withObject({err:e});e=connect.VoiceIdError(connect.VoiceIdErrorTypes.EVALUATE_SPEAKER_FAILED,"evaluateSpeaker failed",e);r(e)}})}e?t.startSession().then(function(e){o()}).catch(function(e){r(e)}):o()})},s.prototype.describeSession=function(){var o=this;o.checkConferenceCall();var e=connect.core.getClient(),i=connect.core.getAgentDataProvider().getContactData(this.contactId),s=120;return new Promise(function(n,r){!function t(){e.call(connect.AgentAppClientMethods.DESCRIBE_VOICEID_SESSION,{SessionNameOrId:i.initialContactId||this.contactId},{success:function(e){1!=s--?e.Session.EnrollmentRequestDetails.Status===connect.VoiceIdEnrollmentRequestStatus.COMPLETED?n(e):e.Session.EnrollmentRequestDetails.Status===connect.VoiceIdEnrollmentRequestStatus.IN_PROGRESS?setTimeout(function(){t()},5e3):e.Session.EnrollmentRequestDetails.Status===connect.VoiceIdEnrollmentRequestStatus.NOT_ENOUGH_SPEECH?e.Session.StreamingStatus===connect.VoiceIdStreamingStatus.ENDED?o.startSession().then(function(e){t()}).catch(function(e,t){r(e)}):setTimeout(function(){t()},5e3):r(Error(e.Session.EnrollmentRequestDetails.Status)):(connect.getLog().error("describeSession timeout"),e=connect.VoiceIdError(connect.VoiceIdErrorTypes.TIMEOUT,"describeSession timeout"),r(e))},failure:function(e){connect.getLog().error("describeSession failed").withObject({err:e}),e=connect.VoiceIdError(connect.VoiceIdErrorTypes.DESCRIBE_SESSION_FAILED,"describeSession failed",e),r(e)}})}()})},s.prototype.enrollSpeaker=function(){var r=this;r.checkConferenceCall();var e=connect.core.getClient(),o=connect.core.getAgentDataProvider().getContactData(this.contactId);return new Promise(function(t,n){e.call(connect.AgentAppClientMethods.ENROLL_SPEAKER_IN_VOICEID,{SessionNameOrId:o.initialContactId||this.contactId},{success:function(e){e.Status===connect.VoiceIdEnrollmentRequestStatus.COMPLETED?t(e):r.describeSession().then(function(e){t(e)}).catch(function(e){n(e)})},failure:function(e){connect.getLog().error("enrollSpeaker failed").withObject({err:e});e=connect.VoiceIdError(connect.VoiceIdErrorTypes.ENROLL_SPEAKER_FAILED,"enrollSpeaker failed",e);n(e)}})})},s.prototype.updateSpeakerId=function(e){this.checkConferenceCall();var r=connect.core.getClient(),o=connect.core.getAgentDataProvider().getContactData(this.contactId);return new Promise(function(t,n){r.call(connect.AgentAppClientMethods.UPDATE_VOICEID_SESSION,{SessionNameOrId:o.initialContactId||this.contactId,SpeakerId:connect.assertNotNull(e,"speakerId")},{success:function(e){t(e)},failure:function(e){connect.getLog().error("updateSpeakerId failed").withObject({err:e});e=connect.VoiceIdError(connect.VoiceIdErrorTypes.UPDATE_SPEAKER_ID_FAILED,"updateSpeakerId failed",e);n(e)}})})},s.prototype.checkConferenceCall=function(){if(2=this._level}},{key:"hasClientLogger",value:function(){return null!==this._clientLogger}},{key:"getLogger",value:function(e){e=e.prefix||"";return"DEBUG"===this._logsDestination?this.consoleLoggerWrapper:new y(e)}},{key:"updateLoggerConfig",value:function(e){e=e||{};this._level=e.level||f.DEBUG,this._clientLogger=e.logger||null,this._logsDestination="NULL",e.debug&&(this._logsDestination="DEBUG"),e.logger&&(this._logsDestination="CLIENT_LOGGER")}}]),S),m=(h(E,[{key:"debug",value:function(){}},{key:"info",value:function(){}},{key:"warn",value:function(){}},{key:"error",value:function(){}}]),E),y=(function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}(b,m),h(b,[{key:"debug",value:function(){for(var e=arguments.length,t=new Array(e),n=0;n>>0).toString(8);break;case"s":n=String(n),n=o.precision?n.substring(0,o.precision):n;break;case"t":n=String(!!n),n=o.precision?n.substring(0,o.precision):n;break;case"T":n=Object.prototype.toString.call(n).slice(8,-1).toLowerCase(),n=o.precision?n.substring(0,o.precision):n;break;case"u":n=parseInt(n,10)>>>0;break;case"v":n=n.valueOf(),n=o.precision?n.substring(0,o.precision):n;break;case"x":n=(parseInt(n,10)>>>0).toString(16);break;case"X":n=(parseInt(n,10)>>>0).toString(16).toUpperCase()}d.json.test(o.type)?p+=n:(!d.number.test(o.type)||c&&!o.sign?a="":(a=c?"+":"-",n=n.toString().replace(d.sign,"")),i=o.pad_char?"0"===o.pad_char?"0":o.pad_char.charAt(1):" ",s=o.width-(a+n).length,s=o.width&&0t.packetsLost?e.packetsLost-t.packetsLost:0,t=e.packetsCount>t.packetsCount?e.packetsCount-t.packetsCount:0;return new L(e.timestamp,r,t,n,e.audioLevel,e.jbMilliseconds,e.rttMilliseconds)}return new L(e.timestamp,e.packetsLost,e.packetsCount,n,e.audioLevel,e.jbMilliseconds,e.rttMilliseconds)},O=function(e,t){u=r(u),l=r(l),function(e,t,n,r){t.streamStats=[x(n,i),x(r,s)];var o={callStartTime:t.sessionStartTime,callEndTime:t.sessionEndTime,gumTimeMillis:t.gumTimeMillis,initializationTimeMillis:t.initializationTimeMillis,iceCollectionTimeMillis:t.iceCollectionTimeMillis,signallingConnectTimeMillis:t.signallingConnectTimeMillis,handshakingTimeMillis:t.handshakingTimeMillis,preTalkingTimeMillis:t.preTalkingTimeMillis,talkingTimeMillis:t.talkingTimeMillis,cleanupTimeMillis:t.cleanupTimeMillis,iceCollectionFailure:t.iceCollectionFailure,signallingConnectionFailure:t.signallingConnectionFailure,handshakingFailure:t.handshakingFailure,gumOtherFailure:t.gumOtherFailure,gumTimeoutFailure:t.gumTimeoutFailure,createOfferFailure:t.createOfferFailure,setLocalDescriptionFailure:t.setLocalDescriptionFailure,userBusyFailure:t.userBusyFailure,invalidRemoteSDPFailure:t.invalidRemoteSDPFailure,noRemoteIceCandidateFailure:t.noRemoteIceCandidateFailure,setRemoteDescriptionFailure:t.setRemoteDescriptionFailure,softphoneStreamStatistics:t.streamStats};e.sendSoftphoneReport(o,{success:function(){p.info("sendSoftphoneReport success"+JSON.stringify(o)).sendInternalLogToServer()},failure:function(e){p.error("sendSoftphoneReport failed.").withObject(e).sendInternalLogToServer()}})}(e,t,x(c,i),x(a,s)),n(e)},L=function(e,t,n,r,o,i,s){this.softphoneStreamType=r,this.timestamp=e,this.packetsLost=t,this.packetsCount=n,this.audioLevel=o,this.jitterBufferMillis=i,this.roundTripTimeMillis=s},x=function(e,t){return new L((e=e||{}).timestamp,e.packetsLost,e.packetsCount,t,e.audioLevel)},P=function(e){this._originalLogger=e;var r=this;this._tee=function(e,n){return function(){var e=Array.prototype.slice.call(arguments[0]),t="";return e.forEach(function(){t+=" %s"}),n.apply(r._originalLogger,[connect.LogComponent.SOFTPHONE,t].concat(e))}}};P.prototype.debug=function(){return this._tee(1,this._originalLogger.debug)(arguments)},P.prototype.info=function(){return this._tee(2,this._originalLogger.info)(arguments)},P.prototype.log=function(){return this._tee(3,this._originalLogger.log)(arguments)},P.prototype.warn=function(){return this._tee(4,this._originalLogger.warn)(arguments)},P.prototype.error=function(){return this._tee(5,this._originalLogger.error)(arguments)},connect.SoftphoneManager=function(e){var i;p=new P(connect.getLog()),connect.RtcPeerConnectionFactory&&(i=new connect.RtcPeerConnectionFactory(p,connect.core.getWebSocketManager(),f,connect.hitch(this,t,{transportType:"softphone",softphoneClientId:f}),connect.hitch(this,C))),A()||C(h.UNSUPPORTED_BROWSER,"Connect does not support this browser. Some functionality may not work. ","");S({success:function(e){connect.isFirefoxBrowser()&&connect.core.setSoftphoneUserMediaStream(e)},failure:function(e){C(e,"Your microphone is not enabled in your browser. ","")}});m(),this.ringtoneEngine=null;var s="true"===e.cleanMultipleSessions,c={},a={};this.getSession=function(e){return c[e]};function u(n){var r;c.hasOwnProperty(n)&&(r=c[n],new Promise(function(e,t){delete c[n],delete a[n],r.hangup()}).catch(function(e){lily.getLog().warn("Clean up the session locally "+n,e.message).sendInternalLogToServer()}))}function n(n,r){var e,t,o;!c[r]||(t=n).getStatus().type!==connect.ContactStatusType.ENDED&&t.getStatus().type!==connect.ContactStatusType.ERROR&&t.getStatus().type!==connect.ContactStatusType.MISSED||u(r),!n.isSoftphoneCall()||a[r]||n.getStatus().type!==connect.ContactStatusType.CONNECTING&&n.getStatus().type!==connect.ContactStatusType.INCOMING||(a[r]=!0,p.info("Softphone call detected:","contactId "+n.getContactId(),"agent connectionId "+r).sendInternalLogToServer(),function(e){if(0] * a list of credentials objects or functions that return credentials * objects. If the provider is a function, the function will be - * executed lazily when the provider needs to be checked for valid + * started lazily when the provider needs to be checked for valid * credentials. By default, this object will be set to the * {defaultProviders}. * @see defaultProviders @@ -21172,8 +21203,11 @@ global.connect = connect; global.lily = connect; - // How frequently logs should be collected and reported to shared worker. - var LOG_REPORT_INTERVAL_MILLIS = 5000; + // How frequently softphone logs should be collected and reported to shared worker. + var SOFTPHONE_LOG_REPORT_INTERVAL_MILLIS = 5000; + + // How frequently logs should be collected and sent downstream + var LOGS_REPORT_INTERVAL_MILLIS = 5000; // The default log roll interval (30min) var DEFAULT_LOG_ROLL_INTERVAL = 1800000; @@ -21198,7 +21232,8 @@ var LogComponent = { CCP: "ccp", SOFTPHONE: "softphone", - CHAT: "chat" + CHAT: "chat", + TASK: "task" }; /** @@ -21237,7 +21272,7 @@ */ var isValidLogComponent = function (component) { - return [LogComponent.SOFTPHONE, LogComponent.CCP, LogComponent.CHAT].indexOf(component) !== -1; + return Object.values(LogComponent).indexOf(component) !== -1; }; /** @@ -21248,6 +21283,7 @@ var firstArg = args.shift(); var format; var component; + if (isValidLogComponent(firstArg)) { component = firstArg; format = args.shift(); @@ -21256,6 +21292,7 @@ format = firstArg; component = LogComponent.CCP; } + return { format: format, component: component, @@ -21370,6 +21407,15 @@ return this; }; + /** + * Indicate that this log entry should be sent to the server + * NOTE: This should be used for internal logs only + */ + LogEntry.prototype.sendInternalLogToServer = function () { + connect.getLog()._serverBoundInternalLogs.push(this); + return this; + }; + /** * The logger instance. */ @@ -21377,6 +21423,7 @@ this._logs = []; this._rolledLogs = []; this._logsToPush = []; + this._serverBoundInternalLogs = []; this._echoLevel = LogLevelOrder.INFO; this._logLevel = LogLevelOrder.INFO; this._lineCount = 0; @@ -21449,6 +21496,7 @@ Logger.prototype.addLogEntry = function (logEntry) { this._logs.push(logEntry); + //For now only send softphone logs only. //TODO add CCP logs once we are sure that no sensitive data is being logged. if (LogComponent.SOFTPHONE === logEntry.component) { @@ -21466,6 +21514,20 @@ } }; + Logger.prototype.sendInternalLogEntryToServer = function (logEntry) { + this._serverBoundInternalLogs.push(logEntry); + + if (logEntry.level in LogLevelOrder && + LogLevelOrder[logEntry.level] >= this._logLevel) { + + if (LogLevelOrder[logEntry.level] >= this._echoLevel) { + CONSOLE_LOGGER_MAP[logEntry.getLevel()](logEntry.toString()); + } + + logEntry.line = this._lineCount++; + } + }; + /** * Remove all objects from all log entries. */ @@ -21587,7 +21649,7 @@ if (!connect.upstreamLogPushScheduled) { connect.upstreamLogPushScheduled = true; /** Schedule pushing logs frequently to sharedworker upstream, sharedworker will report to LARS*/ - global.setInterval(connect.hitch(this, this.reportMasterLogsUpStream, conduit), LOG_REPORT_INTERVAL_MILLIS); + global.setInterval(connect.hitch(this, this.reportMasterLogsUpStream, conduit), SOFTPHONE_LOG_REPORT_INTERVAL_MILLIS); } }; @@ -21605,9 +21667,33 @@ return this._loggerId; }; + Logger.prototype.scheduleDownstreamClientSideLogsPush = function () { + global.setInterval(connect.hitch(this, this.pushClientSideLogsDownstream), LOGS_REPORT_INTERVAL_MILLIS); + } + + Logger.prototype.pushClientSideLogsDownstream = function () { + var logs = []; + + // We do not send a request if we have less than 50 records so that we minimize the number of + // requests per second. + // 500 is the max we accept on the server. + // We chose 500 because this is the limit imposed by Firehose for a put batch request + if (this._serverBoundInternalLogs.length < 50) { + return; + } else if (this._serverBoundInternalLogs.length > 500) { + logs = this._serverBoundInternalLogs.splice(0, 500); + } else { + logs = this._serverBoundInternalLogs; + this._serverBoundInternalLogs = []; + } + + connect.publishClientSideLogs(logs); + } + var DownstreamConduitLogger = function (conduit) { Logger.call(this); this.conduit = conduit; + global.setInterval(connect.hitch(this, this._pushLogsDownstream), DownstreamConduitLogger.LOG_PUSH_INTERVAL); @@ -21630,10 +21716,17 @@ DownstreamConduitLogger.prototype._pushLogsDownstream = function () { var self = this; + this._logs.forEach(function (log) { self.conduit.sendDownstream(connect.EventType.LOG, log); }); this._logs = []; + + for (var i = 0; i < this._serverBoundInternalLogs.length; i++) { + this.conduit.sendDownstream(connect.EventType.SERVER_BOUND_INTERNAL_LOG, this._serverBoundInternalLogs[i]); + } + + this._serverBoundInternalLogs = []; }; /** Create the singleton logger instance. */ @@ -21862,6 +21955,14 @@ return enumObj; }; + connect.makeGenericNamespacedEnum = function (prefix, values, delimiter) { + var enumObj = connect.makeEnum(values); + connect.keys(enumObj).forEach(function (key) { + enumObj[key] = connect.sprintf("%s"+delimiter+"%s", prefix, enumObj[key]); + }); + return enumObj; + }; + /** * Methods to determine browser type and versions, used for softphone initialization. */ @@ -21985,6 +22086,14 @@ return connect.sprintf("%s//%s:%s", location.protocol, location.hostname, location.port); }; + connect.getUrlWithProtocol = function(url) { + var protocol = global.location.protocol; + if (url.substr(0, protocol.length) !== protocol) { + return connect.sprintf("%s//%s", protocol, url); + } + return url; + } + /** * Determine if the current window is in an iframe. * Courtesy: http://stackoverflow.com/questions/326069/ @@ -22058,6 +22167,21 @@ bus.trigger(connect.EventType.CLIENT_METRIC, metricData); }; + connect.publishSoftphoneStats = function(stats) { + var bus = connect.core.getEventBus(); + bus.trigger(connect.EventType.SOFTPHONE_STATS, stats); + }; + + connect.publishSoftphoneReport = function(report) { + var bus = connect.core.getEventBus(); + bus.trigger(connect.EventType.SOFTPHONE_REPORT, report); + }; + + connect.publishClientSideLogs = function(logs) { + var bus = connect.core.getEventBus(); + bus.trigger(connect.EventType.CLIENT_SIDE_LOGS, logs); + }; + /** * A wrapper around Window.open() for managing single instance popups. */ @@ -22136,11 +22260,11 @@ connect.NotificationManager.prototype.requestPermission = function () { var self = this; if (!("Notification" in global)) { - connect.getLog().warn("This browser doesn't support notifications."); + connect.getLog().warn("This browser doesn't support notifications.").sendInternalLogToServer(); this.permission = NotificationPermission.DENIED; } else if (global.Notification.permission === NotificationPermission.DENIED) { - connect.getLog().warn("The user has requested to not receive notifications."); + connect.getLog().warn("The user has requested to not receive notifications.").sendInternalLogToServer(); this.permission = NotificationPermission.DENIED; } else if (this.permission !== NotificationPermission.GRANTED) { @@ -22161,15 +22285,18 @@ return this._showImpl({ title: title, options: options }); } else if (this.permission === NotificationPermission.DENIED) { - connect.getLog().warn("Unable to show notification.").withObject({ - title: title, - options: options - }); + connect.getLog().warn("Unable to show notification.") + .sendInternalLogToServer() + .withObject({ + title: title, + options: options + }); } else { var params = { title: title, options: options }; connect.getLog().warn("Deferring notification until user decides to allow or deny.") - .withObject(params); + .withObject(params) + .sendInternalLogToServer(); this.queue.push(params); } }; @@ -22223,6 +22350,15 @@ connect.StateError.prototype = Object.create(connect.BaseError.prototype); connect.StateError.prototype.constructor = connect.StateError; + connect.VoiceIdError = function(type, message, err){ + var error = {}; + error.type = type; + error.message = message; + error.stack = Error(message); + error.err = err; + return error; + } + })(); /* @@ -22260,6 +22396,10 @@ 'broadcast', 'api_metric', 'client_metric', + 'softphone_stats', + 'softphone_report', + 'client_side_logs', + 'server_bound_internal_log', 'mute', "iframe_style" ]); @@ -22487,14 +22627,19 @@ var allEventSubs = this.subMap.getSubscriptions(ALL_EVENTS); var eventSubs = this.subMap.getSubscriptions(eventName); - if (this.logEvents && (eventName !== connect.EventType.LOG && eventName !== connect.EventType.MASTER_RESPONSE && eventName !== connect.EventType.API_METRIC)) { - connect.getLog().trace("Publishing event: %s", eventName); + if (this.logEvents && + eventName !== connect.EventType.LOG && + eventName !== connect.EventType.MASTER_RESPONSE && + eventName !== connect.EventType.API_METRIC && + eventName !== connect.EventType.SERVER_BOUND_INTERNAL_LOG + ) { + connect.getLog().trace("Publishing event: %s", eventName).sendInternalLogToServer(); } allEventSubs.concat(eventSubs).forEach(function (sub) { try { sub.f(data || null, eventName, self); } catch (e) { - connect.getLog().error("'%s' event handler failed.", eventName).withException(e); + connect.getLog().error("'%s' event handler failed.", eventName).withException(e).sendInternalLogToServer(); } }); }; @@ -22882,8 +23027,11 @@ 'updateAgentConfiguration', 'acceptContact', 'createOutboundContact', + 'createTaskContact', 'clearContact', 'completeContact', + 'destroyContact', + 'rejectContact', 'notifyContactIssue', 'updateContactAttributes', 'createAdditionalConnection', @@ -22901,6 +23049,20 @@ 'createTransport' ]); + /**--------------------------------------------------------------- + * enum AgentAppClientMethods + */ + connect.AgentAppClientMethods = { + GET_SPEAKER_ID: "AgentAppService.Lcms.getContact", + ENROLL_SPEAKER_IN_VOICEID: "AgentAppService.VoiceId.enrollBySession", + EVALUATE_SPEAKER_WITH_VOICEID: "AgentAppService.VoiceId.evaluateSession", + GET_SPEAKER_STATUS: "AgentAppService.VoiceId.describeSpeaker", + OPT_OUT_VOICEID_SPEAKER: "AgentAppService.VoiceId.optOutSpeaker", + DESCRIBE_VOICEID_SESSION: "AgentAppService.VoiceId.describeSession", + UPDATE_VOICEID_SESSION: "AgentAppService.VoiceId.updateSession", + START_VOICEID_SESSION: "AgentAppService.Nasa.startVoiceIdSession", + }; + /**--------------------------------------------------------------- * enum MasterMethods */ @@ -23008,7 +23170,43 @@ }; UpstreamConduitMasterClient.prototype = Object.create(UpstreamConduitClientBase.prototype); UpstreamConduitMasterClient.prototype.constructor = UpstreamConduitMasterClient; + + /**--------------------------------------------------------------- + * class AgentAppClient extends ClientBase + */ + var AgentAppClient = function(authCookieName, authToken, endpoint) { + connect.assertNotNull(authCookieName, 'authCookieName'); + connect.assertNotNull(authToken, 'authToken'); + connect.assertNotNull(endpoint, 'endpoint'); + ClientBase.call(this); + this.endpointUrl = connect.getUrlWithProtocol(endpoint); + this.authToken = authToken; + this.authCookieName = authCookieName + }; + AgentAppClient.prototype = Object.create(ClientBase.prototype); + AgentAppClient.prototype.constructor = AgentAppClient; + + AgentAppClient.prototype._callImpl = function(method, params, callbacks) { + var self = this; + var bear = {}; + bear[self.authCookieName] = self.authToken; + var options = { + method: 'post', + body: JSON.stringify(params || {}), + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'X-Amz-target': method, + 'X-Amz-Bearer': JSON.stringify(bear) + } + }; + connect.fetch(self.endpointUrl, options).then(function(res){ + callbacks.success(res); + }).catch(function(err){ + callbacks.failure(err); + }) + }; /**--------------------------------------------------------------- * class AWSClient extends ClientBase */ @@ -23042,7 +23240,7 @@ } else { params = this._translateParams(method, params); - log.trace("AWSClient: --> Calling operation '%s'", method); + log.trace("AWSClient: --> Calling operation '%s'", method).sendInternalLogToServer(); this.client[method](params) .on('build', function(request) { @@ -23066,15 +23264,15 @@ callbacks.failure(error, data); } - log.trace("AWSClient: <-- Operation '%s' failed: %s", method, JSON.stringify(err)); + log.trace("AWSClient: <-- Operation '%s' failed: %s", method, JSON.stringify(err)).sendInternalLogToServer(); } else { - log.trace("AWSClient: <-- Operation '%s' succeeded.", method).withObject(data); + log.trace("AWSClient: <-- Operation '%s' succeeded.", method).withObject(data).sendInternalLogToServer(); callbacks.success(data); } } catch (e) { connect.getLog().error("Failed to handle AWS API request for method %s", method) - .withException(e); + .withException(e).sendInternalLogToServer(); } }); } @@ -23083,7 +23281,8 @@ AWSClient.prototype._requiresAuthenticationParam = function (method) { return method !== connect.ClientMethods.COMPLETE_CONTACT && method !== connect.ClientMethods.CLEAR_CONTACT && - method !== connect.ClientMethods.REJECT_CONTACT; + method !== connect.ClientMethods.REJECT_CONTACT && + method !== connect.ClientMethods.CREATE_TASK_CONTACT; }; AWSClient.prototype._translateParams = function(method, params) { @@ -23183,6 +23382,7 @@ connect.UpstreamConduitClient = UpstreamConduitClient; connect.UpstreamConduitMasterClient = UpstreamConduitMasterClient; connect.AWSClient = AWSClient; + connect.AgentAppClient = AgentAppClient; })(); @@ -23474,7 +23674,20 @@ connect.ContactType = connect.makeEnum([ 'voice', 'queue_callback', - 'chat' + 'chat', + 'task' + ]); + + /*---------------------------------------------------------------- + * enum ContactInitiationMethod + */ + connect.ContactInitiationMethod = connect.makeEnum([ + 'inbound', + 'outbound', + 'transfer', + 'queue_transfer', + 'callback', + 'api', ]); /*---------------------------------------------------------------- @@ -23482,7 +23695,8 @@ */ connect.ChannelType = connect.makeEnum([ 'VOICE', - 'CHAT' + 'CHAT', + 'TASK' ]); /*---------------------------------------------------------------- @@ -23490,7 +23704,8 @@ */ connect.MediaType = connect.makeEnum([ 'softphone', - 'chat' + 'chat', + 'task' ]); /*---------------------------------------------------------------- @@ -23518,6 +23733,23 @@ 'other' ]); + /*---------------------------------------------------------------- + * enum for VoiceIdErrorTypes + */ + connect.VoiceIdErrorTypes = connect.makeEnum([ + 'no_speaker_id_found', + 'get_speaker_id_failed', + 'get_speaker_status_failed', + 'opt_out_speaker_failed', + 'start_session_failed', + 'evaluate_speaker_failed', + 'describe_session_failed', + 'enroll_speaker_failed', + 'update_speaker_id_failed', + 'not_supported_on_conference_calls', + 'timeout' + ]); + /*---------------------------------------------------------------- * enum for CTI exceptions */ @@ -23531,8 +23763,51 @@ "PaginationException", "RefreshTokenExpiredException", "SendDataFailedException", - "UnauthorizedException" + "UnauthorizedException", + "QuotaExceededException" + ]); + /*---------------------------------------------------------------- + * enum for VoiceId streaming status + */ + connect.VoiceIdStreamingStatus = connect.makeEnum([ + "ONGOING", + "ENDED" ]); + + /*---------------------------------------------------------------- + * enum for VoiceId authentication decision + */ + connect.VoiceIdAuthenticationDecision = connect.makeEnum([ + "ACCEPT", + "REJECT", + "NOT_ENOUGH_SPEECH", + "SPEAKER_NOT_ENROLLED", + "SPEAKER_OPTED_OUT", + "SPEAKER_ID_NOT_PROVIDED" + ]); + + /*---------------------------------------------------------------- + * enum for contact flow authentication decision + */ + connect.ContactFlowAuthenticationDecision = connect.makeEnum([ + "Authenticated", + "NotAuthenticated", + "Inconclusive", + "NotEnrolled", + "OptedOut", + "Error" + ]); + + /*---------------------------------------------------------------- + * enum for VoiceId EnrollmentRequestStatus status + */ + connect.VoiceIdEnrollmentRequestStatus = connect.makeEnum([ + "NOT_ENOUGH_SPEECH", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ]); + /*---------------------------------------------------------------- * class Agent */ @@ -23674,7 +23949,10 @@ var channelConcurrencyMap = this.getRoutingProfile().channelConcurrencyMap; if (!channelConcurrencyMap) { channelConcurrencyMap = Object.keys(connect.ChannelType).reduce(function (acc, key) { - acc[connect.ChannelType[key]] = 1; + // Exclude TASK from default concurrency. + if (key !== 'TASK') { + acc[connect.ChannelType[key]] = 1; + } return acc; }, {}); } @@ -23830,6 +24108,8 @@ Contact.prototype._createConnectionAPI = function (connectionData) { if (this.getType() === connect.ContactType.CHAT) { return new connect.ChatConnection(this.contactId, connectionData.connectionId); + } else if (this.getType() === connect.ContactType.TASK) { + return new connect.TaskConnection(this.contactId, connectionData.connectionId); } else { return new connect.VoiceConnection(this.contactId, connectionData.connectionId); } @@ -23937,6 +24217,8 @@ return this._getData().connections.map(function (connData) { if (self.getType() === connect.ContactType.CHAT) { return new connect.ChatConnection(self.contactId, connData.connectionId); + } else if (self.getType() === connect.ContactType.TASK) { + return new connect.TaskConnection(self.contactId, connData.connectionId); } else { return new connect.VoiceConnection(self.contactId, connData.connectionId); } @@ -23977,18 +24259,49 @@ }); }; + Contact.prototype.getName = function () { + return this._getData().name; + }; + + Contact.prototype.getContactMetadata = function () { + return this._getData().contactMetadata; + } + + Contact.prototype.getDescription = function () { + return this._getData().description; + }; + + Contact.prototype.getReferences = function () { + return this._getData().references; + }; + Contact.prototype.getAttributes = function () { return this._getData().attributes; }; + Contact.prototype.getContactFeatures = function () { + return this._getData().contactFeatures; + }; + Contact.prototype.isSoftphoneCall = function () { return connect.find(this.getConnections(), function (conn) { return conn.getSoftphoneMediaInfo() != null; }) != null; }; + Contact.prototype._isInbound = function () { + var initiationMethod = this._getData().initiationMethod; + return (initiationMethod === connect.ContactInitiationMethod.OUTBOUND) ? false : true; + } + Contact.prototype.isInbound = function () { var conn = this.getInitialConnection(); + + // We will gradually change checking inbound by relying on contact initiationMethod + if (conn.getMediaType() === connect.MediaType.TASK) { + return this._isInbound(); + } + return conn ? conn.getType() === connect.ConnectionType.INBOUND : false; }; @@ -24023,16 +24336,20 @@ }); }; - Contact.prototype.complete = function (callbacks) { + Contact.prototype.destroy = function () { + connect.getLog().warn("contact.destroy() has been deprecated."); + }; + + Contact.prototype.reject = function (callbacks) { var client = connect.core.getClient(); - client.call(connect.ClientMethods.COMPLETE_CONTACT, { + client.call(connect.ClientMethods.REJECT_CONTACT, { contactId: this.getContactId() }, callbacks); }; - Contact.prototype.clear = function (callbacks) { + Contact.prototype.complete = function (callbacks) { var client = connect.core.getClient(); - client.call(connect.ClientMethods.CLEAR_CONTACT, { + client.call(connect.ClientMethods.COMPLETE_CONTACT, { contactId: this.getContactId() }, callbacks); }; @@ -24098,6 +24415,12 @@ ccpVersion: global.ccpVersion, softphoneStreamStatistics: softphoneStreamStatistics }, callbacks); + + connect.publishSoftphoneStats({ + contactId: this.getContactId(), + ccpVersion: global.ccpVersion, + stats: softphoneStreamStatistics + }); }; Contact.prototype.sendSoftphoneReport = function (report, callbacks) { @@ -24107,6 +24430,12 @@ ccpVersion: global.ccpVersion, report: report }, callbacks); + + connect.publishSoftphoneReport({ + contactId: this.getContactId(), + ccpVersion: global.ccpVersion, + report: report + }); }; Contact.prototype.conferenceConnections = function (callbacks) { @@ -24276,46 +24605,389 @@ || connectionType === connect.ConnectionType.MONITORING; } - /** - * @class VoiceConnection - * @param {number} contactId - * @param {number} connectionId - * @description - Provides voice media specific operations - */ - var VoiceConnection = function (contactId, connectionId) { - Connection.call(this, contactId, connectionId); - }; - - VoiceConnection.prototype = Object.create(Connection.prototype); - VoiceConnection.prototype.constructor = VoiceConnection; - - /** - * @deprecated - * Please use getMediaInfo + /*---------------------------------------------------------------- + * Voice authenticator VoiceId */ - VoiceConnection.prototype.getSoftphoneMediaInfo = function () { - return this._getData().softphoneMediaInfo; + + var VoiceId = function (contactId) { + this.contactId = contactId; }; - VoiceConnection.prototype.getMediaInfo = function () { - return this._getData().softphoneMediaInfo; + VoiceId.prototype.getSpeakerId = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.GET_SPEAKER_ID, { + "contactId": self.contactId, + "instanceId": connect.core.getAgentDataProvider().getInstanceId(), + "awsAccountId": connect.core.getAgentDataProvider().getAWSAccountId() + }, { + success: function (data) { + if(data.contactData.customerId) { + var obj = { + speakerId: data.contactData.customerId + } + resolve(obj); + } else { + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.NO_SPEAKER_ID_FOUND, "No speakerId assotiated with this call", err); + reject(error); + } + + }, + failure: function (err) { + connect.getLog().error("Get SpeakerId failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.GET_SPEAKER_ID_FAILED, "Get SpeakerId failed", err); + reject(error); + } + }); + }); }; - VoiceConnection.prototype.getMediaType = function () { - return connect.MediaType.SOFTPHONE; + VoiceId.prototype.getSpeakerStatus = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + self.getSpeakerId().then(function(data){ + client.call(connect.AgentAppClientMethods.GET_SPEAKER_STATUS, { + "SpeakerId": connect.assertNotNull(data.speakerId, 'speakerId'), + "DomainId" : "ConnectDefaultDomainId" + }, { + success: function (data) { + resolve(data); + }, + failure: function (err) { + connect.getLog().error("getSpeakerStatus failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.GET_SPEAKER_STATUS_FAILED, "Get SpeakerStatus failed", err); + reject(error); + } + }); + }).catch(function(err){ + reject(err); + }); + }); }; - VoiceConnection.prototype.getMediaController = function () { - return connect.core.mediaFactory.get(this); - } - + VoiceId.prototype.optOutSpeaker = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + self.getSpeakerId().then(function(data){ + client.call(connect.AgentAppClientMethods.OPT_OUT_VOICEID_SPEAKER, { + "SpeakerId": connect.assertNotNull(data.speakerId, 'speakerId'), + "DomainId" : "ConnectDefaultDomainId" + }, { + success: function (data) { + connect.getLog().info("optOutSpeaker succeeded"); + //TODO add more logic here for filtering out data once VoiceId API finalized + resolve(data); + }, + failure: function (err) { + connect.getLog().error("optOutSpeaker failed") + .withObject({ + err: err, + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.OPT_OUT_SPEAKER_FAILED, "optOutSpeaker failed.", err); + reject(error); + } + }); + }).catch(function(err){ + reject(err); + }); + }); + }; - /** - * @class ChatConnection - * @param {*} contactId - * @param {*} connectionId - * @description adds the chat media specific functionality - */ + VoiceId.prototype.startSession = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.START_VOICEID_SESSION, { + "contactId": self.contactId, + "instanceId": connect.core.getAgentDataProvider().getInstanceId(), + "customerAccountId": connect.core.getAgentDataProvider().getAWSAccountId(), + "clientToken": AWS.util.uuid.v4() + }, { + success: function (data) { + if(data.sessionId) { + resolve(data); + } else { + reject(Error("No contact id is returned from start session api.")) + } + }, + failure: function (err) { + connect.getLog().error("startVoiceIdSession failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.START_SESSION_FAILED, "startVoiceIdSession failed", err); + reject(error); + } + }); + }); + }; + + VoiceId.prototype.evaluateSpeaker = function (startNew) { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + var maxPollTimes = 120; // Polling for maximum 2 mins. + var milliInterval = 1000; + return new Promise(function (resolve, reject) { + function evaluate() { + client.call(connect.AgentAppClientMethods.EVALUATE_SPEAKER_WITH_VOICEID, { + "SessionNameOrId": contactData.initialContactId || this.contactId + }, { + success: function (data) { + if(maxPollTimes-- !== 1) { + if(data.StreamingStatus === connect.VoiceIdStreamingStatus.ENDED && data.AuthenticationResult.Decision === connect.VoiceIdAuthenticationDecision.NOT_ENOUGH_SPEECH){ + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.INCONCLUSIVE; + resolve(data); + }else if(data.AuthenticationResult.Decision !== connect.VoiceIdAuthenticationDecision.NOT_ENOUGH_SPEECH) { + switch (data.AuthenticationResult.Decision) { + case connect.VoiceIdAuthenticationDecision.ACCEPT: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.AUTHENTICATED; + break; + case connect.VoiceIdAuthenticationDecision.REJECT: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.NOT_AUTHENTICATED; + break; + case connect.VoiceIdAuthenticationDecision.SPEAKER_OPTED_OUT: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.OPT_OUT; + break; + case connect.VoiceIdAuthenticationDecision.SPEAKER_NOT_ENROLLED: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.NOT_ENROLLED; + break; + default: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.ERROR; + } + resolve(data); + } else { + setTimeout(function(){ + evaluate(); + },milliInterval); + } + } else { + connect.getLog().error("evaluateSpeaker timeout"); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.TIMEOUT, "evaluateSpeaker timeout"); + reject(error); + } + }, + failure: function (err) { + connect.getLog().error("evaluateSpeaker failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.EVALUATE_SPEAKER_FAILED, "evaluateSpeaker failed", err); + reject(error); + } + }) + } + if(!startNew){ + evaluate(); + } else { + self.startSession().then(function(data){ + evaluate(); + }).catch(function(err){ + reject(err) + }) + } + }); + }; + + VoiceId.prototype.describeSession = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + var maxPollingTimes = 120; // It is polling for maximum 10 mins. + var milliInterval = 5000; + return new Promise(function (resolve, reject) { + function describe() { + client.call(connect.AgentAppClientMethods.DESCRIBE_VOICEID_SESSION, { + "SessionNameOrId": contactData.initialContactId || this.contactId + }, { + success: function (data) { + if(maxPollingTimes-- !== 1) { + if(data.Session.EnrollmentRequestDetails.Status === connect.VoiceIdEnrollmentRequestStatus.COMPLETED) { + resolve(data); + } else if(data.Session.EnrollmentRequestDetails.Status === connect.VoiceIdEnrollmentRequestStatus.IN_PROGRESS) { + setTimeout(function(){ + describe(); + },milliInterval); + } else if(data.Session.EnrollmentRequestDetails.Status === connect.VoiceIdEnrollmentRequestStatus.NOT_ENOUGH_SPEECH) { + if(data.Session.StreamingStatus === connect.VoiceIdStreamingStatus.ENDED) { + self.startSession().then(function(data){ + describe(); + }).catch(function(err, data){ + reject(err); + }) + } else { + setTimeout(function(){ + describe(); + },milliInterval); + } + } else { + reject(Error(data.Session.EnrollmentRequestDetails.Status)); + } + } else { + connect.getLog().error("describeSession timeout"); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.TIMEOUT, "describeSession timeout"); + reject(error); + } + }, + failure: function (err) { + connect.getLog().error("describeSession failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.DESCRIBE_SESSION_FAILED, "describeSession failed", err); + reject(error); + } + }) + } + describe(); + }); + }; + + VoiceId.prototype.enrollSpeaker = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.ENROLL_SPEAKER_IN_VOICEID, { + "SessionNameOrId": contactData.initialContactId || this.contactId + }, { + success: function (data) { + if(data.Status === connect.VoiceIdEnrollmentRequestStatus.COMPLETED) { + resolve(data); + } else { + self.describeSession().then(function(data){ + resolve(data); + }).catch(function(err){ + reject(err); + }) + } + }, + failure: function (err) { + connect.getLog().error("enrollSpeaker failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.ENROLL_SPEAKER_FAILED, "enrollSpeaker failed", err); + reject(error); + } + }); + }); + }; + + VoiceId.prototype.updateSpeakerId = function (speakerId) { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.UPDATE_VOICEID_SESSION, { + "SessionNameOrId": contactData.initialContactId || this.contactId, + "SpeakerId": connect.assertNotNull(speakerId, 'speakerId') + }, { + success: function (data) { + resolve(data); + }, + failure: function (err) { + connect.getLog().error("updateSpeakerId failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.UPDATE_SPEAKER_ID_FAILED, "updateSpeakerId failed", err); + reject(error); + } + }); + }); + }; + + VoiceId.prototype.checkConferenceCall = function(){ + var self = this; + var isConferenceCall = connect.core.getAgentDataProvider().getContactData(self.contactId).connections.length > 2; + if(isConferenceCall){ + throw new connect.NotImplementedError("VoiceId is not supported for conference calls"); + } + } + + /** + * @class VoiceConnection + * @param {number} contactId + * @param {number} connectionId + * @description - Provides voice media specific operations + */ + var VoiceConnection = function (contactId, connectionId) { + this._speakerAuthenticator = new VoiceId(contactId); + Connection.call(this, contactId, connectionId); + }; + + VoiceConnection.prototype = Object.create(Connection.prototype); + VoiceConnection.prototype.constructor = VoiceConnection; + + /** + * @deprecated + * Please use getMediaInfo + */ + VoiceConnection.prototype.getSoftphoneMediaInfo = function () { + return this._getData().softphoneMediaInfo; + }; + + VoiceConnection.prototype.getMediaInfo = function () { + return this._getData().softphoneMediaInfo; + }; + + VoiceConnection.prototype.getMediaType = function () { + return connect.MediaType.SOFTPHONE; + }; + + VoiceConnection.prototype.getMediaController = function () { + return connect.core.mediaFactory.get(this); + } + + VoiceConnection.prototype.getVoiceIdSpeakerId = function() { + return this._speakerAuthenticator.getSpeakerId(); + } + + VoiceConnection.prototype.getVoiceIdSpeakerStatus = function() { + return this._speakerAuthenticator.getSpeakerStatus(); + } + + VoiceConnection.prototype.optOutVoiceIdSpeaker = function() { + + return this._speakerAuthenticator.optOutSpeaker(); + } + + VoiceConnection.prototype.evaluateSpeakerWithVoiceId = function(startNew) { + return this._speakerAuthenticator.evaluateSpeaker(startNew); + } + + VoiceConnection.prototype.enrollSpeakerInVoiceId = function() { + return this._speakerAuthenticator.enrollSpeaker(); + } + + VoiceConnection.prototype.updateVoiceIdSpeakerId = function(speakerId) { + return this._speakerAuthenticator.updateSpeakerId(speakerId); + } + + /** + * @class ChatConnection + * @param {*} contactId + * @param {*} connectionId + * @description adds the chat media specific functionality + */ var ChatConnection = function (contactId, connectionId) { Connection.call(this, contactId, connectionId); }; @@ -24339,7 +25011,10 @@ try { mediaObject.participantToken = JSON.parse(data.connectionData).ConnectionAuthenticationToken; } catch (e) { - connect.getLog().error(connect.LogComponent.CHAT, "Connection data is invalid").withObject(data).withException(e); + connect.getLog().error(connect.LogComponent.CHAT, "Connection data is invalid") + .withObject(data) + .withException(e) + .sendInternalLogToServer(); mediaObject.participantToken = null; } } @@ -24369,11 +25044,11 @@ return new Promise(function (resolve, reject) { client.call(connect.ClientMethods.CREATE_TRANSPORT, transportDetails, { success: function (data) { - connect.getLog().info("getConnectionToken succeeded"); + connect.getLog().info("getConnectionToken succeeded").sendInternalLogToServer(); resolve(data); }, failure: function (err, data) { - connect.getLog().error("getConnectionToken failed") + connect.getLog().error("getConnectionToken failed").sendInternalLogToServer() .withObject({ err: err, data: data @@ -24399,6 +25074,35 @@ } } + /** + * @class TaskConnection + * @param {*} contactId + * @param {*} connectionId + * @description adds the task media specific functionality + */ + var TaskConnection = function (contactId, connectionId) { + Connection.call(this, contactId, connectionId); + }; + TaskConnection.prototype = Object.create(Connection.prototype); + TaskConnection.prototype.constructor = TaskConnection; + + TaskConnection.prototype.getMediaType = function () { + return connect.MediaType.TASK; + } + + TaskConnection.prototype.getMediaInfo = function () { + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + var mediaObject = { + contactId: this.contactId, + initialContactId: contactData.initialContactId || this.contactId, + }; + return mediaObject; + }; + + TaskConnection.prototype.getMediaController = function () { + return connect.core.mediaFactory.get(this); + }; + /*---------------------------------------------------------------- * class ConnectionSnapshot */ @@ -24504,7 +25208,7 @@ if (!connect.core.masterClient) { // We can't be the master because there is no master client! - connect.getLog().warn("We can't be the master for topic '%s' because there is no master client!", topic); + connect.getLog().warn("We can't be the master for topic '%s' because there is no master client!", topic).sendInternalLogToServer(); if (f_else) { f_else(); } @@ -24546,6 +25250,7 @@ connect.BaseConnection = Connection; connect.VoiceConnection = VoiceConnection; connect.ChatConnection = ChatConnection; + connect.TaskConnection = TaskConnection; connect.ConnectionSnapshot = ConnectionSnapshot; connect.Endpoint = Endpoint; connect.Address = Endpoint; @@ -24554,7 +25259,9 @@ })(); -!function(e){var n={};function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:o})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(t.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)t.d(o,r,function(n){return e[n]}.bind(null,r));return o},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=2)}([function(e,n,t){"use strict";var o=t(1);function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i={assertTrue:function(e,n){if(!e)throw new Error(n)},assertNotNull:function(e,n){return i.assertTrue(null!==e&&void 0!==r(e),Object(o.sprintf)("%s must be provided",n||"A value")),e},isNonEmptyString:function(e){return"string"==typeof e&&e.length>0},assertIsList:function(e,n){if(!Array.isArray(e))throw new Error(n+" is not an array")},isFunction:function(e){return!!(e&&e.constructor&&e.call&&e.apply)},isObject:function(e){return!("object"!==r(e)||null===e)},isString:function(e){return"string"==typeof e},isNumber:function(e){return"number"==typeof e}},c=new RegExp("^(wss://)\\w*");i.validWSUrl=function(e){return c.test(e)},i.getSubscriptionResponse=function(e,n,t){return{topic:e,content:{status:n?"success":"failure",topics:t}}},i.assertIsObject=function(e,n){if(!i.isObject(e))throw new Error(n+" is not an object!")},i.addJitter=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;n=Math.min(n,1);var t=Math.random()>.5?1:-1;return Math.floor(e+t*e*Math.random()*n)},i.isNetworkOnline=function(){return navigator.onLine};var s=i,a="NULL",u="CLIENT_LOGGER",l="DEBUG",f="aws/subscribe",p="aws/unsubscribe",d="aws/heartbeat",b="connected",g="disconnected";function m(e){return(m="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function y(e,n){return!n||"object"!==m(n)&&"function"!=typeof n?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):n}function S(e){return(S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function k(e,n){return(k=Object.setPrototypeOf||function(e,n){return e.__proto__=n,e})(e,n)}function w(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function v(e,n){for(var t=0;t=this._level}},{key:"hasClientLogger",value:function(){return null!==this._clientLogger}},{key:"getLogger",value:function(e){var n=e.prefix||"";return this._logsDestination===l?this.consoleLoggerWrapper:new W(n)}},{key:"updateLoggerConfig",value:function(e){var n=e||{};this._level=n.level||T.DEBUG,this._clientLogger=n.logger||null,this._logsDestination=a,n.debug&&(this._logsDestination=l),n.logger&&(this._logsDestination=u)}}]),e}(),I=function(){function e(){w(this,e)}return h(e,[{key:"debug",value:function(){}},{key:"info",value:function(){}},{key:"warn",value:function(){}},{key:"error",value:function(){}}]),e}(),W=function(e){function n(e){var t;return w(this,n),(t=y(this,S(n).call(this))).prefix=e||"",t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),n&&k(e,n)}(n,I),h(n,[{key:"debug",value:function(){for(var e=arguments.length,n=new Array(e),t=0;t0&&void 0!==arguments[0]?arguments[0]:"";e.debug("["+n+"] Primary WebSocket: "+k(t.primary)+" | Secondary WebSocket: "+k(t.secondary))},v=function(e,n){return e&&e.readyState===n},h=function(e){return v(e,WebSocket.OPEN)},C=function(e){return null===e||void 0===e.readyState||v(e,WebSocket.CLOSED)},T=function(){return null!==t.secondary?t.secondary:t.primary},O=function(){return h(T())},I=function(){if(i.pendingResponse)return e.warn("Heartbeat response not received"),clearInterval(i.intervalHandle),i.pendingResponse=!1,void G();O()?(e.debug("Sending heartbeat"),T().send(P(d)),i.pendingResponse=!0):(e.warn("Failed to send heartbeat since WebSocket is not open"),w("sendHeartBeat"),G())},W=function(){o.exponentialBackOffTime=1e3,i.pendingResponse=!1,o.reconnectWebSocket=!0,clearTimeout(o.lifeTimeTimeoutHandle),clearInterval(i.intervalHandle),clearTimeout(o.exponentialTimeoutHandle),clearTimeout(o.webSocketInitCheckerTimeoutId)},N=function(){l.consecutiveFailedSubscribeAttempts=0,l.consecutiveNoResponseRequest=0,clearInterval(l.responseCheckIntervalId),clearInterval(l.reSubscribeIntervalId)},E=function(){r.connectWebSocketRetryCount=0,r.connectionAttemptStartTime=null,r.noOpenConnectionsTimestamp=null},L=function(){try{e.info("WebSocket connection established!"),w("webSocketOnOpen"),o.connState=b,null===t.secondary&&S(c.connectionGain);var n=Date.now();S(c.connectionOpen,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,noOpenConnectionsTimestamp:r.noOpenConnectionsTimestamp,connectionEstablishedTime:n,timeToConnect:n-r.connectionAttemptStartTime,timeWithoutConnection:r.noOpenConnectionsTimestamp?n-r.noOpenConnectionsTimestamp:null}),E(),W(),T().openTimestamp=Date.now(),0===u.subscribed.size&&h(t.secondary)&&j(t.primary,"[Primary WebSocket] Closing WebSocket"),(u.subscribed.size>0||u.pending.size>0)&&(h(t.secondary)&&e.info("Subscribing secondary websocket to topics of primary websocket"),u.subscribed.forEach(function(e){u.subscriptionHistory.add(e),u.pending.add(e)}),u.subscribed.clear(),R()),I(),i.intervalHandle=setInterval(I,1e4),o.lifeTimeTimeoutHandle=setTimeout(function(){e.debug("Starting scheduled WebSocket manager reconnect"),G()},1e3*a.connConfig.webSocketTransport.transportLifeTimeInSeconds)}catch(n){e.error("Error after establishing WebSocket connection",n)}},F=function(n){w("webSocketOnError"),e.error("WebSocketManager Error, error_event: ",n),G()},x=function(n){var o=JSON.parse(n.data);switch(o.topic){case f:if(e.debug("Subscription Message received from webSocket server",n.data),l.requestCompleted=!0,l.consecutiveNoResponseRequest=0,"success"===o.content.status)l.consecutiveFailedSubscribeAttempts=0,o.content.topics.forEach(function(e){u.subscriptionHistory.delete(e),u.pending.delete(e),u.subscribed.add(e)}),0===u.subscriptionHistory.size?h(t.secondary)&&(e.info("Successfully subscribed secondary websocket to all topics of primary websocket"),j(t.primary,"[Primary WebSocket] Closing WebSocket")):R(),S(c.subscriptionUpdate,o);else{if(clearInterval(l.reSubscribeIntervalId),++l.consecutiveFailedSubscribeAttempts,5===l.consecutiveFailedSubscribeAttempts)return S(c.subscriptionFailure,o),void(l.consecutiveFailedSubscribeAttempts=0);l.reSubscribeIntervalId=setInterval(function(){R()},500)}break;case d:e.debug("Heartbeat response received"),i.pendingResponse=!1;break;default:if(o.topic){if(e.debug("Message received for topic "+o.topic),h(t.primary)&&h(t.secondary)&&0===u.subscriptionHistory.size&&this===t.primary)return void e.warn("Ignoring Message for Topic "+o.topic+", to avoid duplicates");if(0===c.allMessage.size&&0===c.topic.size)return void e.warn("No registered callback listener for Topic",o.topic);S(c.allMessage,o),c.topic.has(o.topic)&&S(c.topic.get(o.topic),o)}else o.message?e.warn("WebSocketManager Message Error",o):e.warn("Invalid incoming message",o)}},R=function n(){if(l.consecutiveNoResponseRequest>3)return e.warn("Ignoring subscribePendingTopics since we have exhausted max subscription retries with no response"),void S(c.subscriptionFailure,s.getSubscriptionResponse(f,!1,Array.from(u.pending)));O()?(clearInterval(l.responseCheckIntervalId),T().send(P(f,{topics:Array.from(u.pending)})),l.requestCompleted=!1,l.responseCheckIntervalId=setInterval(function(){l.requestCompleted||(++l.consecutiveNoResponseRequest,n())},1e3)):e.warn("Ignoring subscribePendingTopics call since Default WebSocket is not open")},j=function(n,t){v(n,WebSocket.CONNECTING)||v(n,WebSocket.OPEN)?n.close(1e3,t):e.warn("Ignoring WebSocket Close request, WebSocket State: "+k(n))},A=function(e){j(t.primary,"[Primary] WebSocket "+e),j(t.secondary,"[Secondary] WebSocket "+e)},M=function(){r.connectWebSocketRetryCount++;var n=s.addJitter(o.exponentialBackOffTime,.3);Date.now()+n<=a.connConfig.urlConnValidTime?(e.debug("Scheduling WebSocket reinitialization, after delay "+n+" ms"),o.exponentialTimeoutHandle=setTimeout(function(){return z()},n),o.exponentialBackOffTime*=2):(e.warn("WebSocket URL is cannot be used to establish connection"),G())},D=function(n){W(),N(),e.error("WebSocket Initialization failed"),o.websocketInitFailed=!0,A("Terminating WebSocket Manager"),clearInterval(y),S(c.initFailure,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,reason:n}),E()},P=function(e,n){return JSON.stringify({topic:e,content:n})},H=function(n){return!!(s.isObject(n)&&s.isObject(n.webSocketTransport)&&s.isNonEmptyString(n.webSocketTransport.url)&&s.validWSUrl(n.webSocketTransport.url)&&1e3*n.webSocketTransport.transportLifeTimeInSeconds>=36e5)||(e.error("Invalid WebSocket Connection Configuration",n),!1)},G=function n(){if(s.isNetworkOnline())if(o.websocketInitFailed)e.debug("WebSocket Init had failed, ignoring this getWebSocketConnConfig request");else{if(a.promiseCompleted)return W(),e.info("Fetching new WebSocket connection configuration"),r.connectionAttemptStartTime=r.connectionAttemptStartTime||Date.now(),a.promiseCompleted=!1,a.promiseHandle=c.getWebSocketTransport(),a.promiseHandle.then(function(n){return a.promiseCompleted=!0,e.debug("Successfully fetched webSocket connection configuration",n),H(n)?(a.connConfig=n,a.connConfig.urlConnValidTime=Date.now()+85e3,z()):(D("Invalid WebSocket connection configuration: "+n),{webSocketConnectionFailed:!0})},function(t){return a.promiseCompleted=!0,e.error("Failed to fetch webSocket connection configuration",t),setTimeout(function(){return n()},s.addJitter(5e3,.3)),{webSocketConnectionFailed:!0}});e.debug("There is an ongoing getWebSocketConnConfig request, this request will be ignored")}else e.info("Network offline, ignoring this getWebSocketConnConfig request")},z=function(){if(o.websocketInitFailed)return e.info("web-socket initializing had failed, aborting re-init"),{webSocketConnectionFailed:!0};if(!s.isNetworkOnline())return e.warn("System is offline aborting web-socket init"),{webSocketConnectionFailed:!0};e.info("Initializing Websocket Manager"),w("initWebSocket");try{if(H(a.connConfig)){var n=null;return h(t.primary)?(e.debug("Primary Socket connection is already open"),v(t.secondary,WebSocket.CONNECTING)||(e.debug("Establishing a secondary web-socket connection"),t.secondary=U()),n=t.secondary):(v(t.primary,WebSocket.CONNECTING)||(e.debug("Establishing a primary web-socket connection"),t.primary=U()),n=t.primary),o.webSocketInitCheckerTimeoutId=setTimeout(function(){h(n)||M()},1e3),{webSocketConnectionFailed:!1}}}catch(n){return e.error("Error Initializing web-socket-manager",n),D("Failed to initialize new WebSocket: "+n.message),{webSocketConnectionFailed:!0}}},U=function(){var n=new WebSocket(a.connConfig.webSocketTransport.url);return n.addEventListener("open",L),n.addEventListener("message",x),n.addEventListener("error",F),n.addEventListener("close",function(i){return function(n,i){e.info("Socket connection is closed",n),w("webSocketOnClose before-cleanup"),S(c.connectionClose,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),C(t.primary)&&(t.primary=null),C(t.secondary)&&(t.secondary=null),o.reconnectWebSocket&&(h(t.primary)||h(t.secondary)?C(t.primary)&&h(t.secondary)&&(e.info("[Primary] WebSocket Cleanly Closed"),t.primary=t.secondary,t.secondary=null):(e.warn("Neither primary websocket and nor secondary websocket have open connections, attempting to re-establish connection"),o.connState!==g?(S(c.connectionLost,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),r.noOpenConnectionsTimestamp=Date.now()):e.info("Ignoring connectionLost callback invocation"),o.connState=g,G()),w("webSocketOnClose after-cleanup"))}(i,n)}),n};this.init=function(n){if(s.assertTrue(s.isFunction(n),"transportHandle must be a function"),null===c.getWebSocketTransport)return c.getWebSocketTransport=n,G();e.warn("Web Socket Manager was already initialized")},this.onInitFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.initFailure.add(e),o.websocketInitFailed&&e(),function(){return c.initFailure.delete(e)}},this.onConnectionOpen=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionOpen.add(e),function(){return c.connectionOpen.delete(e)}},this.onConnectionClose=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionClose.add(e),function(){return c.connectionClose.delete(e)}},this.onConnectionGain=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionGain.add(e),O()&&e(),function(){return c.connectionGain.delete(e)}},this.onConnectionLost=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionLost.add(e),o.connState===g&&e(),function(){return c.connectionLost.delete(e)}},this.onSubscriptionUpdate=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionUpdate.add(e),function(){return c.subscriptionUpdate.delete(e)}},this.onSubscriptionFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionFailure.add(e),function(){return c.subscriptionFailure.delete(e)}},this.onMessage=function(e,n){return s.assertNotNull(e,"topicName"),s.assertTrue(s.isFunction(n),"cb must be a function"),c.topic.has(e)?c.topic.get(e).add(n):c.topic.set(e,new Set([n])),function(){return c.topic.get(e).delete(n)}},this.onAllMessage=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.allMessage.add(e),function(){return c.allMessage.delete(e)}},this.subscribeTopics=function(e){s.assertNotNull(e,"topics"),s.assertIsList(e),e.forEach(function(e){u.subscribed.has(e)||u.pending.add(e)}),l.consecutiveNoResponseRequest=0,R()},this.sendMessage=function(n){if(s.assertIsObject(n,"payload"),void 0===n.topic||m.has(n.topic))e.warn("Cannot send message, Invalid topic",n);else{try{n=JSON.stringify(n)}catch(t){return void e.warn("Error stringify message",n)}O()?T().send(n):e.warn("Cannot send message, web socket connection is not open")}},this.closeWebSocket=function(){W(),N(),o.reconnectWebSocket=!1,clearInterval(y),A("User request to close WebSocket")},this.terminateWebSocketManager=D},L={create:function(){return new E},setGlobalConfig:function(e){var n=e.loggerConfig;_.updateLoggerConfig(n)},LogLevel:T,Logger:C}},function(e,n,t){var o;!function(){"use strict";var r={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function i(e){return function(e,n){var t,o,c,s,a,u,l,f,p,d=1,b=e.length,g="";for(o=0;o=0),s.type){case"b":t=parseInt(t,10).toString(2);break;case"c":t=String.fromCharCode(parseInt(t,10));break;case"d":case"i":t=parseInt(t,10);break;case"j":t=JSON.stringify(t,null,s.width?parseInt(s.width):0);break;case"e":t=s.precision?parseFloat(t).toExponential(s.precision):parseFloat(t).toExponential();break;case"f":t=s.precision?parseFloat(t).toFixed(s.precision):parseFloat(t);break;case"g":t=s.precision?String(Number(t.toPrecision(s.precision))):parseFloat(t);break;case"o":t=(parseInt(t,10)>>>0).toString(8);break;case"s":t=String(t),t=s.precision?t.substring(0,s.precision):t;break;case"t":t=String(!!t),t=s.precision?t.substring(0,s.precision):t;break;case"T":t=Object.prototype.toString.call(t).slice(8,-1).toLowerCase(),t=s.precision?t.substring(0,s.precision):t;break;case"u":t=parseInt(t,10)>>>0;break;case"v":t=t.valueOf(),t=s.precision?t.substring(0,s.precision):t;break;case"x":t=(parseInt(t,10)>>>0).toString(16);break;case"X":t=(parseInt(t,10)>>>0).toString(16).toUpperCase()}r.json.test(s.type)?g+=t:(!r.number.test(s.type)||f&&!s.sign?p="":(p=f?"+":"-",t=t.toString().replace(r.sign,"")),u=s.pad_char?"0"===s.pad_char?"0":s.pad_char.charAt(1):" ",l=s.width-(p+t).length,a=s.width&&l>0?u.repeat(l):"",g+=s.align?p+t+a:"0"===u?p+a+t:a+p+t)}return g}(function(e){if(s[e])return s[e];var n,t=e,o=[],i=0;for(;t;){if(null!==(n=r.text.exec(t)))o.push(n[0]);else if(null!==(n=r.modulo.exec(t)))o.push("%");else{if(null===(n=r.placeholder.exec(t)))throw new SyntaxError("[sprintf] unexpected placeholder");if(n[2]){i|=1;var c=[],a=n[2],u=[];if(null===(u=r.key.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(c.push(u[1]);""!==(a=a.substring(u[0].length));)if(null!==(u=r.key_access.exec(a)))c.push(u[1]);else{if(null===(u=r.index_access.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");c.push(u[1])}n[2]=c}else i|=2;if(3===i)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");o.push({placeholder:n[0],param_no:n[1],keys:n[2],sign:n[3],pad_char:n[4],align:n[5],width:n[6],precision:n[7],type:n[8]})}t=t.substring(n[0].length)}return s[e]=o}(e),arguments)}function c(e,n){return i.apply(null,[e].concat(n||[]))}var s=Object.create(null);n.sprintf=i,n.vsprintf=c,"undefined"!=typeof window&&(window.sprintf=i,window.vsprintf=c,void 0===(o=function(){return{sprintf:i,vsprintf:c}}.call(n,t,n,e))||(e.exports=o))}()},function(e,n,t){"use strict";t.r(n),function(e){t.d(n,"WebSocketManager",function(){return r});var o=t(0);e.connect=e.connect||{},connect.WebSocketManager=o.a;var r=o.a}.call(this,t(3))},function(e,n){var t;t=function(){return this}();try{t=t||new Function("return this")()}catch(e){"object"==typeof window&&(t=window)}e.exports=t}]); +!function(e){var n={};function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:o})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(t.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)t.d(o,r,function(n){return e[n]}.bind(null,r));return o},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=2)}([function(e,n,t){"use strict";var o=t(1);function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i={assertTrue:function(e,n){if(!e)throw new Error(n)},assertNotNull:function(e,n){return i.assertTrue(null!==e&&void 0!==r(e),Object(o.sprintf)("%s must be provided",n||"A value")),e},isNonEmptyString:function(e){return"string"==typeof e&&e.length>0},assertIsList:function(e,n){if(!Array.isArray(e))throw new Error(n+" is not an array")},isFunction:function(e){return!!(e&&e.constructor&&e.call&&e.apply)},isObject:function(e){return!("object"!==r(e)||null===e)},isString:function(e){return"string"==typeof e},isNumber:function(e){return"number"==typeof e}},c=new RegExp("^(wss://)\\w*");i.validWSUrl=function(e){return c.test(e)},i.getSubscriptionResponse=function(e,n,t){return{topic:e,content:{status:n?"success":"failure",topics:t}}},i.assertIsObject=function(e,n){if(!i.isObject(e))throw new Error(n+" is not an object!")},i.addJitter=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;n=Math.min(n,1);var t=Math.random()>.5?1:-1;return Math.floor(e+t*e*Math.random()*n)},i.isNetworkOnline=function(){return navigator.onLine};var s=i,a="NULL",u="CLIENT_LOGGER",l="DEBUG",f="aws/subscribe",p="aws/unsubscribe",d="aws/heartbeat",b="connected",g="disconnected";function m(e){return(m="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function y(e,n){return!n||"object"!==m(n)&&"function"!=typeof n?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):n}function S(e){return(S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function k(e,n){return(k=Object.setPrototypeOf||function(e,n){return e.__proto__=n,e})(e,n)}function v(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function h(e,n){for(var t=0;t=this._level}},{key:"hasClientLogger",value:function(){return null!==this._clientLogger}},{key:"getLogger",value:function(e){var n=e.prefix||"";return this._logsDestination===l?this.consoleLoggerWrapper:new W(n)}},{key:"updateLoggerConfig",value:function(e){var n=e||{};this._level=n.level||T.DEBUG,this._clientLogger=n.logger||null,this._logsDestination=a,n.debug&&(this._logsDestination=l),n.logger&&(this._logsDestination=u)}}]),e}(),I=function(){function e(){v(this,e)}return w(e,[{key:"debug",value:function(){}},{key:"info",value:function(){}},{key:"warn",value:function(){}},{key:"error",value:function(){}}]),e}(),W=function(e){function n(e){var t;return v(this,n),(t=y(this,S(n).call(this))).prefix=e||"",t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),n&&k(e,n)}(n,I),w(n,[{key:"debug",value:function(){for(var e=arguments.length,n=new Array(e),t=0;t0&&void 0!==arguments[0]?arguments[0]:"";q(e.debug("["+n+"] Primary WebSocket: "+k(t.primary)+" | Secondary WebSocket: "+k(t.secondary)))},h=function(e,n){return e&&e.readyState===n},w=function(e){return h(e,WebSocket.OPEN)},C=function(e){return null===e||void 0===e.readyState||h(e,WebSocket.CLOSED)},T=function(){return null!==t.secondary?t.secondary:t.primary},O=function(){return w(T())},I=function(){if(i.pendingResponse)return q(e.warn("Heartbeat response not received")),clearInterval(i.intervalHandle),i.pendingResponse=!1,void G();O()?(q(e.debug("Sending heartbeat")),T().send(P(d)),i.pendingResponse=!0):(q(e.warn("Failed to send heartbeat since WebSocket is not open")),v("sendHeartBeat"),G())},W=function(){o.exponentialBackOffTime=1e3,i.pendingResponse=!1,o.reconnectWebSocket=!0,clearTimeout(o.lifeTimeTimeoutHandle),clearInterval(i.intervalHandle),clearTimeout(o.exponentialTimeoutHandle),clearTimeout(o.webSocketInitCheckerTimeoutId)},N=function(){l.consecutiveFailedSubscribeAttempts=0,l.consecutiveNoResponseRequest=0,clearInterval(l.responseCheckIntervalId),clearInterval(l.reSubscribeIntervalId)},E=function(){r.connectWebSocketRetryCount=0,r.connectionAttemptStartTime=null,r.noOpenConnectionsTimestamp=null},L=function(){try{q(e.info("WebSocket connection established!")),v("webSocketOnOpen"),null!==o.connState&&o.connState!==g||S(c.connectionGain),o.connState=b;var n=Date.now();S(c.connectionOpen,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,noOpenConnectionsTimestamp:r.noOpenConnectionsTimestamp,connectionEstablishedTime:n,timeToConnect:n-r.connectionAttemptStartTime,timeWithoutConnection:r.noOpenConnectionsTimestamp?n-r.noOpenConnectionsTimestamp:null}),E(),W(),T().openTimestamp=Date.now(),0===u.subscribed.size&&w(t.secondary)&&j(t.primary,"[Primary WebSocket] Closing WebSocket"),(u.subscribed.size>0||u.pending.size>0)&&(w(t.secondary)&&q(e.info("Subscribing secondary websocket to topics of primary websocket")),u.subscribed.forEach(function(e){u.subscriptionHistory.add(e),u.pending.add(e)}),u.subscribed.clear(),R()),I(),i.intervalHandle=setInterval(I,1e4);var l=Math.min(s.addJitter(3e6,.1),1e3*a.connConfig.webSocketTransport.transportLifeTimeInSeconds);q(e.debug("Scheduling WebSocket manager reconnection, after delay "+l+" ms")),o.lifeTimeTimeoutHandle=setTimeout(function(){q(e.debug("Starting scheduled WebSocket manager reconnection")),G()},l)}catch(n){q(e.error("Error after establishing WebSocket connection",n))}},F=function(n){v("webSocketOnError"),q(e.error("WebSocketManager Error, error_event: ",JSON.stringify(n))),G()},x=function(n){var o=JSON.parse(n.data);switch(o.topic){case f:if(q(e.debug("Subscription Message received from webSocket server",n.data)),l.requestCompleted=!0,l.consecutiveNoResponseRequest=0,"success"===o.content.status)l.consecutiveFailedSubscribeAttempts=0,o.content.topics.forEach(function(e){u.subscriptionHistory.delete(e),u.pending.delete(e),u.subscribed.add(e)}),0===u.subscriptionHistory.size?w(t.secondary)&&(q(e.info("Successfully subscribed secondary websocket to all topics of primary websocket")),j(t.primary,"[Primary WebSocket] Closing WebSocket")):R(),S(c.subscriptionUpdate,o);else{if(clearInterval(l.reSubscribeIntervalId),++l.consecutiveFailedSubscribeAttempts,5===l.consecutiveFailedSubscribeAttempts)return S(c.subscriptionFailure,o),void(l.consecutiveFailedSubscribeAttempts=0);l.reSubscribeIntervalId=setInterval(function(){R()},500)}break;case d:q(e.debug("Heartbeat response received")),i.pendingResponse=!1;break;default:if(o.topic){if(q(e.debug("Message received for topic "+o.topic)),w(t.primary)&&w(t.secondary)&&0===u.subscriptionHistory.size&&this===t.primary)return void q(e.warn("Ignoring Message for Topic "+o.topic+", to avoid duplicates"));if(0===c.allMessage.size&&0===c.topic.size)return void q(e.warn("No registered callback listener for Topic",o.topic));S(c.allMessage,o),c.topic.has(o.topic)&&S(c.topic.get(o.topic),o)}else o.message?q(e.warn("WebSocketManager Message Error",o)):q(e.warn("Invalid incoming message",o))}},R=function n(){if(l.consecutiveNoResponseRequest>3)return q(e.warn("Ignoring subscribePendingTopics since we have exhausted max subscription retries with no response")),void S(c.subscriptionFailure,s.getSubscriptionResponse(f,!1,Array.from(u.pending)));O()?(clearInterval(l.responseCheckIntervalId),T().send(P(f,{topics:Array.from(u.pending)})),l.requestCompleted=!1,l.responseCheckIntervalId=setInterval(function(){l.requestCompleted||(++l.consecutiveNoResponseRequest,n())},1e3)):q(e.warn("Ignoring subscribePendingTopics call since Default WebSocket is not open"))},j=function(n,t){h(n,WebSocket.CONNECTING)||h(n,WebSocket.OPEN)?n.close(1e3,t):q(e.warn("Ignoring WebSocket Close request, WebSocket State: "+k(n)))},M=function(e){j(t.primary,"[Primary] WebSocket "+e),j(t.secondary,"[Secondary] WebSocket "+e)},A=function(){r.connectWebSocketRetryCount++;var n=s.addJitter(o.exponentialBackOffTime,.3);Date.now()+n<=a.connConfig.urlConnValidTime?(q(e.debug("Scheduling WebSocket reinitialization, after delay "+n+" ms")),o.exponentialTimeoutHandle=setTimeout(function(){return z()},n),o.exponentialBackOffTime*=2):(q(e.warn("WebSocket URL cannot be used to establish connection")),G())},D=function(n){W(),N(),q(e.error("WebSocket Initialization failed")),o.websocketInitFailed=!0,M("Terminating WebSocket Manager"),clearInterval(y),S(c.initFailure,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,reason:n}),E()},P=function(e,n){return JSON.stringify({topic:e,content:n})},H=function(n){return!!(s.isObject(n)&&s.isObject(n.webSocketTransport)&&s.isNonEmptyString(n.webSocketTransport.url)&&s.validWSUrl(n.webSocketTransport.url)&&1e3*n.webSocketTransport.transportLifeTimeInSeconds>=3e5)||(q(e.error("Invalid WebSocket Connection Configuration",n)),!1)},G=function(){if(s.isNetworkOnline())if(o.websocketInitFailed)q(e.debug("WebSocket Init had failed, ignoring this getWebSocketConnConfig request"));else{if(a.promiseCompleted)return W(),q(e.info("Fetching new WebSocket connection configuration")),r.connectionAttemptStartTime=r.connectionAttemptStartTime||Date.now(),a.promiseCompleted=!1,a.promiseHandle=c.getWebSocketTransport(),a.promiseHandle.then(function(n){return a.promiseCompleted=!0,q(e.debug("Successfully fetched webSocket connection configuration",n)),H(n)?(a.connConfig=n,a.connConfig.urlConnValidTime=Date.now()+85e3,z()):(D("Invalid WebSocket connection configuration: "+n),{webSocketConnectionFailed:!0})},function(n){return a.promiseCompleted=!0,q(e.error("Failed to fetch webSocket connection configuration",n)),{webSocketConnectionFailed:!0}});q(e.debug("There is an ongoing getWebSocketConnConfig request, this request will be ignored"))}else q(e.info("Network offline, ignoring this getWebSocketConnConfig request"))},z=function(){if(o.websocketInitFailed)return q(e.info("web-socket initializing had failed, aborting re-init")),{webSocketConnectionFailed:!0};if(!s.isNetworkOnline())return q(e.warn("System is offline aborting web-socket init")),{webSocketConnectionFailed:!0};q(e.info("Initializing Websocket Manager")),v("initWebSocket");try{if(H(a.connConfig)){var n=null;return w(t.primary)?(q(e.debug("Primary Socket connection is already open")),h(t.secondary,WebSocket.CONNECTING)||(q(e.debug("Establishing a secondary web-socket connection")),t.secondary=U()),n=t.secondary):(h(t.primary,WebSocket.CONNECTING)||(q(e.debug("Establishing a primary web-socket connection")),t.primary=U()),n=t.primary),o.webSocketInitCheckerTimeoutId=setTimeout(function(){w(n)||A()},1e3),{webSocketConnectionFailed:!1}}}catch(n){return q(e.error("Error Initializing web-socket-manager",n)),D("Failed to initialize new WebSocket: "+n.message),{webSocketConnectionFailed:!0}}},U=function(){var n=new WebSocket(a.connConfig.webSocketTransport.url);return n.addEventListener("open",L),n.addEventListener("message",x),n.addEventListener("error",F),n.addEventListener("close",function(i){return function(n,i){q(e.info("Socket connection is closed",n)),v("webSocketOnClose before-cleanup"),S(c.connectionClose,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),C(t.primary)&&(t.primary=null),C(t.secondary)&&(t.secondary=null),o.reconnectWebSocket&&(w(t.primary)||w(t.secondary)?C(t.primary)&&w(t.secondary)&&(q(e.info("[Primary] WebSocket Cleanly Closed")),t.primary=t.secondary,t.secondary=null):(q(e.warn("Neither primary websocket and nor secondary websocket have open connections, attempting to re-establish connection")),o.connState===g?q(e.info("Ignoring connectionLost callback invocation")):(S(c.connectionLost,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),r.noOpenConnectionsTimestamp=Date.now()),o.connState=g,G()),v("webSocketOnClose after-cleanup"))}(i,n)}),n},q=function(e){return e&&"function"==typeof e.sendInternalLogToServer&&e.sendInternalLogToServer(),e};this.init=function(n){if(s.assertTrue(s.isFunction(n),"transportHandle must be a function"),null===c.getWebSocketTransport)return c.getWebSocketTransport=n,G();q(e.warn("Web Socket Manager was already initialized"))},this.onInitFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.initFailure.add(e),o.websocketInitFailed&&e(),function(){return c.initFailure.delete(e)}},this.onConnectionOpen=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionOpen.add(e),function(){return c.connectionOpen.delete(e)}},this.onConnectionClose=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionClose.add(e),function(){return c.connectionClose.delete(e)}},this.onConnectionGain=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionGain.add(e),O()&&e(),function(){return c.connectionGain.delete(e)}},this.onConnectionLost=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionLost.add(e),o.connState===g&&e(),function(){return c.connectionLost.delete(e)}},this.onSubscriptionUpdate=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionUpdate.add(e),function(){return c.subscriptionUpdate.delete(e)}},this.onSubscriptionFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionFailure.add(e),function(){return c.subscriptionFailure.delete(e)}},this.onMessage=function(e,n){return s.assertNotNull(e,"topicName"),s.assertTrue(s.isFunction(n),"cb must be a function"),c.topic.has(e)?c.topic.get(e).add(n):c.topic.set(e,new Set([n])),function(){return c.topic.get(e).delete(n)}},this.onAllMessage=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.allMessage.add(e),function(){return c.allMessage.delete(e)}},this.subscribeTopics=function(e){s.assertNotNull(e,"topics"),s.assertIsList(e),e.forEach(function(e){u.subscribed.has(e)||u.pending.add(e)}),l.consecutiveNoResponseRequest=0,R()},this.sendMessage=function(n){if(s.assertIsObject(n,"payload"),void 0===n.topic||m.has(n.topic))q(e.warn("Cannot send message, Invalid topic",n));else{try{n=JSON.stringify(n)}catch(t){return void q(e.warn("Error stringify message",n))}O()?T().send(n):q(e.warn("Cannot send message, web socket connection is not open"))}},this.closeWebSocket=function(){W(),N(),o.reconnectWebSocket=!1,clearInterval(y),M("User request to close WebSocket")},this.terminateWebSocketManager=D},L={create:function(){return new E},setGlobalConfig:function(e){var n=e.loggerConfig;_.updateLoggerConfig(n)},LogLevel:T,Logger:C}},function(e,n,t){var o;!function(){"use strict";var r={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function i(e){return function(e,n){var t,o,c,s,a,u,l,f,p,d=1,b=e.length,g="";for(o=0;o=0),s.type){case"b":t=parseInt(t,10).toString(2);break;case"c":t=String.fromCharCode(parseInt(t,10));break;case"d":case"i":t=parseInt(t,10);break;case"j":t=JSON.stringify(t,null,s.width?parseInt(s.width):0);break;case"e":t=s.precision?parseFloat(t).toExponential(s.precision):parseFloat(t).toExponential();break;case"f":t=s.precision?parseFloat(t).toFixed(s.precision):parseFloat(t);break;case"g":t=s.precision?String(Number(t.toPrecision(s.precision))):parseFloat(t);break;case"o":t=(parseInt(t,10)>>>0).toString(8);break;case"s":t=String(t),t=s.precision?t.substring(0,s.precision):t;break;case"t":t=String(!!t),t=s.precision?t.substring(0,s.precision):t;break;case"T":t=Object.prototype.toString.call(t).slice(8,-1).toLowerCase(),t=s.precision?t.substring(0,s.precision):t;break;case"u":t=parseInt(t,10)>>>0;break;case"v":t=t.valueOf(),t=s.precision?t.substring(0,s.precision):t;break;case"x":t=(parseInt(t,10)>>>0).toString(16);break;case"X":t=(parseInt(t,10)>>>0).toString(16).toUpperCase()}r.json.test(s.type)?g+=t:(!r.number.test(s.type)||f&&!s.sign?p="":(p=f?"+":"-",t=t.toString().replace(r.sign,"")),u=s.pad_char?"0"===s.pad_char?"0":s.pad_char.charAt(1):" ",l=s.width-(p+t).length,a=s.width&&l>0?u.repeat(l):"",g+=s.align?p+t+a:"0"===u?p+a+t:a+p+t)}return g}(function(e){if(s[e])return s[e];var n,t=e,o=[],i=0;for(;t;){if(null!==(n=r.text.exec(t)))o.push(n[0]);else if(null!==(n=r.modulo.exec(t)))o.push("%");else{if(null===(n=r.placeholder.exec(t)))throw new SyntaxError("[sprintf] unexpected placeholder");if(n[2]){i|=1;var c=[],a=n[2],u=[];if(null===(u=r.key.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(c.push(u[1]);""!==(a=a.substring(u[0].length));)if(null!==(u=r.key_access.exec(a)))c.push(u[1]);else{if(null===(u=r.index_access.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");c.push(u[1])}n[2]=c}else i|=2;if(3===i)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");o.push({placeholder:n[0],param_no:n[1],keys:n[2],sign:n[3],pad_char:n[4],align:n[5],width:n[6],precision:n[7],type:n[8]})}t=t.substring(n[0].length)}return s[e]=o}(e),arguments)}function c(e,n){return i.apply(null,[e].concat(n||[]))}var s=Object.create(null);n.sprintf=i,n.vsprintf=c,"undefined"!=typeof window&&(window.sprintf=i,window.vsprintf=c,void 0===(o=function(){return{sprintf:i,vsprintf:c}}.call(n,t,n,e))||(e.exports=o))}()},function(e,n,t){"use strict";t.r(n),function(e){t.d(n,"WebSocketManager",function(){return r});var o=t(0);e.connect=e.connect||{},connect.WebSocketManager=o.a;var r=o.a}.call(this,t(3))},function(e,n){var t;t=function(){return this}();try{t=t||new Function("return this")()}catch(e){"object"==typeof window&&(t=window)}e.exports=t}]); +//# sourceMappingURL=amazon-connect-websocket-manager.js.map + /* * Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * @@ -24568,7 +25275,7 @@ connect.core = {}; connect.core.initialized = false; - connect.version = "1.5.2"; + connect.version = "1.6.0"; connect.DEFAULT_BATCH_SIZE = 500; var CCP_SYN_TIMEOUT = 1000; // 1 sec @@ -24650,7 +25357,7 @@ connect.core.checkNotInitialized = function () { if (connect.core.initialized) { var log = connect.getLog(); - log.warn("Connect core already initialized, only needs to be initialized once."); + log.warn("Connect core already initialized, only needs to be initialized once.").sendInternalLogToServer(); } }; @@ -24662,6 +25369,7 @@ connect.core.eventBus = new connect.EventBus(); connect.core.agentDataProvider = new AgentDataProvider(connect.core.getEventBus()); connect.core.initClient(params); + connect.core.initAgentAppClient(params); connect.core.initialized = true; }; @@ -24680,11 +25388,26 @@ connect.core.client = new connect.AWSClient(authToken, region, endpoint); }; + /**------------------------------------------------------------------------- + * Initialized AgentApp client + * Should be used by Shared Worker to update AgentApp client with new credentials + * after refreshed authentication. + */ + connect.core.initAgentAppClient = function (params) { + connect.assertNotNull(params, 'params'); + var authToken = connect.assertNotNull(params.authToken, 'params.authToken'); + var authCookieName = connect.assertNotNull(params.authCookieName, 'params.authCookieName'); + var endpoint = connect.assertNotNull(params.agentAppEndpoint, 'params.agentAppEndpoint'); + + connect.core.agentAppClient = new connect.AgentAppClient(authCookieName, authToken, endpoint); + }; + /**------------------------------------------------------------------------- * Uninitialize Connect. */ connect.core.terminate = function () { connect.core.client = new connect.NullClient(); + connect.core.agentAppClient = new connect.NullClient(); connect.core.masterClient = new connect.NullClient(); var bus = connect.core.getEventBus(); if (bus) bus.unsubscribeAll(); @@ -24729,18 +25452,24 @@ if (!ringtoneSettings.voice.disabled && !connect.core.ringtoneEngines.voice) { connect.core.ringtoneEngines.voice = new connect.VoiceRingtoneEngine(ringtoneSettings.voice); - connect.getLog().info("VoiceRingtoneEngine initialized."); + connect.getLog().info("VoiceRingtoneEngine initialized.").sendInternalLogToServer(); } if (!ringtoneSettings.chat.disabled && !connect.core.ringtoneEngines.chat) { connect.core.ringtoneEngines.chat = new connect.ChatRingtoneEngine(ringtoneSettings.chat); - connect.getLog().info("ChatRingtoneEngine initialized."); + connect.getLog().info("ChatRingtoneEngine initialized.").sendInternalLogToServer(); + } + + if (!ringtoneSettings.task.disabled && !connect.core.ringtoneEngines.task) { + connect.core.ringtoneEngines.task = + new connect.TaskRingtoneEngine(ringtoneSettings.task); + connect.getLog().info("TaskRingtoneEngine initialized.").sendInternalLogToServer(); } if (!ringtoneSettings.queue_callback.disabled && !connect.core.ringtoneEngines.queue_callback) { connect.core.ringtoneEngines.queue_callback = new connect.QueueCallbackRingtoneEngine(ringtoneSettings.queue_callback); - connect.getLog().info("QueueCallbackRingtoneEngine initialized."); + connect.getLog().info("QueueCallbackRingtoneEngine initialized.").sendInternalLogToServer(); } }); }); @@ -24754,6 +25483,8 @@ params.ringtone.voice = params.ringtone.voice || {}; params.ringtone.queue_callback = params.ringtone.queue_callback || {}; params.ringtone.chat = params.ringtone.chat || { disabled: true }; + params.ringtone.task = params.ringtone.task || { disabled: true }; + if (otherParams.softphone) { if (otherParams.softphone.disableRingtone) { params.ringtone.voice.disabled = true; @@ -24936,6 +25667,8 @@ ? LEGACY_AUTHORIZE_ENDPOINT : AUTHORIZE_ENDPOINT; } + var agentAppEndpoint = params.agentAppEndpoint || null; + var authCookieName = params.authCookieName || null; try { // Initialize the event bus and agent data providers. @@ -24960,6 +25693,7 @@ }; connect.getLog().scheduleUpstreamLogPush(conduit); + connect.getLog().scheduleDownstreamClientSideLogsPush(); // Bridge all upstream messages into the event bus. conduit.onAllUpstream(connect.core.getEventBus().bridge()); // Bridge all downstream messages into the event bus. @@ -24976,11 +25710,13 @@ endpoint: endpoint, refreshToken: refreshToken, region: region, - authorizeEndpoint: authorizeEndpoint + authorizeEndpoint: authorizeEndpoint, + agentAppEndpoint: agentAppEndpoint, + authCookieName: authCookieName }); conduit.onUpstream(connect.EventType.ACKNOWLEDGE, function () { - connect.getLog().info("Acknowledged by the ConnectSharedWorker!"); + connect.getLog().info("Acknowledged by the ConnectSharedWorker!").sendInternalLogToServer(); connect.core.initialized = true; this.unsubscribe(); }); @@ -24990,6 +25726,11 @@ connect.getLog().addLogEntry(connect.LogEntry.fromObject(logEntry)); } }); + conduit.onUpstream(connect.EventType.SERVER_BOUND_INTERNAL_LOG, function (logEntry) { + if (logEntry.loggerId !== connect.getLog().getLoggerId()) { + connect.getLog().sendInternalLogEntryToServer(connect.LogEntry.fromObject(logEntry)); + } + }); // Reload the page if the shared worker detects an API auth failure. conduit.onUpstream(connect.EventType.AUTH_FAIL, function (logEntry) { location.reload(); @@ -25016,7 +25757,7 @@ } catch (e) { connect.getLog().error("Failed to initialize the API shared worker, we're dead!") - .withException(e); + .withException(e).sendInternalLogToServer(); } }; @@ -25093,7 +25834,7 @@ // Once we receive the first ACK, setup our upstream API client and establish // the SYN/ACK refresh flow. conduit.onUpstream(connect.EventType.ACKNOWLEDGE, function () { - connect.getLog().info("Acknowledged by the CCP!"); + connect.getLog().info("Acknowledged by the CCP!").sendInternalLogToServer(); connect.core.client = new connect.UpstreamConduitClient(conduit); connect.core.masterClient = new connect.UpstreamConduitMasterClient(conduit); connect.core.initialized = true; @@ -25121,6 +25862,11 @@ connect.getLog().addLogEntry(connect.LogEntry.fromObject(logEntry)); } }); + conduit.onUpstream(connect.EventType.SERVER_BOUND_INTERNAL_LOG, function (logEntry) { + if (logEntry.loggerId !== connect.getLog().getLoggerId()) { + connect.getLog().sendInternalLogEntryToServer(connect.LogEntry.fromObject(logEntry)); + } + }); // Pop a login page when we encounter an ACK timeout. connect.core.getEventBus().subscribe(connect.EventType.ACK_TIMEOUT, function () { @@ -25128,14 +25874,14 @@ if (params.loginPopup !== false) { try { var loginUrl = getLoginUrl(params); - connect.getLog().warn("ACK_TIMEOUT occurred, attempting to pop the login page if not already open."); + connect.getLog().warn("ACK_TIMEOUT occurred, attempting to pop the login page if not already open.").sendInternalLogEntryToServer(); // clear out last opened timestamp for SAML authentication when there is ACK_TIMEOUT if (params.loginUrl) { connect.core.getPopupManager().clear(connect.MasterTopics.LOGIN_POPUP); } connect.core.loginWindow = connect.core.getPopupManager().open(loginUrl, connect.MasterTopics.LOGIN_POPUP, params.loginOptions); } catch (e) { - connect.getLog().error("ACK_TIMEOUT occurred but we are unable to open the login popup.").withException(e); + connect.getLog().error("ACK_TIMEOUT occurred but we are unable to open the login popup.").withException(e).sendInternalLogToServer(); } } @@ -25395,6 +26141,14 @@ return connectionData; }; + + AgentDataProvider.prototype.getInstanceId = function(){ + return this.getAgentData().configuration.routingProfile.routingProfileId.match(/instance\/([0-9a-fA-F|-]+)\//)[1]; + } + + AgentDataProvider.prototype.getAWSAccountId = function(){ + return this.getAgentData().configuration.routingProfile.routingProfileId.match(/:([0-9]+):instance/)[1]; + } AgentDataProvider.prototype._diffContacts = function (oldAgentData) { var diff = { @@ -25642,7 +26396,10 @@ connect.ContactEvents.ENDED) .assoc(connect.EventGraph.ANY, connect.values(connect.AgentErrorStates), - connect.ContactEvents.ERROR); + connect.ContactEvents.ERROR) + .assoc(connect.ContactStateType.CONNECTING, + connect.ContactStateType.MISSED, + connect.ContactEvents.MISSED); /**-----------------------------------------------------------------------*/ connect.core.getClient = function () { @@ -25653,6 +26410,15 @@ }; connect.core.client = null; + /**-----------------------------------------------------------------------*/ + connect.core.getAgentAppClient = function () { + if (!connect.core.agentAppClient) { + throw new connect.StateError('The connect AgentApp Client has not been initialized!'); + } + return connect.core.agentAppClient; + }; + connect.core.agentAppClient = null; + /**-----------------------------------------------------------------------*/ connect.core.getMasterClient = function () { if (!connect.core.masterClient) { @@ -25696,6 +26462,7 @@ connect.core.AgentDataProvider = AgentDataProvider; })(); + /* * Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * @@ -25728,7 +26495,7 @@ } else { this._audio = null; - connect.getLog().error("Unable to provide a ringtone."); + connect.getLog().error("Unable to provide a ringtone.").sendInternalLogToServer(); } self._driveRingtone(); @@ -25869,6 +26636,28 @@ }); }; + var TaskRingtoneEngine = function (ringtoneConfig) { + RingtoneEngineBase.call(this, ringtoneConfig); + }; + TaskRingtoneEngine.prototype = Object.create(RingtoneEngineBase.prototype); + TaskRingtoneEngine.prototype.constructor = TaskRingtoneEngine; + + TaskRingtoneEngine.prototype._driveRingtone = function () { + var self = this; + + var onContactConnect = function (contact) { + if (contact.getType() === lily.ContactType.TASK && contact.isInbound()) { + self._ringtoneSetup(contact); + self._publishTelemetryEvent("Task Ringtone Connecting", contact); + } + }; + + connect.contact(function (contact) { + contact.onConnecting(onContactConnect); + }); + }; + + var QueueCallbackRingtoneEngine = function (ringtoneConfig) { RingtoneEngineBase.call(this, ringtoneConfig); }; @@ -25891,6 +26680,7 @@ /* export connect.RingtoneEngine */ connect.VoiceRingtoneEngine = VoiceRingtoneEngine; connect.ChatRingtoneEngine = ChatRingtoneEngine; + connect.TaskRingtoneEngine = TaskRingtoneEngine; connect.QueueCallbackRingtoneEngine = QueueCallbackRingtoneEngine; })(); @@ -26016,7 +26806,7 @@ delete callsDetected[agentConnectionId]; session.hangup(); }).catch(function (err) { - lily.getLog().warn("Clean up the session locally " + agentConnectionId, err.message); + lily.getLog().warn("Clean up the session locally " + agentConnectionId, err.message).sendInternalLogToServer(); }); } }; @@ -26056,7 +26846,7 @@ // Set to true, this will block subsequent invokes from entering. callsDetected[agentConnectionId] = true; - logger.info("Softphone call detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId); + logger.info("Softphone call detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId).sendInternalLogToServer(); // Ensure our session state matches our contact state to prevent issues should we lose track of a contact. sanityCheckActiveSessions(rtcSessions); @@ -26148,7 +26938,7 @@ var onInitContact = function (contact) { var agentConnectionId = contact.getAgentConnection().connectionId; - logger.info("Contact detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId); + logger.info("Contact detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId).sendInternalLogToServer(); if (!callsDetected[agentConnectionId]) { contact.onRefresh(function () { @@ -26162,7 +26952,8 @@ // Contact already in connecting state scenario - In this case contact INIT is missed hence the OnRefresh callback is missed. new connect.Agent().getContacts().forEach(function (contact) { var agentConnectionId = contact.getAgentConnection().connectionId; - logger.info("Contact exist in the snapshot. Reinitiate the Contact and RTC session creation for contactId" + contact.getContactId(), "agent connectionId " + agentConnectionId); + logger.info("Contact exist in the snapshot. Reinitiate the Contact and RTC session creation for contactId" + contact.getContactId(), "agent connectionId " + agentConnectionId) + .sendInternalLogToServer(); onInitContact(contact); onRefreshContact(contact, agentConnectionId); }); @@ -26172,24 +26963,26 @@ var conduit = connect.core.getUpstream(); var agentConnection = contact.getAgentConnection(); if (!agentConnection) { - logger.info("Not able to retrieve the auto-accept setting from null AgentConnection, ignoring event publish.."); + logger.info("Not able to retrieve the auto-accept setting from null AgentConnection, ignoring event publish..").sendInternalLogToServer(); return; } var softphoneMediaInfo = agentConnection.getSoftphoneMediaInfo(); if (!softphoneMediaInfo) { - logger.info("Not able to retrieve the auto-accept setting from null SoftphoneMediaInfo, ignoring event publish.."); + logger.info("Not able to retrieve the auto-accept setting from null SoftphoneMediaInfo, ignoring event publish..").sendInternalLogToServer(); return; } if (softphoneMediaInfo.autoAccept === true) { - logger.info("Auto-accept is enabled, sending out Accepted event to stop ringtone.."); + logger.info("Auto-accept is enabled, sending out Accepted event to stop ringtone..").sendInternalLogToServer(); conduit.sendUpstream(connect.EventType.BROADCAST, { - event: connect.ContactEvents.ACCEPTED + event: connect.ContactEvents.ACCEPTED, + data: new connect.Contact(contact.contactId) }); conduit.sendUpstream(connect.EventType.BROADCAST, { - event: connect.core.getContactEventName(connect.ContactEvents.ACCEPTED, contact.contactId) + event: connect.core.getContactEventName(connect.ContactEvents.ACCEPTED, contact.contactId), + data: new connect.Contact(contact.contactId) }); } else { - logger.info("Auto-accept is disabled, ringtone will be stopped by user action."); + logger.info("Auto-accept is disabled, ringtone will be stopped by user action.").sendInternalLogToServer(); } }; @@ -26230,9 +27023,9 @@ localMediaStream[connectionId].muted = status; if (status) { - logger.info("Agent has muted the contact, connectionId - " + connectionId); + logger.info("Agent has muted the contact, connectionId - " + connectionId).sendInternalLogToServer(); } else { - logger.info("Agent has unmuted the contact, connectionId - " + connectionId); + logger.info("Agent has unmuted the contact, connectionId - " + connectionId).sendInternalLogToServer(); } } else { @@ -26275,7 +27068,7 @@ rtcSession._signalingUri); } else if (reason === connect.RTCErrors.CALL_NOT_FOUND) { // No need to publish any softphone error for this case. CCP UX will handle this case. - logger.error("Softphone call failed due to CallNotFoundException."); + logger.error("Softphone call failed due to CallNotFoundException.").sendInternalLogToServer(); } else { publishError(SoftphoneErrorTypes.WEBRTC_ERROR, "webrtc system error. ", @@ -26335,7 +27128,7 @@ var publishError = function (errorType, message, endPointUrl) { logger.error("Softphone error occurred : ", errorType, - message || ""); + message || "").sendInternalLogToServer(); connect.core.getUpstream().sendUpstream(connect.EventType.BROADCAST, { event: connect.AgentEvents.SOFTPHONE_ERROR, @@ -26365,7 +27158,8 @@ name: "AgentConnectionId", value: agentConnectionId }]); - logger.info("Publish multiple session error metrics", eventName, "contactId " + contactId, "agent connectionId " + agentConnectionId); + logger.info("Publish multiple session error metrics", eventName, "contactId " + contactId, "agent connectionId " + agentConnectionId) + .sendInternalLogToServer(); }; var isBrowserSoftPhoneSupported = function () { @@ -26391,11 +27185,13 @@ if (streamStats.length > 0) { contact.sendSoftphoneMetrics(streamStats, { success: function () { - logger.info("sendSoftphoneMetrics success" + JSON.stringify(streamStats)); + logger.info("sendSoftphoneMetrics success" + JSON.stringify(streamStats)) + .sendInternalLogToServer(); }, failure: function (data) { logger.error("sendSoftphoneMetrics failed.") - .withObject(data); + .withObject(data) + .sendInternalLogToServer(); } }); } @@ -26430,11 +27226,13 @@ }; contact.sendSoftphoneReport(callReport, { success: function () { - logger.info("sendSoftphoneReport success" + JSON.stringify(callReport)); + logger.info("sendSoftphoneReport success" + JSON.stringify(callReport)) + .sendInternalLogToServer(); }, failure: function (data) { logger.error("sendSoftphoneReport failed.") - .withObject(data); + .withObject(data) + .sendInternalLogToServer(); } }); }; @@ -26446,14 +27244,14 @@ aggregatedUserAudioStats = stats; timeSeriesStreamStatsBuffer.push(getTimeSeriesStats(aggregatedUserAudioStats, previousUserStats, AUDIO_INPUT)); }, function (error) { - logger.debug("Failed to get user audio stats.", error); + logger.debug("Failed to get user audio stats.", error).sendInternalLogToServer(); }); rtcSession.getRemoteAudioStats().then(function (stats) { var previousRemoteStats = aggregatedRemoteAudioStats; aggregatedRemoteAudioStats = stats; timeSeriesStreamStatsBuffer.push(getTimeSeriesStats(aggregatedRemoteAudioStats, previousRemoteStats, AUDIO_OUTPUT)); }, function (error) { - logger.debug("Failed to get remote audio stats.", error); + logger.debug("Failed to get remote audio stats.", error).sendInternalLogToServer(); }); }, 1000); }; @@ -26538,25 +27336,25 @@ args.forEach(function () { format = format + " %s"; }); - method.apply(self._originalLogger, [connect.LogComponent.SOFTPHONE, format].concat(args)); + return method.apply(self._originalLogger, [connect.LogComponent.SOFTPHONE, format].concat(args)); }; }; }; SoftphoneLogger.prototype.debug = function () { - this._tee(1, this._originalLogger.debug)(arguments); + return this._tee(1, this._originalLogger.debug)(arguments); }; SoftphoneLogger.prototype.info = function () { - this._tee(2, this._originalLogger.info)(arguments); + return this._tee(2, this._originalLogger.info)(arguments); }; SoftphoneLogger.prototype.log = function () { - this._tee(3, this._originalLogger.log)(arguments); + return this._tee(3, this._originalLogger.log)(arguments); }; SoftphoneLogger.prototype.warn = function () { - this._tee(4, this._originalLogger.warn)(arguments); + return this._tee(4, this._originalLogger.warn)(arguments); }; SoftphoneLogger.prototype.error = function () { - this._tee(5, this._originalLogger.error)(arguments); + return this._tee(5, this._originalLogger.error)(arguments); }; connect.SoftphoneManager = SoftphoneManager; @@ -26626,23 +27424,37 @@ WorkerClient.prototype._callImpl = function (method, params, callbacks) { var self = this; var request_start = new Date().getTime(); - connect.core.getClient()._callImpl(method, params, { - success: function (data) { - self._recordAPILatency(method, request_start); - callbacks.success(data); - }, - failure: function (error, data) { - self._recordAPILatency(method, request_start, error); - callbacks.failure(error, data); - }, - authFailure: function () { - self._recordAPILatency(method, request_start); - callbacks.authFailure(); - }, - accessDenied: function () { - callbacks.accessDenied && callbacks.accessDenied(); - } - }); + if(connect.containsValue(connect.AgentAppClientMethods, method)) { + connect.core.getAgentAppClient()._callImpl(method, params, { + success: function (data) { + self._recordAPILatency(method, request_start); + callbacks.success(data); + }, + failure: function (error, data) { + self._recordAPILatency(method, request_start, error); + callbacks.failure(error, data); + } + }) + } else { + connect.core.getClient()._callImpl(method, params, { + success: function (data) { + self._recordAPILatency(method, request_start); + callbacks.success(data); + }, + failure: function (error, data) { + self._recordAPILatency(method, request_start, error); + callbacks.failure(error, data); + }, + authFailure: function () { + self._recordAPILatency(method, request_start); + callbacks.authFailure(); + }, + accessDenied: function () { + callbacks.accessDenied && callbacks.accessDenied(); + } + }); + } + }; WorkerClient.prototype._recordAPILatency = function (method, request_start, err) { @@ -26705,7 +27517,8 @@ // init only once. if (!webSocketManager) { - connect.getLog().info("Creating a new Websocket connection for CCP"); + connect.getLog().info("Creating a new Websocket connection for CCP") + .sendInternalLogToServer(); connect.WebSocketManager.setGlobalConfig({ loggerConfig: { logger: connect.getLog() } @@ -26758,13 +27571,16 @@ webSocketManager.init(connect.hitch(self, self.getWebSocketUrl)).then(function(response) { if (response && !response.webSocketConnectionFailed) { // Start polling for agent data. - connect.getLog().info("Kicking off agent polling"); + connect.getLog().info("Kicking off agent polling") + .sendInternalLogToServer(); self.pollForAgent(); - connect.getLog().info("Kicking off config polling"); + connect.getLog().info("Kicking off config polling") + .sendInternalLogToServer(); self.pollForAgentConfiguration({ repeatForever: true }); - connect.getLog().info("Kicking off auth token polling"); + connect.getLog().info("Kicking off auth token polling") + .sendInternalLogToServer(); global.setInterval(connect.hitch(self, self.checkAuthToken), CHECK_AUTH_TOKEN_INTERVAL_MS); } else { if (!connect.webSocketInitFailed) { @@ -26774,7 +27590,8 @@ } }); } else { - connect.getLog().info("Not Creating a Websocket instance, since there's already one exist"); + connect.getLog().info("Not Initializing a new WebsocketManager instance, since one already exists") + .sendInternalLogToServer(); } } }); @@ -26839,10 +27656,15 @@ self.agent.snapshot.localTimestamp = connect.now(); self.agent.snapshot.skew = self.agent.snapshot.snapshotTimestamp - self.agent.snapshot.localTimestamp; self.nextToken = data.nextToken; - connect.getLog().trace("GET_AGENT_SNAPSHOT succeeded.").withObject(data); + connect.getLog().trace("GET_AGENT_SNAPSHOT succeeded.") + .withObject(data) + .sendInternalLogToServer(); self.updateAgent(); } catch (e) { - connect.getLog().error("Long poll failed to update agent.").withObject(data).withException(e); + connect.getLog().error("Long poll failed to update agent.") + .withObject(data) + .withException(e) + .sendInternalLogToServer(); } finally { global.setTimeout(connect.hitch(self, self.pollForAgent), GET_AGENT_SUCCESS_TIMEOUT_MS); } @@ -26850,6 +27672,7 @@ failure: function (err, data) { try { connect.getLog().error("Failed to get agent data.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -26888,6 +27711,7 @@ failure: function (err, data) { try { connect.getLog().error("Failed to fetch agent configuration data.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -26931,6 +27755,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch agent states list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -26966,6 +27791,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch agent permissions list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -27000,6 +27826,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch dialable country codes list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -27035,6 +27862,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch routing profile queues list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -27057,7 +27885,9 @@ var response = connect.EventFactory.createResponse(connect.EventType.API_RESPONSE, request, data, JSON.stringify(err)); portConduit.sendDownstream(response.event, response); connect.getLog().error("'%s' API request failed", request.method) - .withObject({ request: self.filterAuthToken(request), response: response }).withException(err); + .withObject({ request: self.filterAuthToken(request), response: response }) + .withException(err) + .sendInternalLogToServer(); }, authFailure: connect.hitch(self, self.handleAuthFail) }); @@ -27113,19 +27943,23 @@ this.updateAgent(); } else { - connect.getLog().trace("Waiting to update agent configuration until all config data has been fetched."); + connect.getLog().trace("Waiting to update agent configuration until all config data has been fetched.") + .sendInternalLogToServer(); } }; ClientEngine.prototype.updateAgent = function () { if (!this.agent) { - connect.getLog().trace("Waiting to update agent until the agent has been fully constructed."); + connect.getLog().trace("Waiting to update agent until the agent has been fully constructed.") + .sendInternalLogToServer(); } else if (!this.agent.snapshot) { - connect.getLog().trace("Waiting to update agent until the agent snapshot is available."); + connect.getLog().trace("Waiting to update agent until the agent snapshot is available.") + .sendInternalLogToServer(); } else if (!this.agent.configuration) { - connect.getLog().trace("Waiting to update agent until the agent configuration is available."); + connect.getLog().trace("Waiting to update agent until the agent configuration is available.") + .sendInternalLogToServer(); } else { // Alias some of the properties for backwards compatibility. @@ -27176,11 +28010,12 @@ return new Promise(function (resolve, reject) { client.call(connect.ClientMethods.CREATE_TRANSPORT, { transportType: connect.TRANSPORT_TYPES.WEB_SOCKET }, { success: function (data) { - connect.getLog().info("getWebSocketUrl succeeded"); + connect.getLog().info("getWebSocketUrl succeeded").sendInternalLogToServer(); resolve(data); }, failure: function (err, data) { connect.getLog().error("getWebSocketUrl failed") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -27188,12 +28023,12 @@ reject(Error("getWebSocketUrl failed")); }, authFailure: function () { - connect.getLog().error("getWebSocketUrl Auth Failure"); + connect.getLog().error("getWebSocketUrl Auth Failure").sendInternalLogToServer(); reject(Error("Authentication failed while getting getWebSocketUrl")); onAuthFail(); }, accessDenied: function () { - connect.getLog().error("getWebSocketUrl Access Denied Failure"); + connect.getLog().error("getWebSocketUrl Access Denied Failure").sendInternalLogToServer(); reject(Error("Access Denied Failure while getting getWebSocketUrl")); onAccessDenied(); } @@ -27220,10 +28055,12 @@ }); this.client.call(connect.ClientMethods.SEND_CLIENT_LOGS, { logEvents: logEvents }, { success: function (data) { - connect.getLog().info("SendLogs request succeeded."); + connect.getLog().info("SendLogs request succeeded.").sendInternalLogToServer(); }, failure: function (err, data) { - connect.getLog().error("SendLogs request failed.").withObject(data).withException(err); + connect.getLog().error("SendLogs request failed.") + .withObject(data).withException(err) + .sendInternalLogToServer(); }, authFailure: connect.hitch(self, self.handleAuthFail) }); @@ -27247,7 +28084,8 @@ // refresh token 30 minutes before expiration if (expirationDate.getTime() < (currentTimeStamp + thirtyMins)) { - connect.getLog().info("Auth token expires at " + expirationDate + " Start refreshing token with retry."); + connect.getLog().info("Auth token expires at " + expirationDate + " Start refreshing token with retry.") + .sendInternalLogToServer(); connect.backoff(connect.hitch(self, self.authorize), REFRESH_AUTH_TOKEN_INTERVAL_MS, REFRESH_AUTH_TOKEN_MAX_TRY); } }; @@ -27257,13 +28095,16 @@ var self = this; connect.core.authorize(this.initData.authorizeEndpoint).then(function (response) { var expiration = new Date(response.expiration); - connect.getLog().info("Authorization succeeded and the token expires at %s", expiration); + connect.getLog().info("Authorization succeeded and the token expires at %s", expiration) + .sendInternalLogToServer(); self.initData.authToken = response.accessToken; self.initData.authTokenExpiration = expiration; connect.core.initClient(self.initData); + connect.core.initAgentAppClient(self.initData); callbacks.success(); }).catch(function (response) { - connect.getLog().error("Authorization failed with code %s", response.status); + connect.getLog().error("Authorization failed with code %s", response.status) + .sendInternalLogToServer(); if (response.status === 401) { self.handleAuthFail(); } else { @@ -27329,7 +28170,8 @@ var createMediaInstance = function () { publishTelemetryEvent("Chat media controller init", mediaInfo.contactId); - logger.info(logComponent, "Chat media controller init").withObject(mediaInfo); + logger.info(logComponent, "Chat media controller init") + .withObject(mediaInfo).sendInternalLogToServer(); connect.ChatSession.setGlobalConfig({ loggerConfig: { @@ -27349,12 +28191,14 @@ return controller .connect() .then(function (data) { - logger.info(logComponent, "Chat Session Successfully established for contactId %s", mediaInfo.contactId); + logger.info(logComponent, "Chat Session Successfully established for contactId %s", mediaInfo.contactId) + .sendInternalLogToServer(); publishTelemetryEvent("Chat Session Successfully established", mediaInfo.contactId); return controller; }) .catch(function (error) { - logger.error(logComponent, "Chat Session establishement failed for contact %s", mediaInfo.contactId).withException(error); + logger.error(logComponent, "Chat Session establishement failed for contact %s", mediaInfo.contactId) + .withException(error).sendInternalLogToServer(); publishTelemetryEvent("Chat Session establishement failed", mediaInfo.contactId, error); throw error; }); @@ -27370,12 +28214,14 @@ var trackChatConnectionStatus = function (controller) { controller.onConnectionBroken(function (data) { - logger.error(logComponent, "Chat Session connection broken").withException(data); + logger.error(logComponent, "Chat Session connection broken") + .withException(data).sendInternalLogToServer(); publishTelemetryEvent("Chat Session connection broken", data); }); controller.onConnectionEstablished(function (data) { - logger.info(logComponent, "Chat Session connection established").withObject(data); + logger.info(logComponent, "Chat Session connection established") + .withObject(data).sendInternalLogToServer(); publishTelemetryEvent("Chat Session connection established", data); }); } @@ -27411,11 +28257,12 @@ connect.MediaFactory = function (params) { /** controller holder */ var mediaControllers = {}; + var toBeDestroyed = new Set(); var logger = connect.getLog(); var logComponent = connect.LogComponent.CHAT; - var metadata = params || {}; + var metadata = connect.merge({}, params) || {}; metadata.region = metadata.region || "us-west-2"; // Default it to us-west-2 var getMediaController = function (connectionObj) { @@ -27423,19 +28270,24 @@ var mediaInfo = connectionObj.getMediaInfo(); /** if we do not have the media info then just reject the request */ if (!mediaInfo) { - logger.error(logComponent, "Media info does not exists for a media type %s").withObject(connectionObj); + logger.error(logComponent, "Media info does not exists for a media type %s") + .withObject(connectionObj).sendInternalLogToServer(); return Promise.reject("Media info does not exists for this connection"); } if (!mediaControllers[connectionId]) { - logger.info(logComponent, "media controller of type %s init", connectionObj.getMediaType()).withObject(connectionObj); + logger.info(logComponent, "media controller of type %s init", connectionObj.getMediaType()) + .withObject(connectionObj).sendInternalLogToServer(); switch (connectionObj.getMediaType()) { case connect.MediaType.CHAT: return mediaControllers[connectionId] = new connect.ChatMediaController(connectionObj.getMediaInfo(), metadata).get(); case connect.MediaType.SOFTPHONE: return mediaControllers[connectionId] = new connect.SoftphoneMediaController(connectionObj.getMediaInfo()).get(); + case connect.MediaType.TASK: + return mediaControllers[connectionId] = new connect.TaskMediaController(connectionObj.getMediaInfo()).get(); default: - logger.error(logComponent, "Unrecognized media type %s ", connectionObj.getMediaType()); + logger.error(logComponent, "Unrecognized media type %s ", connectionObj.getMediaType()) + .sendInternalLogToServer(); return Promise.reject(); } } else { @@ -27458,9 +28310,23 @@ }; var destroy = function (connectionId) { - if (mediaControllers[connectionId]) { - logger.info(logComponent, "Destroying mediaController for %s", connectionId); - delete mediaControllers[connectionId]; + if (mediaControllers[connectionId] && !toBeDestroyed.has(connectionId)) { + logger.info( + logComponent, + "Destroying mediaController for %s", + connectionId + ); + toBeDestroyed.add(connectionId); + mediaControllers[connectionId] + .then(function() { + if (typeof controller.cleanUp === "function") controller.cleanUp(); + delete mediaControllers[connectionId]; + toBeDestroyed.delete(connectionId); + }) + .catch(function() { + delete mediaControllers[connectionId]; + toBeDestroyed.delete(connectionId); + }); } }; @@ -27500,3 +28366,268 @@ } } })(); + +/* + * Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Amazon Software License (the "License"). You may not use + * this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/asl/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +(function () { + var global = this; + connect = global.connect || {}; + global.connect = connect; + + connect.TaskMediaController = function (mediaInfo) { + var logger = connect.getLog(); + var logComponent = connect.LogComponent.TASK; + + var createMediaInstance = function () { + publishTelemetryEvent("Task media controller init", mediaInfo.contactId); + logger + .info(logComponent, "Task media controller init") + .withObject(mediaInfo); + + var controller = connect.TaskSession.create({ + contactId: mediaInfo.contactId, + initialContactId: mediaInfo.initialContactId, + websocketManager: connect.core.getWebSocketManager(), + }); + + trackTaskConnectionStatus(controller); + + return controller + .connect() + .then(function () { + logger.info( + logComponent, + "Task Session Successfully established for contactId %s", + mediaInfo.contactId + ); + publishTelemetryEvent( + "Task Session Successfully established", + mediaInfo.contactId + ); + return controller; + }) + .catch(function (error) { + logger + .error( + logComponent, + "Task Session establishement failed for contact %s", + mediaInfo.contactId + ) + .withException(error); + publishTelemetryEvent( + "Chat Session establishement failed", + mediaInfo.contactId, + error + ); + throw error; + }); + }; + + var publishTelemetryEvent = function (eventName, data) { + connect.publishMetric({ + name: eventName, + contactId: mediaInfo.contactId, + data: data || mediaInfo, + }); + }; + + var trackTaskConnectionStatus = function (controller) { + controller.onConnectionBroken(function (data) { + logger + .error(logComponent, "Task Session connection broken") + .withException(data); + publishTelemetryEvent("Task Session connection broken", data); + }); + + controller.onConnectionEstablished(function (data) { + logger + .info(logComponent, "Task Session connection established") + .withObject(data); + publishTelemetryEvent("Task Session connection established", data); + }); + }; + + return { + get: function () { + return createMediaInstance(); + }, + }; + }; +})(); + +(function () { + var global = this; + connect = global.connect || {}; + global.connect = connect; + global.lily = connect; + + connect.agentApp = {}; + + var IFRAME_REFRESH_INTERVAL = 5000; + var APP = { + CCP: 'ccp', + }; + + connect.agentApp.initCCP = connect.core.initCCP; + connect.agentApp.isInitialized = function (instanceAlias) {}; + + connect.agentApp.initAppCommunication = function (iframeId, endpoint) { + var iframe = document.getElementById(iframeId); + var iframeConduit = new connect.IFrameConduit(endpoint, window, iframe); + var BROADCAST_TYPE = [connect.AgentEvents.UPDATE, connect.ContactEvents.VIEW, connect.EventType.ACKNOWLEDGE, connect.EventType.TERMINATED]; + iframe.addEventListener('load', function (e) { + BROADCAST_TYPE.forEach(function (type) { + connect.core.getUpstream().onUpstream(type, function (data) { + iframeConduit.sendUpstream(type, data); + }); + }); + }); + + var iframeRefreshInterval = window.setInterval(function () { + iframe.src += ''; + }, IFRAME_REFRESH_INTERVAL); + + connect.core.getUpstream().onUpstream(connect.EventType.ACKNOWLEDGE, function () { + global.clearInterval(iframeRefreshInterval); + }); + }; + + var getConnectUrl = function (ccpUrl) { + var pos = ccpUrl.indexOf('ccp-v2'); + return ccpUrl.slice(0, pos - 1); + }; + + var signOutThroughCCP = function (ccpUrl) { + var logoutUrl = getConnectUrl(ccpUrl) + '/logout'; + return connect.fetch(logoutUrl, { + credentials: 'include', + }).then(function () { + var eventBus = connect.core.getEventBus(); + eventBus.trigger(connect.EventType.TERMINATE); + return true; + }).catch(function (e) { + connect + .getLog() + .error('An error occured on logout.' + e) + .withException(e); + window.location.href = logoutUrl; + return false; + }); + }; + + var signInThroughinitCCP = function (ccpUrl, container, config) { + var defaultParams = { + ccpUrl: ccpUrl, + ccpLoadTimeout: 10000, + loginPopup: true, + loginUrl: getConnectUrl(ccpUrl) + '/login', + softphone: { + allowFramedSoftphone: true, + disableRingtone: false, + } + }; + var ccpParams = connect.merge(defaultParams, config.ccpParams); + connect.core.initCCP(container, ccpParams); + }; + + connect.agentApp.initApp = function (name, containerId, appUrl, config) { + config = config ? config : {}; + var endpoint = appUrl.endsWith('/') ? appUrl : appUrl + '/'; + var registerConfig = { endpoint: endpoint, style: config.style }; + connect.agentApp.AppRegistry.register(name, registerConfig, document.getElementById(containerId)); + connect.agentApp.AppRegistry.start(name, function (moduleData) { + var endpoint = moduleData.endpoint; + var containerDOM = moduleData.containerDOM; + return { + init: function () { + if (name === APP.CCP) return signInThroughinitCCP(endpoint, containerDOM, config); + return connect.agentApp.initAppCommunication(name, endpoint); + }, + destroy: function () { + if (name === APP.CCP) return signOutThroughCCP(endpoint); + return null; + } + }; + }); + }; + + connect.agentApp.stopApp = function (name) { + return connect.agentApp.AppRegistry.stop(name); + }; +})(); + +(function () { + var global = this; + connect = global.connect || {}; + global.connect = connect; + + var APP = { + CCP: 'ccp', + }; + + function AppRegistry() { + var moduleData = {}; + var makeAppIframe = function (appName, endpoint, style) { + var iframe = document.createElement('iframe'); + iframe.src = endpoint; + iframe.style = style || 'width: 100%; height:100%;'; + iframe.id = appName; + iframe['aria-label'] = appName; + return iframe; + }; + + return { + register: function (appName, config, containerDOM) { + moduleData[appName] = { + containerDOM: containerDOM, + endpoint: config.endpoint, + style: config.style, + instance: undefined, + }; + }, + start: function (appName, creator) { + if (!moduleData[appName]) return; + var containerDOM = moduleData[appName].containerDOM; + var endpoint = moduleData[appName].endpoint; + var style = moduleData[appName].style; + if (appName !== APP.CCP) { + var app = makeAppIframe(appName, endpoint, style); + containerDOM.appendChild(app); + } + + moduleData[appName].instance = creator(moduleData[appName]); + return moduleData[appName].instance.init(); + }, + stop: function (appName) { + if (!moduleData[appName]) return; + + var data = moduleData[appName]; + var app = data.containerDOM.querySelector('iframe'); + data.containerDOM.removeChild(app); + + var result; + if (data.instance) { + result = data.instance.destroy(); + delete data.instance; + } + + return result; + } + }; + } + + global.connect.agentApp.AppRegistry = AppRegistry(); +})(); diff --git a/src/agent-app/agent-app.js b/src/agent-app/agent-app.js new file mode 100644 index 00000000..082de3c2 --- /dev/null +++ b/src/agent-app/agent-app.js @@ -0,0 +1,100 @@ +(function () { + var global = this; + connect = global.connect || {}; + global.connect = connect; + global.lily = connect; + + connect.agentApp = {}; + + var IFRAME_REFRESH_INTERVAL = 5000; + var APP = { + CCP: 'ccp', + }; + + connect.agentApp.initCCP = connect.core.initCCP; + connect.agentApp.isInitialized = function (instanceAlias) {}; + + connect.agentApp.initAppCommunication = function (iframeId, endpoint) { + var iframe = document.getElementById(iframeId); + var iframeConduit = new connect.IFrameConduit(endpoint, window, iframe); + var BROADCAST_TYPE = [connect.AgentEvents.UPDATE, connect.ContactEvents.VIEW, connect.EventType.ACKNOWLEDGE, connect.EventType.TERMINATED]; + iframe.addEventListener('load', function (e) { + BROADCAST_TYPE.forEach(function (type) { + connect.core.getUpstream().onUpstream(type, function (data) { + iframeConduit.sendUpstream(type, data); + }); + }); + }); + + var iframeRefreshInterval = window.setInterval(function () { + iframe.src += ''; + }, IFRAME_REFRESH_INTERVAL); + + connect.core.getUpstream().onUpstream(connect.EventType.ACKNOWLEDGE, function () { + global.clearInterval(iframeRefreshInterval); + }); + }; + + var getConnectUrl = function (ccpUrl) { + var pos = ccpUrl.indexOf('ccp-v2'); + return ccpUrl.slice(0, pos - 1); + }; + + var signOutThroughCCP = function (ccpUrl) { + var logoutUrl = getConnectUrl(ccpUrl) + '/logout'; + return connect.fetch(logoutUrl, { + credentials: 'include', + }).then(function () { + var eventBus = connect.core.getEventBus(); + eventBus.trigger(connect.EventType.TERMINATE); + return true; + }).catch(function (e) { + connect + .getLog() + .error('An error occured on logout.' + e) + .withException(e); + window.location.href = logoutUrl; + return false; + }); + }; + + var signInThroughinitCCP = function (ccpUrl, container, config) { + var defaultParams = { + ccpUrl: ccpUrl, + ccpLoadTimeout: 10000, + loginPopup: true, + loginUrl: getConnectUrl(ccpUrl) + '/login', + softphone: { + allowFramedSoftphone: true, + disableRingtone: false, + } + }; + var ccpParams = connect.merge(defaultParams, config.ccpParams); + connect.core.initCCP(container, ccpParams); + }; + + connect.agentApp.initApp = function (name, containerId, appUrl, config) { + config = config ? config : {}; + var endpoint = appUrl.endsWith('/') ? appUrl : appUrl + '/'; + var registerConfig = { endpoint: endpoint, style: config.style }; + connect.agentApp.AppRegistry.register(name, registerConfig, document.getElementById(containerId)); + connect.agentApp.AppRegistry.start(name, function (moduleData) { + var endpoint = moduleData.endpoint; + var containerDOM = moduleData.containerDOM; + return { + init: function () { + if (name === APP.CCP) return signInThroughinitCCP(endpoint, containerDOM, config); + return connect.agentApp.initAppCommunication(name, endpoint); + }, + destroy: function () { + if (name === APP.CCP) return signOutThroughCCP(endpoint); + return null; + } + }; + }); + }; + + connect.agentApp.stopApp = function (name) { + return connect.agentApp.AppRegistry.stop(name); + }; +})(); diff --git a/src/agent-app/app-registry.js b/src/agent-app/app-registry.js new file mode 100644 index 00000000..12dde406 --- /dev/null +++ b/src/agent-app/app-registry.js @@ -0,0 +1,62 @@ +(function () { + var global = this; + connect = global.connect || {}; + global.connect = connect; + + var APP = { + CCP: 'ccp', + }; + + function AppRegistry() { + var moduleData = {}; + var makeAppIframe = function (appName, endpoint, style) { + var iframe = document.createElement('iframe'); + iframe.src = endpoint; + iframe.style = style || 'width: 100%; height:100%;'; + iframe.id = appName; + iframe['aria-label'] = appName; + return iframe; + }; + + return { + register: function (appName, config, containerDOM) { + moduleData[appName] = { + containerDOM: containerDOM, + endpoint: config.endpoint, + style: config.style, + instance: undefined, + }; + }, + start: function (appName, creator) { + if (!moduleData[appName]) return; + var containerDOM = moduleData[appName].containerDOM; + var endpoint = moduleData[appName].endpoint; + var style = moduleData[appName].style; + if (appName !== APP.CCP) { + var app = makeAppIframe(appName, endpoint, style); + containerDOM.appendChild(app); + } + + moduleData[appName].instance = creator(moduleData[appName]); + return moduleData[appName].instance.init(); + }, + stop: function (appName) { + if (!moduleData[appName]) return; + + var data = moduleData[appName]; + var app = data.containerDOM.querySelector('iframe'); + data.containerDOM.removeChild(app); + + var result; + if (data.instance) { + result = data.instance.destroy(); + delete data.instance; + } + + return result; + } + }; + } + + global.connect.agentApp.AppRegistry = AppRegistry(); +})(); diff --git a/src/api.js b/src/api.js index e321e196..763358ee 100644 --- a/src/api.js +++ b/src/api.js @@ -119,7 +119,20 @@ connect.ContactType = connect.makeEnum([ 'voice', 'queue_callback', - 'chat' + 'chat', + 'task' + ]); + + /*---------------------------------------------------------------- + * enum ContactInitiationMethod + */ + connect.ContactInitiationMethod = connect.makeEnum([ + 'inbound', + 'outbound', + 'transfer', + 'queue_transfer', + 'callback', + 'api', ]); /*---------------------------------------------------------------- @@ -127,7 +140,8 @@ */ connect.ChannelType = connect.makeEnum([ 'VOICE', - 'CHAT' + 'CHAT', + 'TASK' ]); /*---------------------------------------------------------------- @@ -135,7 +149,8 @@ */ connect.MediaType = connect.makeEnum([ 'softphone', - 'chat' + 'chat', + 'task' ]); /*---------------------------------------------------------------- @@ -163,6 +178,23 @@ 'other' ]); + /*---------------------------------------------------------------- + * enum for VoiceIdErrorTypes + */ + connect.VoiceIdErrorTypes = connect.makeEnum([ + 'no_speaker_id_found', + 'get_speaker_id_failed', + 'get_speaker_status_failed', + 'opt_out_speaker_failed', + 'start_session_failed', + 'evaluate_speaker_failed', + 'describe_session_failed', + 'enroll_speaker_failed', + 'update_speaker_id_failed', + 'not_supported_on_conference_calls', + 'timeout' + ]); + /*---------------------------------------------------------------- * enum for CTI exceptions */ @@ -176,8 +208,51 @@ "PaginationException", "RefreshTokenExpiredException", "SendDataFailedException", - "UnauthorizedException" + "UnauthorizedException", + "QuotaExceededException" ]); + /*---------------------------------------------------------------- + * enum for VoiceId streaming status + */ + connect.VoiceIdStreamingStatus = connect.makeEnum([ + "ONGOING", + "ENDED" + ]); + + /*---------------------------------------------------------------- + * enum for VoiceId authentication decision + */ + connect.VoiceIdAuthenticationDecision = connect.makeEnum([ + "ACCEPT", + "REJECT", + "NOT_ENOUGH_SPEECH", + "SPEAKER_NOT_ENROLLED", + "SPEAKER_OPTED_OUT", + "SPEAKER_ID_NOT_PROVIDED" + ]); + + /*---------------------------------------------------------------- + * enum for contact flow authentication decision + */ + connect.ContactFlowAuthenticationDecision = connect.makeEnum([ + "Authenticated", + "NotAuthenticated", + "Inconclusive", + "NotEnrolled", + "OptedOut", + "Error" + ]); + + /*---------------------------------------------------------------- + * enum for VoiceId EnrollmentRequestStatus status + */ + connect.VoiceIdEnrollmentRequestStatus = connect.makeEnum([ + "NOT_ENOUGH_SPEECH", + "IN_PROGRESS", + "COMPLETED", + "FAILED" + ]); + /*---------------------------------------------------------------- * class Agent */ @@ -254,6 +329,10 @@ connect.core.getUpstream().onUpstream(connect.AgentEvents.MUTE_TOGGLE, f); }; + Agent.prototype.onLocalMediaStreamCreated = function (f) { + connect.core.getUpstream().onUpstream(connect.AgentEvents.LOCAL_MEDIA_STREAM_CREATED, f); + }; + Agent.prototype.mute = function () { connect.core.getUpstream().sendUpstream(connect.EventType.BROADCAST, { @@ -315,7 +394,10 @@ var channelConcurrencyMap = this.getRoutingProfile().channelConcurrencyMap; if (!channelConcurrencyMap) { channelConcurrencyMap = Object.keys(connect.ChannelType).reduce(function (acc, key) { - acc[connect.ChannelType[key]] = 1; + // Exclude TASK from default concurrency. + if (key !== 'TASK') { + acc[connect.ChannelType[key]] = 1; + } return acc; }, {}); } @@ -471,6 +553,8 @@ Contact.prototype._createConnectionAPI = function (connectionData) { if (this.getType() === connect.ContactType.CHAT) { return new connect.ChatConnection(this.contactId, connectionData.connectionId); + } else if (this.getType() === connect.ContactType.TASK) { + return new connect.TaskConnection(this.contactId, connectionData.connectionId); } else { return new connect.VoiceConnection(this.contactId, connectionData.connectionId); } @@ -578,6 +662,8 @@ return this._getData().connections.map(function (connData) { if (self.getType() === connect.ContactType.CHAT) { return new connect.ChatConnection(self.contactId, connData.connectionId); + } else if (self.getType() === connect.ContactType.TASK) { + return new connect.TaskConnection(self.contactId, connData.connectionId); } else { return new connect.VoiceConnection(self.contactId, connData.connectionId); } @@ -618,18 +704,49 @@ }); }; + Contact.prototype.getName = function () { + return this._getData().name; + }; + + Contact.prototype.getContactMetadata = function () { + return this._getData().contactMetadata; + } + + Contact.prototype.getDescription = function () { + return this._getData().description; + }; + + Contact.prototype.getReferences = function () { + return this._getData().references; + }; + Contact.prototype.getAttributes = function () { return this._getData().attributes; }; + Contact.prototype.getContactFeatures = function () { + return this._getData().contactFeatures; + }; + Contact.prototype.isSoftphoneCall = function () { return connect.find(this.getConnections(), function (conn) { return conn.getSoftphoneMediaInfo() != null; }) != null; }; + Contact.prototype._isInbound = function () { + var initiationMethod = this._getData().initiationMethod; + return (initiationMethod === connect.ContactInitiationMethod.OUTBOUND) ? false : true; + } + Contact.prototype.isInbound = function () { var conn = this.getInitialConnection(); + + // We will gradually change checking inbound by relying on contact initiationMethod + if (conn.getMediaType() === connect.MediaType.TASK) { + return this._isInbound(); + } + return conn ? conn.getType() === connect.ConnectionType.INBOUND : false; }; @@ -668,6 +785,13 @@ connect.getLog().warn("contact.destroy() has been deprecated."); }; + Contact.prototype.reject = function (callbacks) { + var client = connect.core.getClient(); + client.call(connect.ClientMethods.REJECT_CONTACT, { + contactId: this.getContactId() + }, callbacks); + }; + Contact.prototype.complete = function (callbacks) { var client = connect.core.getClient(); client.call(connect.ClientMethods.COMPLETE_CONTACT, { @@ -736,6 +860,12 @@ ccpVersion: global.ccpVersion, softphoneStreamStatistics: softphoneStreamStatistics }, callbacks); + + connect.publishSoftphoneStats({ + contactId: this.getContactId(), + ccpVersion: global.ccpVersion, + stats: softphoneStreamStatistics + }); }; Contact.prototype.sendSoftphoneReport = function (report, callbacks) { @@ -745,6 +875,12 @@ ccpVersion: global.ccpVersion, report: report }, callbacks); + + connect.publishSoftphoneReport({ + contactId: this.getContactId(), + ccpVersion: global.ccpVersion, + report: report + }); }; Contact.prototype.conferenceConnections = function (callbacks) { @@ -914,6 +1050,324 @@ || connectionType === connect.ConnectionType.MONITORING; } + /*---------------------------------------------------------------- + * Voice authenticator VoiceId + */ + + var VoiceId = function (contactId) { + this.contactId = contactId; + }; + + VoiceId.prototype.getSpeakerId = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.GET_SPEAKER_ID, { + "contactId": self.contactId, + "instanceId": connect.core.getAgentDataProvider().getInstanceId(), + "awsAccountId": connect.core.getAgentDataProvider().getAWSAccountId() + }, { + success: function (data) { + if(data.contactData.customerId) { + var obj = { + speakerId: data.contactData.customerId + } + resolve(obj); + } else { + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.NO_SPEAKER_ID_FOUND, "No speakerId assotiated with this call", err); + reject(error); + } + + }, + failure: function (err) { + connect.getLog().error("Get SpeakerId failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.GET_SPEAKER_ID_FAILED, "Get SpeakerId failed", err); + reject(error); + } + }); + }); + }; + + VoiceId.prototype.getSpeakerStatus = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + self.getSpeakerId().then(function(data){ + client.call(connect.AgentAppClientMethods.GET_SPEAKER_STATUS, { + "SpeakerId": connect.assertNotNull(data.speakerId, 'speakerId'), + "DomainId" : "ConnectDefaultDomainId" + }, { + success: function (data) { + resolve(data); + }, + failure: function (err) { + connect.getLog().error("getSpeakerStatus failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.GET_SPEAKER_STATUS_FAILED, "Get SpeakerStatus failed", err); + reject(error); + } + }); + }).catch(function(err){ + reject(err); + }); + }); + }; + + VoiceId.prototype.optOutSpeaker = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + self.getSpeakerId().then(function(data){ + client.call(connect.AgentAppClientMethods.OPT_OUT_VOICEID_SPEAKER, { + "SpeakerId": connect.assertNotNull(data.speakerId, 'speakerId'), + "DomainId" : "ConnectDefaultDomainId" + }, { + success: function (data) { + connect.getLog().info("optOutSpeaker succeeded"); + //TODO add more logic here for filtering out data once VoiceId API finalized + resolve(data); + }, + failure: function (err) { + connect.getLog().error("optOutSpeaker failed") + .withObject({ + err: err, + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.OPT_OUT_SPEAKER_FAILED, "optOutSpeaker failed.", err); + reject(error); + } + }); + }).catch(function(err){ + reject(err); + }); + }); + }; + + VoiceId.prototype.startSession = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.START_VOICEID_SESSION, { + "contactId": self.contactId, + "instanceId": connect.core.getAgentDataProvider().getInstanceId(), + "customerAccountId": connect.core.getAgentDataProvider().getAWSAccountId(), + "clientToken": AWS.util.uuid.v4() + }, { + success: function (data) { + if(data.sessionId) { + resolve(data); + } else { + reject(Error("No contact id is returned from start session api.")) + } + }, + failure: function (err) { + connect.getLog().error("startVoiceIdSession failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.START_SESSION_FAILED, "startVoiceIdSession failed", err); + reject(error); + } + }); + }); + }; + + VoiceId.prototype.evaluateSpeaker = function (startNew) { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + var maxPollTimes = 120; // Polling for maximum 2 mins. + var milliInterval = 1000; + return new Promise(function (resolve, reject) { + function evaluate() { + client.call(connect.AgentAppClientMethods.EVALUATE_SPEAKER_WITH_VOICEID, { + "SessionNameOrId": contactData.initialContactId || this.contactId + }, { + success: function (data) { + if(maxPollTimes-- !== 1) { + if(data.StreamingStatus === connect.VoiceIdStreamingStatus.ENDED && data.AuthenticationResult.Decision === connect.VoiceIdAuthenticationDecision.NOT_ENOUGH_SPEECH){ + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.INCONCLUSIVE; + resolve(data); + }else if(data.AuthenticationResult.Decision !== connect.VoiceIdAuthenticationDecision.NOT_ENOUGH_SPEECH) { + switch (data.AuthenticationResult.Decision) { + case connect.VoiceIdAuthenticationDecision.ACCEPT: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.AUTHENTICATED; + break; + case connect.VoiceIdAuthenticationDecision.REJECT: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.NOT_AUTHENTICATED; + break; + case connect.VoiceIdAuthenticationDecision.SPEAKER_OPTED_OUT: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.OPT_OUT; + break; + case connect.VoiceIdAuthenticationDecision.SPEAKER_NOT_ENROLLED: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.NOT_ENROLLED; + break; + default: + data.AuthenticationResult.Decision = connect.ContactFlowAuthenticationDecision.ERROR; + } + resolve(data); + } else { + setTimeout(function(){ + evaluate(); + },milliInterval); + } + } else { + connect.getLog().error("evaluateSpeaker timeout"); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.TIMEOUT, "evaluateSpeaker timeout"); + reject(error); + } + }, + failure: function (err) { + connect.getLog().error("evaluateSpeaker failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.EVALUATE_SPEAKER_FAILED, "evaluateSpeaker failed", err); + reject(error); + } + }) + } + if(!startNew){ + evaluate(); + } else { + self.startSession().then(function(data){ + evaluate(); + }).catch(function(err){ + reject(err) + }) + } + }); + }; + + VoiceId.prototype.describeSession = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + var maxPollingTimes = 120; // It is polling for maximum 10 mins. + var milliInterval = 5000; + return new Promise(function (resolve, reject) { + function describe() { + client.call(connect.AgentAppClientMethods.DESCRIBE_VOICEID_SESSION, { + "SessionNameOrId": contactData.initialContactId || this.contactId + }, { + success: function (data) { + if(maxPollingTimes-- !== 1) { + if(data.Session.EnrollmentRequestDetails.Status === connect.VoiceIdEnrollmentRequestStatus.COMPLETED) { + resolve(data); + } else if(data.Session.EnrollmentRequestDetails.Status === connect.VoiceIdEnrollmentRequestStatus.IN_PROGRESS) { + setTimeout(function(){ + describe(); + },milliInterval); + } else if(data.Session.EnrollmentRequestDetails.Status === connect.VoiceIdEnrollmentRequestStatus.NOT_ENOUGH_SPEECH) { + if(data.Session.StreamingStatus === connect.VoiceIdStreamingStatus.ENDED) { + self.startSession().then(function(data){ + describe(); + }).catch(function(err, data){ + reject(err); + }) + } else { + setTimeout(function(){ + describe(); + },milliInterval); + } + } else { + reject(Error(data.Session.EnrollmentRequestDetails.Status)); + } + } else { + connect.getLog().error("describeSession timeout"); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.TIMEOUT, "describeSession timeout"); + reject(error); + } + }, + failure: function (err) { + connect.getLog().error("describeSession failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.DESCRIBE_SESSION_FAILED, "describeSession failed", err); + reject(error); + } + }) + } + describe(); + }); + }; + + VoiceId.prototype.enrollSpeaker = function () { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.ENROLL_SPEAKER_IN_VOICEID, { + "SessionNameOrId": contactData.initialContactId || this.contactId + }, { + success: function (data) { + if(data.Status === connect.VoiceIdEnrollmentRequestStatus.COMPLETED) { + resolve(data); + } else { + self.describeSession().then(function(data){ + resolve(data); + }).catch(function(err){ + reject(err); + }) + } + }, + failure: function (err) { + connect.getLog().error("enrollSpeaker failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.ENROLL_SPEAKER_FAILED, "enrollSpeaker failed", err); + reject(error); + } + }); + }); + }; + + VoiceId.prototype.updateSpeakerId = function (speakerId) { + var self = this; + self.checkConferenceCall(); + var client = connect.core.getClient(); + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + return new Promise(function (resolve, reject) { + client.call(connect.AgentAppClientMethods.UPDATE_VOICEID_SESSION, { + "SessionNameOrId": contactData.initialContactId || this.contactId, + "SpeakerId": connect.assertNotNull(speakerId, 'speakerId') + }, { + success: function (data) { + resolve(data); + }, + failure: function (err) { + connect.getLog().error("updateSpeakerId failed") + .withObject({ + err: err + }); + var error = connect.VoiceIdError(connect.VoiceIdErrorTypes.UPDATE_SPEAKER_ID_FAILED, "updateSpeakerId failed", err); + reject(error); + } + }); + }); + }; + + VoiceId.prototype.checkConferenceCall = function(){ + var self = this; + var isConferenceCall = connect.core.getAgentDataProvider().getContactData(self.contactId).connections.length > 2; + if(isConferenceCall){ + throw new connect.NotImplementedError("VoiceId is not supported for conference calls"); + } + } + /** * @class VoiceConnection * @param {number} contactId @@ -921,6 +1375,7 @@ * @description - Provides voice media specific operations */ var VoiceConnection = function (contactId, connectionId) { + this._speakerAuthenticator = new VoiceId(contactId); Connection.call(this, contactId, connectionId); }; @@ -947,6 +1402,30 @@ return connect.core.mediaFactory.get(this); } + VoiceConnection.prototype.getVoiceIdSpeakerId = function() { + return this._speakerAuthenticator.getSpeakerId(); + } + + VoiceConnection.prototype.getVoiceIdSpeakerStatus = function() { + return this._speakerAuthenticator.getSpeakerStatus(); + } + + VoiceConnection.prototype.optOutVoiceIdSpeaker = function() { + + return this._speakerAuthenticator.optOutSpeaker(); + } + + VoiceConnection.prototype.evaluateSpeakerWithVoiceId = function(startNew) { + return this._speakerAuthenticator.evaluateSpeaker(startNew); + } + + VoiceConnection.prototype.enrollSpeakerInVoiceId = function() { + return this._speakerAuthenticator.enrollSpeaker(); + } + + VoiceConnection.prototype.updateVoiceIdSpeakerId = function(speakerId) { + return this._speakerAuthenticator.updateSpeakerId(speakerId); + } /** * @class ChatConnection @@ -977,7 +1456,10 @@ try { mediaObject.participantToken = JSON.parse(data.connectionData).ConnectionAuthenticationToken; } catch (e) { - connect.getLog().error(connect.LogComponent.CHAT, "Connection data is invalid").withObject(data).withException(e); + connect.getLog().error(connect.LogComponent.CHAT, "Connection data is invalid") + .withObject(data) + .withException(e) + .sendInternalLogToServer(); mediaObject.participantToken = null; } } @@ -1007,11 +1489,11 @@ return new Promise(function (resolve, reject) { client.call(connect.ClientMethods.CREATE_TRANSPORT, transportDetails, { success: function (data) { - connect.getLog().info("getConnectionToken succeeded"); + connect.getLog().info("getConnectionToken succeeded").sendInternalLogToServer(); resolve(data); }, failure: function (err, data) { - connect.getLog().error("getConnectionToken failed") + connect.getLog().error("getConnectionToken failed").sendInternalLogToServer() .withObject({ err: err, data: data @@ -1037,6 +1519,35 @@ } } + /** + * @class TaskConnection + * @param {*} contactId + * @param {*} connectionId + * @description adds the task media specific functionality + */ + var TaskConnection = function (contactId, connectionId) { + Connection.call(this, contactId, connectionId); + }; + TaskConnection.prototype = Object.create(Connection.prototype); + TaskConnection.prototype.constructor = TaskConnection; + + TaskConnection.prototype.getMediaType = function () { + return connect.MediaType.TASK; + } + + TaskConnection.prototype.getMediaInfo = function () { + var contactData = connect.core.getAgentDataProvider().getContactData(this.contactId); + var mediaObject = { + contactId: this.contactId, + initialContactId: contactData.initialContactId || this.contactId, + }; + return mediaObject; + }; + + TaskConnection.prototype.getMediaController = function () { + return connect.core.mediaFactory.get(this); + }; + /*---------------------------------------------------------------- * class ConnectionSnapshot */ @@ -1142,7 +1653,7 @@ if (!connect.core.masterClient) { // We can't be the master because there is no master client! - connect.getLog().warn("We can't be the master for topic '%s' because there is no master client!", topic); + connect.getLog().warn("We can't be the master for topic '%s' because there is no master client!", topic).sendInternalLogToServer(); if (f_else) { f_else(); } @@ -1184,6 +1695,7 @@ connect.BaseConnection = Connection; connect.VoiceConnection = VoiceConnection; connect.ChatConnection = ChatConnection; + connect.TaskConnection = TaskConnection; connect.ConnectionSnapshot = ConnectionSnapshot; connect.Endpoint = Endpoint; connect.Address = Endpoint; diff --git a/src/aws-client.js b/src/aws-client.js index 42aa2f5d..317be27b 100644 --- a/src/aws-client.js +++ b/src/aws-client.js @@ -741,6 +741,33 @@ "members": {} } }, + "CreateTaskContact": { + "input": { + "type": "structure", + "required": [ + "endpoint", + "name" + ], + "members": { + "endpoint": { + "shape": "Se" + }, + "previousContactId": {}, + "name": {}, + "description": {}, + "references": { + "shape": "Sr" + }, + "idempotencyToken": {} + } + }, + "output": { + "type": "structure", + "members": { + "contactId": {} + } + } + }, "CreateTransport": { "input": { "type": "structure", @@ -856,7 +883,7 @@ ], "members": { "configuration": { - "shape": "S1b" + "shape": "S1h" } } } @@ -923,7 +950,10 @@ ], "members": { "state": { - "shape": "S1u" + "shape": "S1z" + }, + "nextState": { + "shape": "S1z" }, "agentAvailabilityState": { "type": "structure", @@ -948,6 +978,14 @@ "members": { "contactId": {}, "initialContactId": {}, + "contactFeatures": { + "type": "structure", + "members": { + "attachmentsEnabled": { + "type": "boolean" + } + } + }, "type": {}, "state": { "type": "structure", @@ -1057,32 +1095,7 @@ "name": {}, "description": {}, "references": { - "type": "map", - "key": {}, - "value": { - "type": "structure", - "required": [ - "value" - ], - "members": { - "value": {} - } - } - }, - "contactMetadata": { - "type": "structure", - "required": [ - "name" - ], - "members": { - "name": {}, - "references": { - "type": "map", - "key": {}, - "value": {} - }, - "description": {} - } + "shape": "Sr" }, "initiationMethod": {} } @@ -1122,7 +1135,7 @@ "states": { "type": "list", "member": { - "shape": "S1u" + "shape": "S1z" } }, "nextToken": {} @@ -1306,7 +1319,10 @@ "shape": "S2" }, "state": { - "shape": "S1u" + "shape": "S1z" + }, + "enqueueNextState": { + "type": "boolean" } } }, @@ -1554,7 +1570,7 @@ "shape": "S2" }, "configuration": { - "shape": "S1b" + "shape": "S1h" } } }, @@ -1595,7 +1611,22 @@ "name": {} } }, - "S1b": { + "Sr": { + "type": "map", + "key": {}, + "value": { + "type": "structure", + "required": [ + "value", + "type" + ], + "members": { + "value": {}, + "type": {} + } + } + }, + "S1h": { "type": "structure", "required": [ "name", @@ -1638,7 +1669,7 @@ } } }, - "S1u": { + "S1z": { "type": "structure", "required": [ "type", @@ -2266,7 +2297,7 @@ }, "iotanalytics": { "name": "IoTAnalytics", - "cors": true + "cors": true }, "iot1clickdevicesservice": { "prefix": "iot1click-devices", @@ -5199,7 +5230,7 @@ * @return [Array] * a list of credentials objects or functions that return credentials * objects. If the provider is a function, the function will be - * executed lazily when the provider needs to be checked for valid + * started lazily when the provider needs to be checked for valid * credentials. By default, this object will be set to the * {defaultProviders}. * @see defaultProviders diff --git a/src/client.js b/src/client.js index 6d91d01a..b26b9dd1 100644 --- a/src/client.js +++ b/src/client.js @@ -23,8 +23,11 @@ 'updateAgentConfiguration', 'acceptContact', 'createOutboundContact', + 'createTaskContact', 'clearContact', 'completeContact', + 'destroyContact', + 'rejectContact', 'notifyContactIssue', 'updateContactAttributes', 'createAdditionalConnection', @@ -42,6 +45,20 @@ 'createTransport' ]); + /**--------------------------------------------------------------- + * enum AgentAppClientMethods + */ + connect.AgentAppClientMethods = { + GET_SPEAKER_ID: "AgentAppService.Lcms.getContact", + ENROLL_SPEAKER_IN_VOICEID: "AgentAppService.VoiceId.enrollBySession", + EVALUATE_SPEAKER_WITH_VOICEID: "AgentAppService.VoiceId.evaluateSession", + GET_SPEAKER_STATUS: "AgentAppService.VoiceId.describeSpeaker", + OPT_OUT_VOICEID_SPEAKER: "AgentAppService.VoiceId.optOutSpeaker", + DESCRIBE_VOICEID_SESSION: "AgentAppService.VoiceId.describeSession", + UPDATE_VOICEID_SESSION: "AgentAppService.VoiceId.updateSession", + START_VOICEID_SESSION: "AgentAppService.Nasa.startVoiceIdSession", + }; + /**--------------------------------------------------------------- * enum MasterMethods */ @@ -149,7 +166,43 @@ }; UpstreamConduitMasterClient.prototype = Object.create(UpstreamConduitClientBase.prototype); UpstreamConduitMasterClient.prototype.constructor = UpstreamConduitMasterClient; + + /**--------------------------------------------------------------- + * class AgentAppClient extends ClientBase + */ + var AgentAppClient = function(authCookieName, authToken, endpoint) { + connect.assertNotNull(authCookieName, 'authCookieName'); + connect.assertNotNull(authToken, 'authToken'); + connect.assertNotNull(endpoint, 'endpoint'); + ClientBase.call(this); + this.endpointUrl = connect.getUrlWithProtocol(endpoint); + this.authToken = authToken; + this.authCookieName = authCookieName + }; + AgentAppClient.prototype = Object.create(ClientBase.prototype); + AgentAppClient.prototype.constructor = AgentAppClient; + + AgentAppClient.prototype._callImpl = function(method, params, callbacks) { + var self = this; + var bear = {}; + bear[self.authCookieName] = self.authToken; + var options = { + method: 'post', + body: JSON.stringify(params || {}), + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'X-Amz-target': method, + 'X-Amz-Bearer': JSON.stringify(bear) + } + }; + connect.fetch(self.endpointUrl, options).then(function(res){ + callbacks.success(res); + }).catch(function(err){ + callbacks.failure(err); + }) + }; /**--------------------------------------------------------------- * class AWSClient extends ClientBase */ @@ -183,7 +236,7 @@ } else { params = this._translateParams(method, params); - log.trace("AWSClient: --> Calling operation '%s'", method); + log.trace("AWSClient: --> Calling operation '%s'", method).sendInternalLogToServer(); this.client[method](params) .on('build', function(request) { @@ -207,15 +260,15 @@ callbacks.failure(error, data); } - log.trace("AWSClient: <-- Operation '%s' failed: %s", method, JSON.stringify(err)); + log.trace("AWSClient: <-- Operation '%s' failed: %s", method, JSON.stringify(err)).sendInternalLogToServer(); } else { - log.trace("AWSClient: <-- Operation '%s' succeeded.", method).withObject(data); + log.trace("AWSClient: <-- Operation '%s' succeeded.", method).withObject(data).sendInternalLogToServer(); callbacks.success(data); } } catch (e) { connect.getLog().error("Failed to handle AWS API request for method %s", method) - .withException(e); + .withException(e).sendInternalLogToServer(); } }); } @@ -224,7 +277,8 @@ AWSClient.prototype._requiresAuthenticationParam = function (method) { return method !== connect.ClientMethods.COMPLETE_CONTACT && method !== connect.ClientMethods.CLEAR_CONTACT && - method !== connect.ClientMethods.REJECT_CONTACT; + method !== connect.ClientMethods.REJECT_CONTACT && + method !== connect.ClientMethods.CREATE_TASK_CONTACT; }; AWSClient.prototype._translateParams = function(method, params) { @@ -324,5 +378,6 @@ connect.UpstreamConduitClient = UpstreamConduitClient; connect.UpstreamConduitMasterClient = UpstreamConduitMasterClient; connect.AWSClient = AWSClient; + connect.AgentAppClient = AgentAppClient; })(); diff --git a/src/core.js b/src/core.js index 3649e7ba..b1aee999 100644 --- a/src/core.js +++ b/src/core.js @@ -93,7 +93,7 @@ connect.core.checkNotInitialized = function () { if (connect.core.initialized) { var log = connect.getLog(); - log.warn("Connect core already initialized, only needs to be initialized once."); + log.warn("Connect core already initialized, only needs to be initialized once.").sendInternalLogToServer(); } }; @@ -105,6 +105,7 @@ connect.core.eventBus = new connect.EventBus(); connect.core.agentDataProvider = new AgentDataProvider(connect.core.getEventBus()); connect.core.initClient(params); + connect.core.initAgentAppClient(params); connect.core.initialized = true; }; @@ -123,11 +124,26 @@ connect.core.client = new connect.AWSClient(authToken, region, endpoint); }; + /**------------------------------------------------------------------------- + * Initialized AgentApp client + * Should be used by Shared Worker to update AgentApp client with new credentials + * after refreshed authentication. + */ + connect.core.initAgentAppClient = function (params) { + connect.assertNotNull(params, 'params'); + var authToken = connect.assertNotNull(params.authToken, 'params.authToken'); + var authCookieName = connect.assertNotNull(params.authCookieName, 'params.authCookieName'); + var endpoint = connect.assertNotNull(params.agentAppEndpoint, 'params.agentAppEndpoint'); + + connect.core.agentAppClient = new connect.AgentAppClient(authCookieName, authToken, endpoint); + }; + /**------------------------------------------------------------------------- * Uninitialize Connect. */ connect.core.terminate = function () { connect.core.client = new connect.NullClient(); + connect.core.agentAppClient = new connect.NullClient(); connect.core.masterClient = new connect.NullClient(); var bus = connect.core.getEventBus(); if (bus) bus.unsubscribeAll(); @@ -172,18 +188,24 @@ if (!ringtoneSettings.voice.disabled && !connect.core.ringtoneEngines.voice) { connect.core.ringtoneEngines.voice = new connect.VoiceRingtoneEngine(ringtoneSettings.voice); - connect.getLog().info("VoiceRingtoneEngine initialized."); + connect.getLog().info("VoiceRingtoneEngine initialized.").sendInternalLogToServer(); } if (!ringtoneSettings.chat.disabled && !connect.core.ringtoneEngines.chat) { connect.core.ringtoneEngines.chat = new connect.ChatRingtoneEngine(ringtoneSettings.chat); - connect.getLog().info("ChatRingtoneEngine initialized."); + connect.getLog().info("ChatRingtoneEngine initialized.").sendInternalLogToServer(); + } + + if (!ringtoneSettings.task.disabled && !connect.core.ringtoneEngines.task) { + connect.core.ringtoneEngines.task = + new connect.TaskRingtoneEngine(ringtoneSettings.task); + connect.getLog().info("TaskRingtoneEngine initialized.").sendInternalLogToServer(); } if (!ringtoneSettings.queue_callback.disabled && !connect.core.ringtoneEngines.queue_callback) { connect.core.ringtoneEngines.queue_callback = new connect.QueueCallbackRingtoneEngine(ringtoneSettings.queue_callback); - connect.getLog().info("QueueCallbackRingtoneEngine initialized."); + connect.getLog().info("QueueCallbackRingtoneEngine initialized.").sendInternalLogToServer(); } }); }); @@ -197,6 +219,8 @@ params.ringtone.voice = params.ringtone.voice || {}; params.ringtone.queue_callback = params.ringtone.queue_callback || {}; params.ringtone.chat = params.ringtone.chat || { disabled: true }; + params.ringtone.task = params.ringtone.task || { disabled: true }; + if (otherParams.softphone) { if (otherParams.softphone.disableRingtone) { params.ringtone.voice.disabled = true; @@ -379,6 +403,8 @@ ? LEGACY_AUTHORIZE_ENDPOINT : AUTHORIZE_ENDPOINT; } + var agentAppEndpoint = params.agentAppEndpoint || null; + var authCookieName = params.authCookieName || null; try { // Initialize the event bus and agent data providers. @@ -403,6 +429,7 @@ }; connect.getLog().scheduleUpstreamLogPush(conduit); + connect.getLog().scheduleDownstreamClientSideLogsPush(); // Bridge all upstream messages into the event bus. conduit.onAllUpstream(connect.core.getEventBus().bridge()); // Bridge all downstream messages into the event bus. @@ -419,11 +446,13 @@ endpoint: endpoint, refreshToken: refreshToken, region: region, - authorizeEndpoint: authorizeEndpoint + authorizeEndpoint: authorizeEndpoint, + agentAppEndpoint: agentAppEndpoint, + authCookieName: authCookieName }); conduit.onUpstream(connect.EventType.ACKNOWLEDGE, function () { - connect.getLog().info("Acknowledged by the ConnectSharedWorker!"); + connect.getLog().info("Acknowledged by the ConnectSharedWorker!").sendInternalLogToServer(); connect.core.initialized = true; this.unsubscribe(); }); @@ -433,6 +462,11 @@ connect.getLog().addLogEntry(connect.LogEntry.fromObject(logEntry)); } }); + conduit.onUpstream(connect.EventType.SERVER_BOUND_INTERNAL_LOG, function (logEntry) { + if (logEntry.loggerId !== connect.getLog().getLoggerId()) { + connect.getLog().sendInternalLogEntryToServer(connect.LogEntry.fromObject(logEntry)); + } + }); // Reload the page if the shared worker detects an API auth failure. conduit.onUpstream(connect.EventType.AUTH_FAIL, function (logEntry) { location.reload(); @@ -459,7 +493,7 @@ } catch (e) { connect.getLog().error("Failed to initialize the API shared worker, we're dead!") - .withException(e); + .withException(e).sendInternalLogToServer(); } }; @@ -536,7 +570,7 @@ // Once we receive the first ACK, setup our upstream API client and establish // the SYN/ACK refresh flow. conduit.onUpstream(connect.EventType.ACKNOWLEDGE, function () { - connect.getLog().info("Acknowledged by the CCP!"); + connect.getLog().info("Acknowledged by the CCP!").sendInternalLogToServer(); connect.core.client = new connect.UpstreamConduitClient(conduit); connect.core.masterClient = new connect.UpstreamConduitMasterClient(conduit); connect.core.initialized = true; @@ -564,6 +598,11 @@ connect.getLog().addLogEntry(connect.LogEntry.fromObject(logEntry)); } }); + conduit.onUpstream(connect.EventType.SERVER_BOUND_INTERNAL_LOG, function (logEntry) { + if (logEntry.loggerId !== connect.getLog().getLoggerId()) { + connect.getLog().sendInternalLogEntryToServer(connect.LogEntry.fromObject(logEntry)); + } + }); // Pop a login page when we encounter an ACK timeout. connect.core.getEventBus().subscribe(connect.EventType.ACK_TIMEOUT, function () { @@ -571,14 +610,14 @@ if (params.loginPopup !== false) { try { var loginUrl = getLoginUrl(params); - connect.getLog().warn("ACK_TIMEOUT occurred, attempting to pop the login page if not already open."); + connect.getLog().warn("ACK_TIMEOUT occurred, attempting to pop the login page if not already open.").sendInternalLogEntryToServer(); // clear out last opened timestamp for SAML authentication when there is ACK_TIMEOUT if (params.loginUrl) { connect.core.getPopupManager().clear(connect.MasterTopics.LOGIN_POPUP); } connect.core.loginWindow = connect.core.getPopupManager().open(loginUrl, connect.MasterTopics.LOGIN_POPUP, params.loginOptions); } catch (e) { - connect.getLog().error("ACK_TIMEOUT occurred but we are unable to open the login popup.").withException(e); + connect.getLog().error("ACK_TIMEOUT occurred but we are unable to open the login popup.").withException(e).sendInternalLogToServer(); } } @@ -838,6 +877,14 @@ return connectionData; }; + + AgentDataProvider.prototype.getInstanceId = function(){ + return this.getAgentData().configuration.routingProfile.routingProfileId.match(/instance\/([0-9a-fA-F|-]+)\//)[1]; + } + + AgentDataProvider.prototype.getAWSAccountId = function(){ + return this.getAgentData().configuration.routingProfile.routingProfileId.match(/:([0-9]+):instance/)[1]; + } AgentDataProvider.prototype._diffContacts = function (oldAgentData) { var diff = { @@ -1085,7 +1132,10 @@ connect.ContactEvents.ENDED) .assoc(connect.EventGraph.ANY, connect.values(connect.AgentErrorStates), - connect.ContactEvents.ERROR); + connect.ContactEvents.ERROR) + .assoc(connect.ContactStateType.CONNECTING, + connect.ContactStateType.MISSED, + connect.ContactEvents.MISSED); /**-----------------------------------------------------------------------*/ connect.core.getClient = function () { @@ -1096,6 +1146,15 @@ }; connect.core.client = null; + /**-----------------------------------------------------------------------*/ + connect.core.getAgentAppClient = function () { + if (!connect.core.agentAppClient) { + throw new connect.StateError('The connect AgentApp Client has not been initialized!'); + } + return connect.core.agentAppClient; + }; + connect.core.agentAppClient = null; + /**-----------------------------------------------------------------------*/ connect.core.getMasterClient = function () { if (!connect.core.masterClient) { @@ -1138,4 +1197,4 @@ /**-----------------------------------------------------------------------*/ connect.core.AgentDataProvider = AgentDataProvider; -})(); \ No newline at end of file +})(); diff --git a/src/event.js b/src/event.js index b977255d..b15385fb 100644 --- a/src/event.js +++ b/src/event.js @@ -33,6 +33,10 @@ 'broadcast', 'api_metric', 'client_metric', + 'softphone_stats', + 'softphone_report', + 'client_side_logs', + 'server_bound_internal_log', 'mute', "iframe_style" ]); @@ -260,14 +264,19 @@ var allEventSubs = this.subMap.getSubscriptions(ALL_EVENTS); var eventSubs = this.subMap.getSubscriptions(eventName); - if (this.logEvents && (eventName !== connect.EventType.LOG && eventName !== connect.EventType.MASTER_RESPONSE && eventName !== connect.EventType.API_METRIC)) { - connect.getLog().trace("Publishing event: %s", eventName); + if (this.logEvents && + eventName !== connect.EventType.LOG && + eventName !== connect.EventType.MASTER_RESPONSE && + eventName !== connect.EventType.API_METRIC && + eventName !== connect.EventType.SERVER_BOUND_INTERNAL_LOG + ) { + connect.getLog().trace("Publishing event: %s", eventName).sendInternalLogToServer(); } allEventSubs.concat(eventSubs).forEach(function (sub) { try { sub.f(data || null, eventName, self); } catch (e) { - connect.getLog().error("'%s' event handler failed.", eventName).withException(e); + connect.getLog().error("'%s' event handler failed.", eventName).withException(e).sendInternalLogToServer(); } }); }; diff --git a/src/index.d.ts b/src/index.d.ts index fbb23167..73091397 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -127,6 +127,58 @@ declare namespace connect { const core: Core; + interface AgentApp { + /** Alias for connect.core.initCCP */ + initCCP(container: HTMLElement, options: InitCCPOptions): void; + /** Waits for CCP to load to begin iframe communication. */ + initAppCommunication(iframeId: string, endpoint: string): void; + /** Registers the app to the registry and initializes it. */ + initApp(appName: string, containerId: string, appUrl: string, config?: AppOptions): void; + /** Destoys the app by calling the destroy method defined in the app registry. */ + stopApp(): void; + /** Memoizes app data along with start and stop functions. */ + AppRegistry: AppRegistry; + } + + const agentApp: AgentApp; + + interface AppOptions { + /** Optional CCP configuration that overrides and gets merged with defaults. */ + ccpParams?: OptionalInitCCPOptions; + /** Optional inline styling for the app iframe. */ + style?: string; + } + + interface AppRegistry { + /** Saves app data to memory. */ + register(appName: string, config: AppRegistryOptions, containerDOM: HTMLElement): void; + /** Initializes the app by calling the init method defined in the creator. */ + start(appName: string, creator: AppCreator): void; + /** Destoys the app by calling the destroy method defined in the creator. */ + stop(): void; + } + + type AppCreator = (moduleData: AppData) => AppMethods; + + type AppData = { + containerDOM: HTMLElement; + endpoint: string; + style?: string; + instance?: AppMethods; + } + + interface AppMethods { + init(): void; + destroy(): void; + } + + interface AppRegistryOptions { + /** This is the page you would normally navigate to in order to use the app in a standalone page. */ + endpoint: string; + /** An optional string to supply inline styling for the iframe. */ + style?: string; + } + interface ViewContactEvent { /** The ID of the viewed contact. */ contactId: string; @@ -222,6 +274,44 @@ declare namespace connect { readonly chat?: ChatOptions; } + + interface OptionalInitCCPOptions { + /** + * Amazon connect instance region. Only required for chat channel. + * @example "us-west-2" + */ + readonly region?: string; + + /** + * Set to `false` to disable the login popup which is shown when the user's authentication expires. + * @default true + */ + readonly loginPopup?: boolean; + + /** + * Options to open login popup in a new window instead of a new tab. If loginPopup is set to + * `false`, these options will be ignored. + */ + readonly loginOptions?: LoginOptions; + + /** + * Set to `true` in conjunction with the `loginPopup` parameter to automatically close the login + * Popup window once the authentication step has completed. If the login page opened in a new + * tab, this parameter will also auto-close that tab. + * @default false + */ + readonly loginPopupAutoClose?: boolean; + + /** Allows custom URL to be used to initiate the ccp, as in the case of SAML authentication. */ + readonly loginUrl?: string; + + /** Allows you to specify some settings surrounding the softphone feature of Connect. */ + readonly softphone?: SoftPhoneOptions; + + /** Allows you to specify ringtone settings for Chat. */ + readonly chat?: ChatOptions; + } + /** This enumeration lists the different types of agent states. */ enum AgentStateType { /** The agent state hasn't been initialized yet. */ @@ -276,6 +366,10 @@ declare namespace connect { QUEUE = "queue", } + enum ReferenceType { + URL = "URL", + } + /** Lists the different types of connections. */ enum ConnectionType { /** The agent connection. */ @@ -352,6 +446,9 @@ declare namespace connect { /** Indicates the contact timed out before the agent could accept it. */ MISSED = "missed", + /** Indicates the contact is rejected */ + REJECTED = "rejected", + /** Indicates the contact is in an error state. */ ERROR = "error", @@ -379,6 +476,9 @@ declare namespace connect { /** Chat contact. */ CHAT = "chat", + + /** Task contact. */ + TASK = "task", } /** This enumeration lists the different types of contact channels. */ @@ -388,11 +488,15 @@ declare namespace connect { /** A chat contact. */ CHAT = "CHAT", + + /** A task contact. */ + TASK = "TASK", } enum MediaType { SOFTPHONE = "softphone", CHAT = "chat", + TASK = "task", } enum SoftphoneCallType { @@ -607,6 +711,15 @@ declare namespace connect { */ setState(state: AgentStateDefinition, callbacks?: SuccessFailOptions): void; + /** + * Create task contact. + * Can only be performed if the agent is not handling a live contact. + * + * @param taskContact The new task contact. + * @param callbacks Success and failure callbacks to determine whether the operation was successful. + */ + createTask(taskContact: TaskContactDefinition, callbacks?: SuccessFailOptions): void; + /** Alias for `setState()`. */ setStatus( state: AgentStateDefinition, @@ -682,6 +795,27 @@ declare namespace connect { readonly name: string; } + interface TaskContactDefinition { + /** The endpoint to assign to */ + readonly endpoint: Endpoint; + + /** The linked contact id */ + readonly previousContactId?: string; + + /** The task name */ + readonly name: string; + + /** The task description */ + readonly description: string; + + /** The task references */ + readonly references: ReferenceDictionary; + + /** A random value */ + readonly idempotencyToken: string; + + } + /** * An object containing the current Agent state */ @@ -777,6 +911,13 @@ declare namespace connect { }; } + interface ReferenceDictionary { + readonly [key: string]: { + type: ReferenceType; + value: string; + }; + } + /** * The Contact API provides event subscription methods and action methods which can be called on behalf of a specific contact. * Contacts come and go and so should these API objects. @@ -906,6 +1047,15 @@ declare namespace connect { /** Alias for `getStatus()` */ getStatus(): ContactState; + /** Get name for the contact. */ + getName(): string; + + /** Get description for the contact. */ + getDescription(): string; + + /** Get references for the contact. */ + getReferences(): ReferenceDictionary; + /** * Get the duration of the contact state in milliseconds relative to local time. * This takes into account time skew between the JS client and the Amazon Connect backend servers. @@ -970,6 +1120,7 @@ declare namespace connect { /** * Close the contact and all of its associated connections. + * This method can also reject and clear contacts but those behaviors will be deprecated. * If the contact is a voice contact, and there is a third-party, the customer remains bridged with the third party and will not be disconnected from the call. * Otherwise, the agent and customer are disconnected. * @@ -977,6 +1128,13 @@ declare namespace connect { */ destroy(callbacks?: SuccessFailOptions): void; + /** + * Reject an incoming contact. + * + * @param callbacks Success and failure callbacks to determine whether the operation was successful. + */ + reject(callbacks?: SuccessFailOptions): void; + /** * Clear the contact. * @@ -1090,7 +1248,7 @@ declare namespace connect { /** * The Connection API provides action methods (no event subscriptions) which can be called to manipulate the state of a particular connection within a contact. * Like contacts, connections come and go. - * It is good practice not to persist these object or keep them as internal state. + * It is good practice not to persist these objects or keep them as internal state. * If you need to, store the contactId and connectionId of the connection and make sure that the contact and connection still exist by fetching them in order from the Agent API object before calling methods on them. */ class BaseConnection { @@ -1185,7 +1343,7 @@ declare namespace connect { /** * The VoiceConnection API provides action methods (no event subscriptions) which can be called to manipulate the state of a particular voice connection within a contact. * Like contacts, connections come and go. - * It is good practice not to persist these object or keep them as internal state. + * It is good practice not to persist these objects or keep them as internal state. * If you need to, store the `contactId` and `connectionId` of the connection and make sure that the contact and connection still exist by fetching them in order from the `Agent` API object before calling methods on them. */ class VoiceConnection extends BaseConnection { @@ -1197,12 +1355,31 @@ declare namespace connect { /** Gets a `Promise` with the media controller associated with this connection. */ getMediaController(): Promise; + + /** Returns the `SpeakerId` associated to this Voice Connection */ + getVoiceIdSpeakerId(): Promise; + + /** Returns the `VoiceId speaker status` associated to this Voice Connection */ + getVoiceIdSpeakerStatus(): Promise; + + /** Opt out speaker associated to this Voice Connection from VoiceId*/ + optOutVoiceIdSpeaker(): Promise; + + /** Returns VoiceId speaker authentication status */ + evaluateSpeakerWithVoiceId(): Promise; + + /** Enroll speaker into VoiceId */ + enrollSpeakerInVoiceId(): Promise; + + /** Update speaker id */ + updateVoiceIdSpeakerId(): Promise; + } /** * The ChatConnection API provides action methods (no event subscriptions) which can be called to manipulate the state of a particular chat connection within a contact. * Like contacts, connections come and go. - * It is good practice not to persist these object or keep them as internal state. + * It is good practice not to persist these objects or keep them as internal state. * If you need to, store the `contactId` and `connectionId` of the connection and make sure that the contact and connection still exist by fetching them in order from the `Agent` API object before calling methods on them. */ class ChatConnection extends BaseConnection { @@ -1222,6 +1399,26 @@ declare namespace connect { getMediaController(): Promise; } + /** + * The TaskConnection API provides action methods (no event subscriptions) which can be called to manipulate the state of a particular task connection within a contact. + * Like contacts, connections come and go. + * It is good practice not to persist these objects or keep them as internal state. + * If you need to, store the `contactId` and `connectionId` of the connection and make sure that the contact and connection still exist by fetching them in order from the `Agent` API object before calling methods on them. + */ + class TaskConnection extends BaseConnection { + /** Get the media info object associated with this connection. */ + getMediaInfo(): TaskMediaInfo; + + /** Returns the `MediaType` enum value: `"task"`. */ + getMediaType(): MediaType.TASK; + + /** + * Gets a `Promise` with the media controller associated with this connection. + * The promise resolves to a `ChatSession` object from `amazon-connect-taskjs` library. + */ + getMediaController(): Promise; + } + interface ConnectionState { /** A `Date` object that indicates when the the connection was put in that state. */ readonly timestamp: Date; @@ -1258,6 +1455,11 @@ declare namespace connect { readonly participantToken: string; } + interface TaskMediaInfo { + readonly contactId: string; + readonly initialContactId: string; + } + interface MonitorInfo { readonly agentName: string; readonly customerName: string; diff --git a/src/lib/amazon-connect-websocket-manager.js b/src/lib/amazon-connect-websocket-manager.js index 78252a61..fc5d8b8b 100644 --- a/src/lib/amazon-connect-websocket-manager.js +++ b/src/lib/amazon-connect-websocket-manager.js @@ -1 +1,2 @@ -!function(e){var n={};function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:o})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(t.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)t.d(o,r,function(n){return e[n]}.bind(null,r));return o},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=2)}([function(e,n,t){"use strict";var o=t(1);function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i={assertTrue:function(e,n){if(!e)throw new Error(n)},assertNotNull:function(e,n){return i.assertTrue(null!==e&&void 0!==r(e),Object(o.sprintf)("%s must be provided",n||"A value")),e},isNonEmptyString:function(e){return"string"==typeof e&&e.length>0},assertIsList:function(e,n){if(!Array.isArray(e))throw new Error(n+" is not an array")},isFunction:function(e){return!!(e&&e.constructor&&e.call&&e.apply)},isObject:function(e){return!("object"!==r(e)||null===e)},isString:function(e){return"string"==typeof e},isNumber:function(e){return"number"==typeof e}},c=new RegExp("^(wss://)\\w*");i.validWSUrl=function(e){return c.test(e)},i.getSubscriptionResponse=function(e,n,t){return{topic:e,content:{status:n?"success":"failure",topics:t}}},i.assertIsObject=function(e,n){if(!i.isObject(e))throw new Error(n+" is not an object!")},i.addJitter=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;n=Math.min(n,1);var t=Math.random()>.5?1:-1;return Math.floor(e+t*e*Math.random()*n)},i.isNetworkOnline=function(){return navigator.onLine};var s=i,a="NULL",u="CLIENT_LOGGER",l="DEBUG",f="aws/subscribe",p="aws/unsubscribe",d="aws/heartbeat",b="connected",g="disconnected";function m(e){return(m="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function y(e,n){return!n||"object"!==m(n)&&"function"!=typeof n?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):n}function S(e){return(S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function k(e,n){return(k=Object.setPrototypeOf||function(e,n){return e.__proto__=n,e})(e,n)}function w(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function v(e,n){for(var t=0;t=this._level}},{key:"hasClientLogger",value:function(){return null!==this._clientLogger}},{key:"getLogger",value:function(e){var n=e.prefix||"";return this._logsDestination===l?this.consoleLoggerWrapper:new W(n)}},{key:"updateLoggerConfig",value:function(e){var n=e||{};this._level=n.level||T.DEBUG,this._clientLogger=n.logger||null,this._logsDestination=a,n.debug&&(this._logsDestination=l),n.logger&&(this._logsDestination=u)}}]),e}(),I=function(){function e(){w(this,e)}return h(e,[{key:"debug",value:function(){}},{key:"info",value:function(){}},{key:"warn",value:function(){}},{key:"error",value:function(){}}]),e}(),W=function(e){function n(e){var t;return w(this,n),(t=y(this,S(n).call(this))).prefix=e||"",t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),n&&k(e,n)}(n,I),h(n,[{key:"debug",value:function(){for(var e=arguments.length,n=new Array(e),t=0;t0&&void 0!==arguments[0]?arguments[0]:"";e.debug("["+n+"] Primary WebSocket: "+k(t.primary)+" | Secondary WebSocket: "+k(t.secondary))},v=function(e,n){return e&&e.readyState===n},h=function(e){return v(e,WebSocket.OPEN)},C=function(e){return null===e||void 0===e.readyState||v(e,WebSocket.CLOSED)},T=function(){return null!==t.secondary?t.secondary:t.primary},O=function(){return h(T())},I=function(){if(i.pendingResponse)return e.warn("Heartbeat response not received"),clearInterval(i.intervalHandle),i.pendingResponse=!1,void G();O()?(e.debug("Sending heartbeat"),T().send(P(d)),i.pendingResponse=!0):(e.warn("Failed to send heartbeat since WebSocket is not open"),w("sendHeartBeat"),G())},W=function(){o.exponentialBackOffTime=1e3,i.pendingResponse=!1,o.reconnectWebSocket=!0,clearTimeout(o.lifeTimeTimeoutHandle),clearInterval(i.intervalHandle),clearTimeout(o.exponentialTimeoutHandle),clearTimeout(o.webSocketInitCheckerTimeoutId)},N=function(){l.consecutiveFailedSubscribeAttempts=0,l.consecutiveNoResponseRequest=0,clearInterval(l.responseCheckIntervalId),clearInterval(l.reSubscribeIntervalId)},E=function(){r.connectWebSocketRetryCount=0,r.connectionAttemptStartTime=null,r.noOpenConnectionsTimestamp=null},L=function(){try{e.info("WebSocket connection established!"),w("webSocketOnOpen"),o.connState=b,null===t.secondary&&S(c.connectionGain);var n=Date.now();S(c.connectionOpen,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,noOpenConnectionsTimestamp:r.noOpenConnectionsTimestamp,connectionEstablishedTime:n,timeToConnect:n-r.connectionAttemptStartTime,timeWithoutConnection:r.noOpenConnectionsTimestamp?n-r.noOpenConnectionsTimestamp:null}),E(),W(),T().openTimestamp=Date.now(),0===u.subscribed.size&&h(t.secondary)&&j(t.primary,"[Primary WebSocket] Closing WebSocket"),(u.subscribed.size>0||u.pending.size>0)&&(h(t.secondary)&&e.info("Subscribing secondary websocket to topics of primary websocket"),u.subscribed.forEach(function(e){u.subscriptionHistory.add(e),u.pending.add(e)}),u.subscribed.clear(),R()),I(),i.intervalHandle=setInterval(I,1e4),o.lifeTimeTimeoutHandle=setTimeout(function(){e.debug("Starting scheduled WebSocket manager reconnect"),G()},1e3*a.connConfig.webSocketTransport.transportLifeTimeInSeconds)}catch(n){e.error("Error after establishing WebSocket connection",n)}},F=function(n){w("webSocketOnError"),e.error("WebSocketManager Error, error_event: ",n),G()},x=function(n){var o=JSON.parse(n.data);switch(o.topic){case f:if(e.debug("Subscription Message received from webSocket server",n.data),l.requestCompleted=!0,l.consecutiveNoResponseRequest=0,"success"===o.content.status)l.consecutiveFailedSubscribeAttempts=0,o.content.topics.forEach(function(e){u.subscriptionHistory.delete(e),u.pending.delete(e),u.subscribed.add(e)}),0===u.subscriptionHistory.size?h(t.secondary)&&(e.info("Successfully subscribed secondary websocket to all topics of primary websocket"),j(t.primary,"[Primary WebSocket] Closing WebSocket")):R(),S(c.subscriptionUpdate,o);else{if(clearInterval(l.reSubscribeIntervalId),++l.consecutiveFailedSubscribeAttempts,5===l.consecutiveFailedSubscribeAttempts)return S(c.subscriptionFailure,o),void(l.consecutiveFailedSubscribeAttempts=0);l.reSubscribeIntervalId=setInterval(function(){R()},500)}break;case d:e.debug("Heartbeat response received"),i.pendingResponse=!1;break;default:if(o.topic){if(e.debug("Message received for topic "+o.topic),h(t.primary)&&h(t.secondary)&&0===u.subscriptionHistory.size&&this===t.primary)return void e.warn("Ignoring Message for Topic "+o.topic+", to avoid duplicates");if(0===c.allMessage.size&&0===c.topic.size)return void e.warn("No registered callback listener for Topic",o.topic);S(c.allMessage,o),c.topic.has(o.topic)&&S(c.topic.get(o.topic),o)}else o.message?e.warn("WebSocketManager Message Error",o):e.warn("Invalid incoming message",o)}},R=function n(){if(l.consecutiveNoResponseRequest>3)return e.warn("Ignoring subscribePendingTopics since we have exhausted max subscription retries with no response"),void S(c.subscriptionFailure,s.getSubscriptionResponse(f,!1,Array.from(u.pending)));O()?(clearInterval(l.responseCheckIntervalId),T().send(P(f,{topics:Array.from(u.pending)})),l.requestCompleted=!1,l.responseCheckIntervalId=setInterval(function(){l.requestCompleted||(++l.consecutiveNoResponseRequest,n())},1e3)):e.warn("Ignoring subscribePendingTopics call since Default WebSocket is not open")},j=function(n,t){v(n,WebSocket.CONNECTING)||v(n,WebSocket.OPEN)?n.close(1e3,t):e.warn("Ignoring WebSocket Close request, WebSocket State: "+k(n))},A=function(e){j(t.primary,"[Primary] WebSocket "+e),j(t.secondary,"[Secondary] WebSocket "+e)},M=function(){r.connectWebSocketRetryCount++;var n=s.addJitter(o.exponentialBackOffTime,.3);Date.now()+n<=a.connConfig.urlConnValidTime?(e.debug("Scheduling WebSocket reinitialization, after delay "+n+" ms"),o.exponentialTimeoutHandle=setTimeout(function(){return z()},n),o.exponentialBackOffTime*=2):(e.warn("WebSocket URL is cannot be used to establish connection"),G())},D=function(n){W(),N(),e.error("WebSocket Initialization failed"),o.websocketInitFailed=!0,A("Terminating WebSocket Manager"),clearInterval(y),S(c.initFailure,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,reason:n}),E()},P=function(e,n){return JSON.stringify({topic:e,content:n})},H=function(n){return!!(s.isObject(n)&&s.isObject(n.webSocketTransport)&&s.isNonEmptyString(n.webSocketTransport.url)&&s.validWSUrl(n.webSocketTransport.url)&&1e3*n.webSocketTransport.transportLifeTimeInSeconds>=36e5)||(e.error("Invalid WebSocket Connection Configuration",n),!1)},G=function n(){if(s.isNetworkOnline())if(o.websocketInitFailed)e.debug("WebSocket Init had failed, ignoring this getWebSocketConnConfig request");else{if(a.promiseCompleted)return W(),e.info("Fetching new WebSocket connection configuration"),r.connectionAttemptStartTime=r.connectionAttemptStartTime||Date.now(),a.promiseCompleted=!1,a.promiseHandle=c.getWebSocketTransport(),a.promiseHandle.then(function(n){return a.promiseCompleted=!0,e.debug("Successfully fetched webSocket connection configuration",n),H(n)?(a.connConfig=n,a.connConfig.urlConnValidTime=Date.now()+85e3,z()):(D("Invalid WebSocket connection configuration: "+n),{webSocketConnectionFailed:!0})},function(t){return a.promiseCompleted=!0,e.error("Failed to fetch webSocket connection configuration",t),setTimeout(function(){return n()},s.addJitter(5e3,.3)),{webSocketConnectionFailed:!0}});e.debug("There is an ongoing getWebSocketConnConfig request, this request will be ignored")}else e.info("Network offline, ignoring this getWebSocketConnConfig request")},z=function(){if(o.websocketInitFailed)return e.info("web-socket initializing had failed, aborting re-init"),{webSocketConnectionFailed:!0};if(!s.isNetworkOnline())return e.warn("System is offline aborting web-socket init"),{webSocketConnectionFailed:!0};e.info("Initializing Websocket Manager"),w("initWebSocket");try{if(H(a.connConfig)){var n=null;return h(t.primary)?(e.debug("Primary Socket connection is already open"),v(t.secondary,WebSocket.CONNECTING)||(e.debug("Establishing a secondary web-socket connection"),t.secondary=U()),n=t.secondary):(v(t.primary,WebSocket.CONNECTING)||(e.debug("Establishing a primary web-socket connection"),t.primary=U()),n=t.primary),o.webSocketInitCheckerTimeoutId=setTimeout(function(){h(n)||M()},1e3),{webSocketConnectionFailed:!1}}}catch(n){return e.error("Error Initializing web-socket-manager",n),D("Failed to initialize new WebSocket: "+n.message),{webSocketConnectionFailed:!0}}},U=function(){var n=new WebSocket(a.connConfig.webSocketTransport.url);return n.addEventListener("open",L),n.addEventListener("message",x),n.addEventListener("error",F),n.addEventListener("close",function(i){return function(n,i){e.info("Socket connection is closed",n),w("webSocketOnClose before-cleanup"),S(c.connectionClose,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),C(t.primary)&&(t.primary=null),C(t.secondary)&&(t.secondary=null),o.reconnectWebSocket&&(h(t.primary)||h(t.secondary)?C(t.primary)&&h(t.secondary)&&(e.info("[Primary] WebSocket Cleanly Closed"),t.primary=t.secondary,t.secondary=null):(e.warn("Neither primary websocket and nor secondary websocket have open connections, attempting to re-establish connection"),o.connState!==g?(S(c.connectionLost,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),r.noOpenConnectionsTimestamp=Date.now()):e.info("Ignoring connectionLost callback invocation"),o.connState=g,G()),w("webSocketOnClose after-cleanup"))}(i,n)}),n};this.init=function(n){if(s.assertTrue(s.isFunction(n),"transportHandle must be a function"),null===c.getWebSocketTransport)return c.getWebSocketTransport=n,G();e.warn("Web Socket Manager was already initialized")},this.onInitFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.initFailure.add(e),o.websocketInitFailed&&e(),function(){return c.initFailure.delete(e)}},this.onConnectionOpen=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionOpen.add(e),function(){return c.connectionOpen.delete(e)}},this.onConnectionClose=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionClose.add(e),function(){return c.connectionClose.delete(e)}},this.onConnectionGain=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionGain.add(e),O()&&e(),function(){return c.connectionGain.delete(e)}},this.onConnectionLost=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionLost.add(e),o.connState===g&&e(),function(){return c.connectionLost.delete(e)}},this.onSubscriptionUpdate=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionUpdate.add(e),function(){return c.subscriptionUpdate.delete(e)}},this.onSubscriptionFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionFailure.add(e),function(){return c.subscriptionFailure.delete(e)}},this.onMessage=function(e,n){return s.assertNotNull(e,"topicName"),s.assertTrue(s.isFunction(n),"cb must be a function"),c.topic.has(e)?c.topic.get(e).add(n):c.topic.set(e,new Set([n])),function(){return c.topic.get(e).delete(n)}},this.onAllMessage=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.allMessage.add(e),function(){return c.allMessage.delete(e)}},this.subscribeTopics=function(e){s.assertNotNull(e,"topics"),s.assertIsList(e),e.forEach(function(e){u.subscribed.has(e)||u.pending.add(e)}),l.consecutiveNoResponseRequest=0,R()},this.sendMessage=function(n){if(s.assertIsObject(n,"payload"),void 0===n.topic||m.has(n.topic))e.warn("Cannot send message, Invalid topic",n);else{try{n=JSON.stringify(n)}catch(t){return void e.warn("Error stringify message",n)}O()?T().send(n):e.warn("Cannot send message, web socket connection is not open")}},this.closeWebSocket=function(){W(),N(),o.reconnectWebSocket=!1,clearInterval(y),A("User request to close WebSocket")},this.terminateWebSocketManager=D},L={create:function(){return new E},setGlobalConfig:function(e){var n=e.loggerConfig;_.updateLoggerConfig(n)},LogLevel:T,Logger:C}},function(e,n,t){var o;!function(){"use strict";var r={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function i(e){return function(e,n){var t,o,c,s,a,u,l,f,p,d=1,b=e.length,g="";for(o=0;o=0),s.type){case"b":t=parseInt(t,10).toString(2);break;case"c":t=String.fromCharCode(parseInt(t,10));break;case"d":case"i":t=parseInt(t,10);break;case"j":t=JSON.stringify(t,null,s.width?parseInt(s.width):0);break;case"e":t=s.precision?parseFloat(t).toExponential(s.precision):parseFloat(t).toExponential();break;case"f":t=s.precision?parseFloat(t).toFixed(s.precision):parseFloat(t);break;case"g":t=s.precision?String(Number(t.toPrecision(s.precision))):parseFloat(t);break;case"o":t=(parseInt(t,10)>>>0).toString(8);break;case"s":t=String(t),t=s.precision?t.substring(0,s.precision):t;break;case"t":t=String(!!t),t=s.precision?t.substring(0,s.precision):t;break;case"T":t=Object.prototype.toString.call(t).slice(8,-1).toLowerCase(),t=s.precision?t.substring(0,s.precision):t;break;case"u":t=parseInt(t,10)>>>0;break;case"v":t=t.valueOf(),t=s.precision?t.substring(0,s.precision):t;break;case"x":t=(parseInt(t,10)>>>0).toString(16);break;case"X":t=(parseInt(t,10)>>>0).toString(16).toUpperCase()}r.json.test(s.type)?g+=t:(!r.number.test(s.type)||f&&!s.sign?p="":(p=f?"+":"-",t=t.toString().replace(r.sign,"")),u=s.pad_char?"0"===s.pad_char?"0":s.pad_char.charAt(1):" ",l=s.width-(p+t).length,a=s.width&&l>0?u.repeat(l):"",g+=s.align?p+t+a:"0"===u?p+a+t:a+p+t)}return g}(function(e){if(s[e])return s[e];var n,t=e,o=[],i=0;for(;t;){if(null!==(n=r.text.exec(t)))o.push(n[0]);else if(null!==(n=r.modulo.exec(t)))o.push("%");else{if(null===(n=r.placeholder.exec(t)))throw new SyntaxError("[sprintf] unexpected placeholder");if(n[2]){i|=1;var c=[],a=n[2],u=[];if(null===(u=r.key.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(c.push(u[1]);""!==(a=a.substring(u[0].length));)if(null!==(u=r.key_access.exec(a)))c.push(u[1]);else{if(null===(u=r.index_access.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");c.push(u[1])}n[2]=c}else i|=2;if(3===i)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");o.push({placeholder:n[0],param_no:n[1],keys:n[2],sign:n[3],pad_char:n[4],align:n[5],width:n[6],precision:n[7],type:n[8]})}t=t.substring(n[0].length)}return s[e]=o}(e),arguments)}function c(e,n){return i.apply(null,[e].concat(n||[]))}var s=Object.create(null);n.sprintf=i,n.vsprintf=c,"undefined"!=typeof window&&(window.sprintf=i,window.vsprintf=c,void 0===(o=function(){return{sprintf:i,vsprintf:c}}.call(n,t,n,e))||(e.exports=o))}()},function(e,n,t){"use strict";t.r(n),function(e){t.d(n,"WebSocketManager",function(){return r});var o=t(0);e.connect=e.connect||{},connect.WebSocketManager=o.a;var r=o.a}.call(this,t(3))},function(e,n){var t;t=function(){return this}();try{t=t||new Function("return this")()}catch(e){"object"==typeof window&&(t=window)}e.exports=t}]); \ No newline at end of file +!function(e){var n={};function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:o})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(t.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)t.d(o,r,function(n){return e[n]}.bind(null,r));return o},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=2)}([function(e,n,t){"use strict";var o=t(1);function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i={assertTrue:function(e,n){if(!e)throw new Error(n)},assertNotNull:function(e,n){return i.assertTrue(null!==e&&void 0!==r(e),Object(o.sprintf)("%s must be provided",n||"A value")),e},isNonEmptyString:function(e){return"string"==typeof e&&e.length>0},assertIsList:function(e,n){if(!Array.isArray(e))throw new Error(n+" is not an array")},isFunction:function(e){return!!(e&&e.constructor&&e.call&&e.apply)},isObject:function(e){return!("object"!==r(e)||null===e)},isString:function(e){return"string"==typeof e},isNumber:function(e){return"number"==typeof e}},c=new RegExp("^(wss://)\\w*");i.validWSUrl=function(e){return c.test(e)},i.getSubscriptionResponse=function(e,n,t){return{topic:e,content:{status:n?"success":"failure",topics:t}}},i.assertIsObject=function(e,n){if(!i.isObject(e))throw new Error(n+" is not an object!")},i.addJitter=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;n=Math.min(n,1);var t=Math.random()>.5?1:-1;return Math.floor(e+t*e*Math.random()*n)},i.isNetworkOnline=function(){return navigator.onLine};var s=i,a="NULL",u="CLIENT_LOGGER",l="DEBUG",f="aws/subscribe",p="aws/unsubscribe",d="aws/heartbeat",b="connected",g="disconnected";function m(e){return(m="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function y(e,n){return!n||"object"!==m(n)&&"function"!=typeof n?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):n}function S(e){return(S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function k(e,n){return(k=Object.setPrototypeOf||function(e,n){return e.__proto__=n,e})(e,n)}function v(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function h(e,n){for(var t=0;t=this._level}},{key:"hasClientLogger",value:function(){return null!==this._clientLogger}},{key:"getLogger",value:function(e){var n=e.prefix||"";return this._logsDestination===l?this.consoleLoggerWrapper:new W(n)}},{key:"updateLoggerConfig",value:function(e){var n=e||{};this._level=n.level||T.DEBUG,this._clientLogger=n.logger||null,this._logsDestination=a,n.debug&&(this._logsDestination=l),n.logger&&(this._logsDestination=u)}}]),e}(),I=function(){function e(){v(this,e)}return w(e,[{key:"debug",value:function(){}},{key:"info",value:function(){}},{key:"warn",value:function(){}},{key:"error",value:function(){}}]),e}(),W=function(e){function n(e){var t;return v(this,n),(t=y(this,S(n).call(this))).prefix=e||"",t}return function(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),n&&k(e,n)}(n,I),w(n,[{key:"debug",value:function(){for(var e=arguments.length,n=new Array(e),t=0;t0&&void 0!==arguments[0]?arguments[0]:"";q(e.debug("["+n+"] Primary WebSocket: "+k(t.primary)+" | Secondary WebSocket: "+k(t.secondary)))},h=function(e,n){return e&&e.readyState===n},w=function(e){return h(e,WebSocket.OPEN)},C=function(e){return null===e||void 0===e.readyState||h(e,WebSocket.CLOSED)},T=function(){return null!==t.secondary?t.secondary:t.primary},O=function(){return w(T())},I=function(){if(i.pendingResponse)return q(e.warn("Heartbeat response not received")),clearInterval(i.intervalHandle),i.pendingResponse=!1,void G();O()?(q(e.debug("Sending heartbeat")),T().send(P(d)),i.pendingResponse=!0):(q(e.warn("Failed to send heartbeat since WebSocket is not open")),v("sendHeartBeat"),G())},W=function(){o.exponentialBackOffTime=1e3,i.pendingResponse=!1,o.reconnectWebSocket=!0,clearTimeout(o.lifeTimeTimeoutHandle),clearInterval(i.intervalHandle),clearTimeout(o.exponentialTimeoutHandle),clearTimeout(o.webSocketInitCheckerTimeoutId)},N=function(){l.consecutiveFailedSubscribeAttempts=0,l.consecutiveNoResponseRequest=0,clearInterval(l.responseCheckIntervalId),clearInterval(l.reSubscribeIntervalId)},E=function(){r.connectWebSocketRetryCount=0,r.connectionAttemptStartTime=null,r.noOpenConnectionsTimestamp=null},L=function(){try{q(e.info("WebSocket connection established!")),v("webSocketOnOpen"),null!==o.connState&&o.connState!==g||S(c.connectionGain),o.connState=b;var n=Date.now();S(c.connectionOpen,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,noOpenConnectionsTimestamp:r.noOpenConnectionsTimestamp,connectionEstablishedTime:n,timeToConnect:n-r.connectionAttemptStartTime,timeWithoutConnection:r.noOpenConnectionsTimestamp?n-r.noOpenConnectionsTimestamp:null}),E(),W(),T().openTimestamp=Date.now(),0===u.subscribed.size&&w(t.secondary)&&j(t.primary,"[Primary WebSocket] Closing WebSocket"),(u.subscribed.size>0||u.pending.size>0)&&(w(t.secondary)&&q(e.info("Subscribing secondary websocket to topics of primary websocket")),u.subscribed.forEach(function(e){u.subscriptionHistory.add(e),u.pending.add(e)}),u.subscribed.clear(),R()),I(),i.intervalHandle=setInterval(I,1e4);var l=Math.min(s.addJitter(3e6,.1),1e3*a.connConfig.webSocketTransport.transportLifeTimeInSeconds);q(e.debug("Scheduling WebSocket manager reconnection, after delay "+l+" ms")),o.lifeTimeTimeoutHandle=setTimeout(function(){q(e.debug("Starting scheduled WebSocket manager reconnection")),G()},l)}catch(n){q(e.error("Error after establishing WebSocket connection",n))}},F=function(n){v("webSocketOnError"),q(e.error("WebSocketManager Error, error_event: ",JSON.stringify(n))),G()},x=function(n){var o=JSON.parse(n.data);switch(o.topic){case f:if(q(e.debug("Subscription Message received from webSocket server",n.data)),l.requestCompleted=!0,l.consecutiveNoResponseRequest=0,"success"===o.content.status)l.consecutiveFailedSubscribeAttempts=0,o.content.topics.forEach(function(e){u.subscriptionHistory.delete(e),u.pending.delete(e),u.subscribed.add(e)}),0===u.subscriptionHistory.size?w(t.secondary)&&(q(e.info("Successfully subscribed secondary websocket to all topics of primary websocket")),j(t.primary,"[Primary WebSocket] Closing WebSocket")):R(),S(c.subscriptionUpdate,o);else{if(clearInterval(l.reSubscribeIntervalId),++l.consecutiveFailedSubscribeAttempts,5===l.consecutiveFailedSubscribeAttempts)return S(c.subscriptionFailure,o),void(l.consecutiveFailedSubscribeAttempts=0);l.reSubscribeIntervalId=setInterval(function(){R()},500)}break;case d:q(e.debug("Heartbeat response received")),i.pendingResponse=!1;break;default:if(o.topic){if(q(e.debug("Message received for topic "+o.topic)),w(t.primary)&&w(t.secondary)&&0===u.subscriptionHistory.size&&this===t.primary)return void q(e.warn("Ignoring Message for Topic "+o.topic+", to avoid duplicates"));if(0===c.allMessage.size&&0===c.topic.size)return void q(e.warn("No registered callback listener for Topic",o.topic));S(c.allMessage,o),c.topic.has(o.topic)&&S(c.topic.get(o.topic),o)}else o.message?q(e.warn("WebSocketManager Message Error",o)):q(e.warn("Invalid incoming message",o))}},R=function n(){if(l.consecutiveNoResponseRequest>3)return q(e.warn("Ignoring subscribePendingTopics since we have exhausted max subscription retries with no response")),void S(c.subscriptionFailure,s.getSubscriptionResponse(f,!1,Array.from(u.pending)));O()?(clearInterval(l.responseCheckIntervalId),T().send(P(f,{topics:Array.from(u.pending)})),l.requestCompleted=!1,l.responseCheckIntervalId=setInterval(function(){l.requestCompleted||(++l.consecutiveNoResponseRequest,n())},1e3)):q(e.warn("Ignoring subscribePendingTopics call since Default WebSocket is not open"))},j=function(n,t){h(n,WebSocket.CONNECTING)||h(n,WebSocket.OPEN)?n.close(1e3,t):q(e.warn("Ignoring WebSocket Close request, WebSocket State: "+k(n)))},M=function(e){j(t.primary,"[Primary] WebSocket "+e),j(t.secondary,"[Secondary] WebSocket "+e)},A=function(){r.connectWebSocketRetryCount++;var n=s.addJitter(o.exponentialBackOffTime,.3);Date.now()+n<=a.connConfig.urlConnValidTime?(q(e.debug("Scheduling WebSocket reinitialization, after delay "+n+" ms")),o.exponentialTimeoutHandle=setTimeout(function(){return z()},n),o.exponentialBackOffTime*=2):(q(e.warn("WebSocket URL cannot be used to establish connection")),G())},D=function(n){W(),N(),q(e.error("WebSocket Initialization failed")),o.websocketInitFailed=!0,M("Terminating WebSocket Manager"),clearInterval(y),S(c.initFailure,{connectWebSocketRetryCount:r.connectWebSocketRetryCount,connectionAttemptStartTime:r.connectionAttemptStartTime,reason:n}),E()},P=function(e,n){return JSON.stringify({topic:e,content:n})},H=function(n){return!!(s.isObject(n)&&s.isObject(n.webSocketTransport)&&s.isNonEmptyString(n.webSocketTransport.url)&&s.validWSUrl(n.webSocketTransport.url)&&1e3*n.webSocketTransport.transportLifeTimeInSeconds>=3e5)||(q(e.error("Invalid WebSocket Connection Configuration",n)),!1)},G=function(){if(s.isNetworkOnline())if(o.websocketInitFailed)q(e.debug("WebSocket Init had failed, ignoring this getWebSocketConnConfig request"));else{if(a.promiseCompleted)return W(),q(e.info("Fetching new WebSocket connection configuration")),r.connectionAttemptStartTime=r.connectionAttemptStartTime||Date.now(),a.promiseCompleted=!1,a.promiseHandle=c.getWebSocketTransport(),a.promiseHandle.then(function(n){return a.promiseCompleted=!0,q(e.debug("Successfully fetched webSocket connection configuration",n)),H(n)?(a.connConfig=n,a.connConfig.urlConnValidTime=Date.now()+85e3,z()):(D("Invalid WebSocket connection configuration: "+n),{webSocketConnectionFailed:!0})},function(n){return a.promiseCompleted=!0,q(e.error("Failed to fetch webSocket connection configuration",n)),{webSocketConnectionFailed:!0}});q(e.debug("There is an ongoing getWebSocketConnConfig request, this request will be ignored"))}else q(e.info("Network offline, ignoring this getWebSocketConnConfig request"))},z=function(){if(o.websocketInitFailed)return q(e.info("web-socket initializing had failed, aborting re-init")),{webSocketConnectionFailed:!0};if(!s.isNetworkOnline())return q(e.warn("System is offline aborting web-socket init")),{webSocketConnectionFailed:!0};q(e.info("Initializing Websocket Manager")),v("initWebSocket");try{if(H(a.connConfig)){var n=null;return w(t.primary)?(q(e.debug("Primary Socket connection is already open")),h(t.secondary,WebSocket.CONNECTING)||(q(e.debug("Establishing a secondary web-socket connection")),t.secondary=U()),n=t.secondary):(h(t.primary,WebSocket.CONNECTING)||(q(e.debug("Establishing a primary web-socket connection")),t.primary=U()),n=t.primary),o.webSocketInitCheckerTimeoutId=setTimeout(function(){w(n)||A()},1e3),{webSocketConnectionFailed:!1}}}catch(n){return q(e.error("Error Initializing web-socket-manager",n)),D("Failed to initialize new WebSocket: "+n.message),{webSocketConnectionFailed:!0}}},U=function(){var n=new WebSocket(a.connConfig.webSocketTransport.url);return n.addEventListener("open",L),n.addEventListener("message",x),n.addEventListener("error",F),n.addEventListener("close",function(i){return function(n,i){q(e.info("Socket connection is closed",n)),v("webSocketOnClose before-cleanup"),S(c.connectionClose,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),C(t.primary)&&(t.primary=null),C(t.secondary)&&(t.secondary=null),o.reconnectWebSocket&&(w(t.primary)||w(t.secondary)?C(t.primary)&&w(t.secondary)&&(q(e.info("[Primary] WebSocket Cleanly Closed")),t.primary=t.secondary,t.secondary=null):(q(e.warn("Neither primary websocket and nor secondary websocket have open connections, attempting to re-establish connection")),o.connState===g?q(e.info("Ignoring connectionLost callback invocation")):(S(c.connectionLost,{openTimestamp:i.openTimestamp,closeTimestamp:Date.now(),connectionDuration:Date.now()-i.openTimestamp,code:n.code,reason:n.reason}),r.noOpenConnectionsTimestamp=Date.now()),o.connState=g,G()),v("webSocketOnClose after-cleanup"))}(i,n)}),n},q=function(e){return e&&"function"==typeof e.sendInternalLogToServer&&e.sendInternalLogToServer(),e};this.init=function(n){if(s.assertTrue(s.isFunction(n),"transportHandle must be a function"),null===c.getWebSocketTransport)return c.getWebSocketTransport=n,G();q(e.warn("Web Socket Manager was already initialized"))},this.onInitFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.initFailure.add(e),o.websocketInitFailed&&e(),function(){return c.initFailure.delete(e)}},this.onConnectionOpen=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionOpen.add(e),function(){return c.connectionOpen.delete(e)}},this.onConnectionClose=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionClose.add(e),function(){return c.connectionClose.delete(e)}},this.onConnectionGain=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionGain.add(e),O()&&e(),function(){return c.connectionGain.delete(e)}},this.onConnectionLost=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.connectionLost.add(e),o.connState===g&&e(),function(){return c.connectionLost.delete(e)}},this.onSubscriptionUpdate=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionUpdate.add(e),function(){return c.subscriptionUpdate.delete(e)}},this.onSubscriptionFailure=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.subscriptionFailure.add(e),function(){return c.subscriptionFailure.delete(e)}},this.onMessage=function(e,n){return s.assertNotNull(e,"topicName"),s.assertTrue(s.isFunction(n),"cb must be a function"),c.topic.has(e)?c.topic.get(e).add(n):c.topic.set(e,new Set([n])),function(){return c.topic.get(e).delete(n)}},this.onAllMessage=function(e){return s.assertTrue(s.isFunction(e),"cb must be a function"),c.allMessage.add(e),function(){return c.allMessage.delete(e)}},this.subscribeTopics=function(e){s.assertNotNull(e,"topics"),s.assertIsList(e),e.forEach(function(e){u.subscribed.has(e)||u.pending.add(e)}),l.consecutiveNoResponseRequest=0,R()},this.sendMessage=function(n){if(s.assertIsObject(n,"payload"),void 0===n.topic||m.has(n.topic))q(e.warn("Cannot send message, Invalid topic",n));else{try{n=JSON.stringify(n)}catch(t){return void q(e.warn("Error stringify message",n))}O()?T().send(n):q(e.warn("Cannot send message, web socket connection is not open"))}},this.closeWebSocket=function(){W(),N(),o.reconnectWebSocket=!1,clearInterval(y),M("User request to close WebSocket")},this.terminateWebSocketManager=D},L={create:function(){return new E},setGlobalConfig:function(e){var n=e.loggerConfig;_.updateLoggerConfig(n)},LogLevel:T,Logger:C}},function(e,n,t){var o;!function(){"use strict";var r={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function i(e){return function(e,n){var t,o,c,s,a,u,l,f,p,d=1,b=e.length,g="";for(o=0;o=0),s.type){case"b":t=parseInt(t,10).toString(2);break;case"c":t=String.fromCharCode(parseInt(t,10));break;case"d":case"i":t=parseInt(t,10);break;case"j":t=JSON.stringify(t,null,s.width?parseInt(s.width):0);break;case"e":t=s.precision?parseFloat(t).toExponential(s.precision):parseFloat(t).toExponential();break;case"f":t=s.precision?parseFloat(t).toFixed(s.precision):parseFloat(t);break;case"g":t=s.precision?String(Number(t.toPrecision(s.precision))):parseFloat(t);break;case"o":t=(parseInt(t,10)>>>0).toString(8);break;case"s":t=String(t),t=s.precision?t.substring(0,s.precision):t;break;case"t":t=String(!!t),t=s.precision?t.substring(0,s.precision):t;break;case"T":t=Object.prototype.toString.call(t).slice(8,-1).toLowerCase(),t=s.precision?t.substring(0,s.precision):t;break;case"u":t=parseInt(t,10)>>>0;break;case"v":t=t.valueOf(),t=s.precision?t.substring(0,s.precision):t;break;case"x":t=(parseInt(t,10)>>>0).toString(16);break;case"X":t=(parseInt(t,10)>>>0).toString(16).toUpperCase()}r.json.test(s.type)?g+=t:(!r.number.test(s.type)||f&&!s.sign?p="":(p=f?"+":"-",t=t.toString().replace(r.sign,"")),u=s.pad_char?"0"===s.pad_char?"0":s.pad_char.charAt(1):" ",l=s.width-(p+t).length,a=s.width&&l>0?u.repeat(l):"",g+=s.align?p+t+a:"0"===u?p+a+t:a+p+t)}return g}(function(e){if(s[e])return s[e];var n,t=e,o=[],i=0;for(;t;){if(null!==(n=r.text.exec(t)))o.push(n[0]);else if(null!==(n=r.modulo.exec(t)))o.push("%");else{if(null===(n=r.placeholder.exec(t)))throw new SyntaxError("[sprintf] unexpected placeholder");if(n[2]){i|=1;var c=[],a=n[2],u=[];if(null===(u=r.key.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(c.push(u[1]);""!==(a=a.substring(u[0].length));)if(null!==(u=r.key_access.exec(a)))c.push(u[1]);else{if(null===(u=r.index_access.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");c.push(u[1])}n[2]=c}else i|=2;if(3===i)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");o.push({placeholder:n[0],param_no:n[1],keys:n[2],sign:n[3],pad_char:n[4],align:n[5],width:n[6],precision:n[7],type:n[8]})}t=t.substring(n[0].length)}return s[e]=o}(e),arguments)}function c(e,n){return i.apply(null,[e].concat(n||[]))}var s=Object.create(null);n.sprintf=i,n.vsprintf=c,"undefined"!=typeof window&&(window.sprintf=i,window.vsprintf=c,void 0===(o=function(){return{sprintf:i,vsprintf:c}}.call(n,t,n,e))||(e.exports=o))}()},function(e,n,t){"use strict";t.r(n),function(e){t.d(n,"WebSocketManager",function(){return r});var o=t(0);e.connect=e.connect||{},connect.WebSocketManager=o.a;var r=o.a}.call(this,t(3))},function(e,n){var t;t=function(){return this}();try{t=t||new Function("return this")()}catch(e){"object"==typeof window&&(t=window)}e.exports=t}]); +//# sourceMappingURL=amazon-connect-websocket-manager.js.map diff --git a/src/lib/amazon-connect-websocket-manager.js.map b/src/lib/amazon-connect-websocket-manager.js.map index 71ba1194..cc20dd65 100644 --- a/src/lib/amazon-connect-websocket-manager.js.map +++ b/src/lib/amazon-connect-websocket-manager.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/utils.js","webpack:///./src/constants.js","webpack:///./src/log.js","webpack:///./src/webSocketManager.js","webpack:///./node_modules/sprintf-js/src/sprintf.js","webpack:///./src/index.js","webpack:///(webpack)/buildin/global.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","Utils","premise","message","Error","assertTrue","undefined","_typeof","sprintf","length","Array","isArray","obj","constructor","apply","wsRegex","RegExp","validWSUrl","wsUrl","test","getSubscriptionResponse","routeKey","isSuccess","topicList","topic","content","status","topics","assertIsObject","isObject","addJitter","base","maxJitter","arguments","Math","min","sign","random","floor","isNetworkOnline","navigator","onLine","LOGS_DESTINATION","ROUTE_KEY","CONN_STATE","Logger","data","LogLevel","DEBUG","INFO","WARN","ERROR","LogManagerImpl","_classCallCheck","this","updateLoggerConfig","consoleLoggerWrapper","createConsoleLogger","level","logStatement","hasClientLogger","_clientLogger","debug","info","warn","error","_level","options","prefix","_logsDestination","LoggerWrapperImpl","inputConfig","config","logger","LoggerWrapper","_this","_possibleConstructorReturn","_getPrototypeOf","_len","args","_key","_log","_len2","_key2","_len3","_key3","_len4","_key4","LogManager","isLevelEnabled","writeToClientLogger","_shouldLog","_convertToSingleStatement","_writeToClientLogger","index","arg","_convertToString","isString","isFunction","toString","toStringResult","JSON","stringify","console","__webpack_exports__","WebSocketManagerObject","WebSocketManager","getLogger","online","webSocket","primary","secondary","reconnectConfig","reconnectWebSocket","websocketInitFailed","exponentialBackOffTime","exponentialTimeoutHandle","lifeTimeTimeoutHandle","webSocketInitCheckerTimeoutId","connState","metrics","connectWebSocketRetryCount","connectionAttemptStartTime","noOpenConnectionsTimestamp","heartbeatConfig","pendingResponse","intervalHandle","callbacks","initFailure","Set","getWebSocketTransport","subscriptionUpdate","subscriptionFailure","Map","allMessage","connectionGain","connectionLost","connectionOpen","connectionClose","webSocketConfig","connConfig","promiseHandle","promiseCompleted","topicSubscription","subscribed","pending","subscriptionHistory","topicSubscriptionConfig","responseCheckIntervalId","requestCompleted","reSubscribeIntervalId","consecutiveFailedSubscribeAttempts","consecutiveNoResponseRequest","invalidSendMessageRouteKeys","networkConnectivityChecker","setInterval","ws","getDefaultWebSocket","isWebSocketState","WebSocket","CLOSING","CLOSED","getWebSocketConnConfig","invokeCallbacks","response","forEach","callback","getWebSocketStates","readyState","CONNECTING","OPEN","printWebSocketState","event","webSocketStateCode","isWebSocketOpen","isWebSocketClosed","isDefaultWebSocketOpen","sendHeartBeat","clearInterval","send","createWebSocketPayload","resetWebSocketState","clearTimeout","resetSubscriptions","resetMetrics","webSocketOnOpen","now","Date","connectionEstablishedTime","timeToConnect","timeWithoutConnection","openTimestamp","size","closeSpecificWebSocket","add","clear","subscribePendingTopics","setTimeout","webSocketTransport","transportLifeTimeInSeconds","webSocketOnError","webSocketOnMessage","parse","topicName","has","from","reason","close","closeWebSocket","retryWebSocketInitialization","waitTime","urlConnValidTime","initWebSocket","terminateWebSocketManager","validWebSocketConnConfig","isNonEmptyString","url","then","webSocketConnectionFailed","getNewWebSocket","addEventListener","closeTimestamp","connectionDuration","code","webSocketOnClose","init","transportHandle","onInitFailure","cb","onConnectionOpen","onConnectionClose","onConnectionGain","onConnectionLost","onSubscriptionUpdate","onSubscriptionFailure","onMessage","assertNotNull","set","onAllMessage","subscribeTopics","assertIsList","sendMessage","payload","setGlobalConfig","loggerConfig","__WEBPACK_AMD_DEFINE_RESULT__","re","not_string","not_bool","not_type","not_primitive","number","numeric_arg","json","not_json","text","modulo","placeholder","key_access","index_access","parse_tree","argv","k","ph","pad","pad_character","pad_length","is_positive","cursor","tree_length","output","keys","param_no","type","Function","isNaN","TypeError","parseInt","String","fromCharCode","width","precision","parseFloat","toExponential","toFixed","Number","toPrecision","substring","slice","toLowerCase","valueOf","toUpperCase","replace","pad_char","charAt","repeat","align","sprintf_format","fmt","sprintf_cache","match","_fmt","arg_names","exec","push","SyntaxError","field_list","replacement_field","field_match","sprintf_parse","vsprintf","concat","window","global","_webSocketManager__WEBPACK_IMPORTED_MODULE_0__","connect","g","e"],"mappings":"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","file":"amazon-connect-websocket-manager.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","import { sprintf } from \"sprintf-js\";\nconst Utils = {};\n\n/**\n * Asserts that a premise is true.\n */\nUtils.assertTrue = function(premise, message) {\n if (!premise) {\n throw new Error(message);\n }\n};\n\n/**\n * Asserts that a value is not null or undefined.\n */\nUtils.assertNotNull = function(value, name) {\n Utils.assertTrue(\n value !== null && typeof value !== undefined,\n sprintf(\"%s must be provided\", name || \"A value\")\n );\n return value;\n};\n\nUtils.isNonEmptyString = function(value) {\n return typeof value === \"string\" && value.length > 0;\n};\n\nUtils.assertIsList = function(value, key) {\n if (!Array.isArray(value)) {\n throw new Error(key + \" is not an array\");\n }\n};\n\n/**\n * Determine if the given value is a callable function type.\n * Borrowed from Underscore.js.\n */\nUtils.isFunction = function(obj) {\n return !!(obj && obj.constructor && obj.call && obj.apply);\n};\n\nUtils.isObject = function(value) {\n return !(typeof value !== \"object\" || value === null);\n};\n\nUtils.isString = function(value) {\n return typeof value === \"string\";\n};\n\nUtils.isNumber = function(value) {\n return typeof value === \"number\";\n};\n\nconst wsRegex = new RegExp(\"^(wss://)\\\\w*\");\nUtils.validWSUrl = function (wsUrl) {\n return wsRegex.test(wsUrl);\n};\n\nUtils.getSubscriptionResponse = (routeKey, isSuccess, topicList) => {\n return {\n topic: routeKey,\n content : {\n status: isSuccess ? \"success\" : \"failure\",\n topics: topicList\n }\n };\n};\n\nUtils.assertIsObject = function(value, key) {\n if (!Utils.isObject(value)) {\n throw new Error(key + \" is not an object!\");\n }\n};\n\nUtils.addJitter = function (base, maxJitter = 1) {\n maxJitter = Math.min(maxJitter, 1.0);\n const sign = Math.random() > 0.5 ? 1 : -1;\n return Math.floor(base + sign * base * Math.random() * maxJitter);\n};\n\nUtils.isNetworkOnline = () => navigator.onLine;\n\nexport default Utils;\n\n","\nexport const LOGS_DESTINATION = {\n NULL: \"NULL\",\n CLIENT_LOGGER: \"CLIENT_LOGGER\",\n DEBUG: \"DEBUG\"\n};\n\nexport const MIN_WEBSOCKET_LIFETIME_MS = 3600000;\nexport const HEARTBEAT_INTERVAL_MS = 10000;\nexport const GET_WEBSOCKET_CONNECTION_INTERVAL_MS = 5000;\nexport const WEBSOCKET_URL_VALID_TIME_MS = 85000;\nexport const TOPIC_SUBSCRIPTION_RETRY_INTERVAL_MS = 500;\nexport const MAX_CONSECUTIVE_FAILED_SUB_ATTEMPTS = 5;\nexport const MAX_WAIT_TIME_SUB_REQUEST_WITH_NO_RESPONSE_MS = 1000;\nexport const MAX_CONSECUTIVE_SUB_REQUEST_WITH_NO_RESPONSE = 3;\nexport const NETWORK_CONN_CHECK_INTERVAL_MS = 250;\nexport const WEBSOCKET_REINIT_JITTER = 0.3;\nexport const WEBSOCKET_CONN_CONFIG_JITTER = 0.3;\n\nexport const ROUTE_KEY = {\n SUBSCRIBE: \"aws/subscribe\",\n UNSUBSCRIBE: \"aws/unsubscribe\",\n HEARTBEAT: \"aws/heartbeat\"\n};\n\nexport const CONN_STATE = {\n CONNECTED: \"connected\",\n DISCONNECTED: \"disconnected\"\n};\n","import Utils from \"./utils\";\nimport { LOGS_DESTINATION } from \"./constants\";\n\n/*eslint-disable no-unused-vars*/\nclass Logger {\n debug(data) {}\n\n info(data) {}\n\n warn(data) {}\n\n error(data) {}\n}\n/*eslint-enable no-unused-vars*/\n\nconst LogLevel = {\n DEBUG: 10,\n INFO: 20,\n WARN: 30,\n ERROR: 40\n};\n\nclass LogManagerImpl {\n constructor() {\n this.updateLoggerConfig();\n this.consoleLoggerWrapper = createConsoleLogger();\n }\n\n writeToClientLogger(level, logStatement) {\n if (!this.hasClientLogger()) {\n return;\n }\n switch (level) {\n case LogLevel.DEBUG:\n return this._clientLogger.debug(logStatement);\n case LogLevel.INFO:\n return this._clientLogger.info(logStatement);\n case LogLevel.WARN:\n return this._clientLogger.warn(logStatement);\n case LogLevel.ERROR:\n return this._clientLogger.error(logStatement);\n }\n }\n\n isLevelEnabled(level) {\n return level >= this._level;\n }\n\n hasClientLogger() {\n return this._clientLogger !== null;\n }\n\n getLogger(options) {\n var prefix = options.prefix || \"\";\n if (this._logsDestination === LOGS_DESTINATION.DEBUG) {\n return this.consoleLoggerWrapper;\n }\n return new LoggerWrapperImpl(prefix);\n }\n\n updateLoggerConfig(inputConfig) {\n var config = inputConfig || {};\n this._level = config.level || LogLevel.DEBUG;\n this._clientLogger = config.logger || null;\n this._logsDestination = LOGS_DESTINATION.NULL;\n if (config.debug) {\n this._logsDestination = LOGS_DESTINATION.DEBUG;\n }\n if (config.logger) {\n this._logsDestination = LOGS_DESTINATION.CLIENT_LOGGER;\n }\n }\n}\n\nclass LoggerWrapper {\n debug() {}\n\n info() {}\n\n warn() {}\n\n error() {}\n}\n\nclass LoggerWrapperImpl extends LoggerWrapper {\n constructor(prefix) {\n super();\n this.prefix = prefix || \"\";\n }\n\n debug(...args) {\n this._log(LogLevel.DEBUG, args);\n }\n\n info(...args) {\n this._log(LogLevel.INFO, args);\n }\n\n warn(...args) {\n this._log(LogLevel.WARN, args);\n }\n\n error(...args) {\n this._log(LogLevel.ERROR, args);\n }\n\n _shouldLog(level) {\n return LogManager.hasClientLogger() && LogManager.isLevelEnabled(level);\n }\n\n _writeToClientLogger(level, logStatement) {\n LogManager.writeToClientLogger(level, logStatement);\n }\n\n _log(level, args) {\n if (this._shouldLog(level)) {\n var logStatement = this._convertToSingleStatement(args);\n this._writeToClientLogger(level, logStatement);\n }\n }\n\n _convertToSingleStatement(args) {\n var logStatement = \"\";\n if (this.prefix) {\n logStatement += this.prefix + \" \";\n }\n for (var index = 0; index < args.length; index++) {\n var arg = args[index];\n logStatement += this._convertToString(arg) + \" \";\n }\n return logStatement;\n }\n\n _convertToString(arg) {\n try {\n if (!arg) {\n return \"\";\n }\n if (Utils.isString(arg)) {\n return arg;\n }\n if (Utils.isObject(arg) && Utils.isFunction(arg.toString)) {\n var toStringResult = arg.toString();\n if (toStringResult !== \"[object Object]\") {\n return toStringResult;\n }\n }\n return JSON.stringify(arg);\n } catch (error) {\n console.error(\"Error while converting argument to string\", arg, error);\n return \"\";\n }\n }\n}\n\nvar createConsoleLogger = () => {\n var logger = new LoggerWrapper();\n logger.debug = console.debug;\n logger.info = console.info;\n logger.warn = console.warn;\n logger.error = console.error;\n return logger;\n};\n\nconst LogManager = new LogManagerImpl();\n\nexport { LogManager, Logger, LogLevel };\n","import Utils from \"./utils\";\nimport { LogManager, LogLevel, Logger } from \"./log\";\nimport {\n MIN_WEBSOCKET_LIFETIME_MS,\n GET_WEBSOCKET_CONNECTION_INTERVAL_MS,\n WEBSOCKET_URL_VALID_TIME_MS,\n HEARTBEAT_INTERVAL_MS,\n ROUTE_KEY,\n CONN_STATE,\n MAX_CONSECUTIVE_FAILED_SUB_ATTEMPTS,\n TOPIC_SUBSCRIPTION_RETRY_INTERVAL_MS,\n MAX_WAIT_TIME_SUB_REQUEST_WITH_NO_RESPONSE_MS,\n MAX_CONSECUTIVE_SUB_REQUEST_WITH_NO_RESPONSE,\n NETWORK_CONN_CHECK_INTERVAL_MS,\n WEBSOCKET_REINIT_JITTER,\n WEBSOCKET_CONN_CONFIG_JITTER\n} from \"./constants\";\n\n\nconst WebSocketManager = function() {\n\n const logger = LogManager.getLogger({});\n\n let online = Utils.isNetworkOnline();\n\n let webSocket = {\n primary: null,\n secondary: null\n };\n\n let reconnectConfig = {\n reconnectWebSocket: true,\n websocketInitFailed: false,\n exponentialBackOffTime: 1000,\n exponentialTimeoutHandle: null,\n lifeTimeTimeoutHandle: null,\n webSocketInitCheckerTimeoutId: null,\n connState: null\n };\n\n let metrics = {\n connectWebSocketRetryCount: 0,\n connectionAttemptStartTime: null,\n noOpenConnectionsTimestamp: null\n };\n\n let heartbeatConfig = {\n pendingResponse: false,\n intervalHandle: null\n };\n\n let callbacks = {\n initFailure: new Set(),\n getWebSocketTransport: null,\n subscriptionUpdate: new Set(),\n subscriptionFailure: new Set(),\n topic: new Map(),\n allMessage: new Set(),\n connectionGain: new Set(),\n connectionLost: new Set(),\n connectionOpen: new Set(),\n connectionClose: new Set()\n };\n\n let webSocketConfig = {\n connConfig: null,\n promiseHandle: null,\n promiseCompleted: true\n };\n\n let topicSubscription = {\n subscribed: new Set(),\n pending: new Set(),\n subscriptionHistory: new Set()\n };\n\n let topicSubscriptionConfig = {\n responseCheckIntervalId: null,\n requestCompleted: true,\n reSubscribeIntervalId: null,\n consecutiveFailedSubscribeAttempts: 0,\n consecutiveNoResponseRequest: 0\n };\n\n const invalidSendMessageRouteKeys = new Set([ROUTE_KEY.SUBSCRIBE, ROUTE_KEY.UNSUBSCRIBE, ROUTE_KEY.HEARTBEAT]);\n\n const networkConnectivityChecker = setInterval(function () {\n if (online !== Utils.isNetworkOnline()) {\n online = Utils.isNetworkOnline();\n if (!online) {\n logger.info(\"Network offline\");\n return;\n }\n const ws = getDefaultWebSocket();\n if (online && (!ws || isWebSocketState(ws, WebSocket.CLOSING) || isWebSocketState(ws, WebSocket.CLOSED))) {\n logger.info(\"Network online, connecting to WebSocket server\");\n getWebSocketConnConfig();\n }\n }\n }, NETWORK_CONN_CHECK_INTERVAL_MS);\n\n const invokeCallbacks = function(callbacks, response) {\n callbacks.forEach(function (callback) {\n try {\n callback(response);\n } catch (error) {\n logger.error(\"Error executing callback\", error);\n }\n });\n };\n\n const getWebSocketStates = function(ws) {\n if (ws === null) return \"NULL\";\n switch (ws.readyState) {\n case WebSocket.CONNECTING:\n return \"CONNECTING\";\n case WebSocket.OPEN:\n return \"OPEN\";\n case WebSocket.CLOSING:\n return \"CLOSING\";\n case WebSocket.CLOSED:\n return \"CLOSED\";\n default:\n return \"UNDEFINED\";\n }\n };\n\n const printWebSocketState = function (event = \"\") {\n logger.debug(\"[\" + event + \"] Primary WebSocket: \" + getWebSocketStates(webSocket.primary)\n + \" | \" + \"Secondary WebSocket: \" + getWebSocketStates(webSocket.secondary) );\n };\n\n const isWebSocketState = function(ws, webSocketStateCode) {\n return ws && ws.readyState === webSocketStateCode;\n };\n\n const isWebSocketOpen = function(ws) {\n return isWebSocketState(ws, WebSocket.OPEN);\n };\n\n const isWebSocketClosed = function(ws) {\n // undefined check is to address the limitation of testing framework\n return ws === null || ws.readyState === undefined || isWebSocketState(ws, WebSocket.CLOSED);\n };\n\n /**\n * This function is meant to handle the scenario when we have two web-sockets open\n * in such a scenario we always select secondary web-socket since all future operations\n * are supposed to be done by this secondary web-socket\n */\n const getDefaultWebSocket = function() {\n if (webSocket.secondary !== null) {\n return webSocket.secondary;\n }\n return webSocket.primary;\n };\n\n const isDefaultWebSocketOpen = function() {\n return isWebSocketOpen(getDefaultWebSocket());\n };\n\n const sendHeartBeat = function() {\n if (heartbeatConfig.pendingResponse) {\n logger.warn(\"Heartbeat response not received\");\n clearInterval(heartbeatConfig.intervalHandle);\n heartbeatConfig.pendingResponse = false;\n getWebSocketConnConfig();\n return;\n }\n if (isDefaultWebSocketOpen()) {\n logger.debug(\"Sending heartbeat\");\n getDefaultWebSocket().send(createWebSocketPayload(ROUTE_KEY.HEARTBEAT));\n heartbeatConfig.pendingResponse = true;\n } else {\n logger.warn(\"Failed to send heartbeat since WebSocket is not open\");\n printWebSocketState(\"sendHeartBeat\");\n getWebSocketConnConfig();\n }\n };\n\n const resetWebSocketState = function() {\n reconnectConfig.exponentialBackOffTime = 1000;\n heartbeatConfig.pendingResponse = false;\n reconnectConfig.reconnectWebSocket = true;\n\n clearTimeout(reconnectConfig.lifeTimeTimeoutHandle);\n clearInterval(heartbeatConfig.intervalHandle);\n clearTimeout(reconnectConfig.exponentialTimeoutHandle);\n clearTimeout(reconnectConfig.webSocketInitCheckerTimeoutId);\n };\n\n const resetSubscriptions = function() {\n topicSubscriptionConfig.consecutiveFailedSubscribeAttempts = 0;\n topicSubscriptionConfig.consecutiveNoResponseRequest = 0;\n clearInterval(topicSubscriptionConfig.responseCheckIntervalId);\n clearInterval(topicSubscriptionConfig.reSubscribeIntervalId);\n };\n\n const resetMetrics = function() {\n metrics.connectWebSocketRetryCount = 0;\n metrics.connectionAttemptStartTime = null;\n metrics.noOpenConnectionsTimestamp = null;\n };\n\n const webSocketOnOpen = function() {\n try {\n logger.info(\"WebSocket connection established!\");\n printWebSocketState(\"webSocketOnOpen\");\n reconnectConfig.connState = CONN_STATE.CONNECTED;\n\n if (webSocket.secondary === null) {\n invokeCallbacks(callbacks.connectionGain);\n }\n\n // Report number of retries to open and record ws open time\n const now = Date.now();\n invokeCallbacks(callbacks.connectionOpen, {\n connectWebSocketRetryCount: metrics.connectWebSocketRetryCount,\n connectionAttemptStartTime: metrics.connectionAttemptStartTime,\n noOpenConnectionsTimestamp: metrics.noOpenConnectionsTimestamp,\n connectionEstablishedTime: now,\n timeToConnect: now - metrics.connectionAttemptStartTime,\n timeWithoutConnection:\n metrics.noOpenConnectionsTimestamp ? now - metrics.noOpenConnectionsTimestamp : null\n });\n\n resetMetrics();\n resetWebSocketState();\n getDefaultWebSocket().openTimestamp = Date.now(); // record open time\n\n // early closure of primary web socket\n if (topicSubscription.subscribed.size === 0 && isWebSocketOpen(webSocket.secondary)) {\n closeSpecificWebSocket(webSocket.primary, \"[Primary WebSocket] Closing WebSocket\");\n }\n if (topicSubscription.subscribed.size > 0 || topicSubscription.pending.size > 0) {\n if (isWebSocketOpen(webSocket.secondary)) {\n logger.info(\"Subscribing secondary websocket to topics of primary websocket\");\n }\n topicSubscription.subscribed.forEach(topic => {\n topicSubscription.subscriptionHistory.add(topic);\n topicSubscription.pending.add(topic);\n });\n topicSubscription.subscribed.clear();\n subscribePendingTopics();\n }\n\n sendHeartBeat();\n heartbeatConfig.intervalHandle = setInterval(sendHeartBeat, HEARTBEAT_INTERVAL_MS);\n\n reconnectConfig.lifeTimeTimeoutHandle = setTimeout(function() {\n logger.debug(\"Starting scheduled WebSocket manager reconnect\");\n getWebSocketConnConfig();\n }, webSocketConfig.connConfig.webSocketTransport.transportLifeTimeInSeconds * 1000);\n } catch (error) {\n logger.error(\"Error after establishing WebSocket connection\", error);\n }\n };\n\n const webSocketOnClose = function(event, ws) {\n logger.info(\"Socket connection is closed\", event);\n printWebSocketState(\"webSocketOnClose before-cleanup\");\n\n invokeCallbacks(callbacks.connectionClose, {\n openTimestamp: ws.openTimestamp,\n closeTimestamp: Date.now(),\n connectionDuration: Date.now() - ws.openTimestamp,\n code: event.code,\n reason: event.reason\n });\n\n if (isWebSocketClosed(webSocket.primary)) {\n webSocket.primary = null;\n }\n if (isWebSocketClosed(webSocket.secondary)) {\n webSocket.secondary = null;\n }\n if (!reconnectConfig.reconnectWebSocket) {\n return;\n }\n if (!isWebSocketOpen(webSocket.primary) && !isWebSocketOpen(webSocket.secondary)) {\n logger.warn(\"Neither primary websocket and nor secondary websocket have open connections, attempting to re-establish connection\");\n if (reconnectConfig.connState !== CONN_STATE.DISCONNECTED) {\n /**\n * This check is required in the scenario where WS Server shuts-down and closes all active\n * WS Client connections and WS Server takes about a minute to become active gain, in this\n * scenario WS Client's onClose is triggered and then WSM start reconnect logic immediately but all\n * connect request to WS Server would fail and WS Client's onError callback would be triggered\n * followed WS Client's onClose callback and hence \"connectionLost\" callback would be invoked several\n * times and this behavior is redundant\n */\n invokeCallbacks(callbacks.connectionLost, {\n openTimestamp: ws.openTimestamp,\n closeTimestamp: Date.now(),\n connectionDuration: Date.now() - ws.openTimestamp,\n code: event.code,\n reason: event.reason\n });\n metrics.noOpenConnectionsTimestamp = Date.now();\n } else {\n logger.info(\"Ignoring connectionLost callback invocation\");\n }\n reconnectConfig.connState = CONN_STATE.DISCONNECTED;\n getWebSocketConnConfig();\n } else if (isWebSocketClosed(webSocket.primary) && isWebSocketOpen(webSocket.secondary)) {\n logger.info(\"[Primary] WebSocket Cleanly Closed\");\n webSocket.primary = webSocket.secondary;\n webSocket.secondary = null;\n }\n printWebSocketState(\"webSocketOnClose after-cleanup\");\n };\n\n const webSocketOnError = function(event) {\n printWebSocketState(\"webSocketOnError\");\n logger.error(\"WebSocketManager Error, error_event: \", event);\n getWebSocketConnConfig();\n };\n\n const webSocketOnMessage = function(event) {\n const response = JSON.parse(event.data);\n\n switch (response.topic) {\n\n case ROUTE_KEY.SUBSCRIBE:\n logger.debug(\"Subscription Message received from webSocket server\", event.data);\n topicSubscriptionConfig.requestCompleted = true;\n topicSubscriptionConfig.consecutiveNoResponseRequest = 0;\n\n if (response.content.status === \"success\") {\n topicSubscriptionConfig.consecutiveFailedSubscribeAttempts = 0;\n response.content.topics.forEach( topicName => {\n topicSubscription.subscriptionHistory.delete(topicName);\n topicSubscription.pending.delete(topicName);\n topicSubscription.subscribed.add(topicName);\n });\n if (topicSubscription.subscriptionHistory.size === 0) {\n if (isWebSocketOpen(webSocket.secondary)) {\n logger.info(\"Successfully subscribed secondary websocket to all topics of primary websocket\");\n closeSpecificWebSocket(webSocket.primary, \"[Primary WebSocket] Closing WebSocket\");\n }\n } else {\n subscribePendingTopics();\n }\n invokeCallbacks(callbacks.subscriptionUpdate, response);\n\n } else {\n clearInterval(topicSubscriptionConfig.reSubscribeIntervalId);\n ++topicSubscriptionConfig.consecutiveFailedSubscribeAttempts;\n if (topicSubscriptionConfig.consecutiveFailedSubscribeAttempts === MAX_CONSECUTIVE_FAILED_SUB_ATTEMPTS) {\n invokeCallbacks(callbacks.subscriptionFailure, response);\n topicSubscriptionConfig.consecutiveFailedSubscribeAttempts = 0;\n return;\n }\n topicSubscriptionConfig.reSubscribeIntervalId = setInterval(function () {\n subscribePendingTopics();\n }, TOPIC_SUBSCRIPTION_RETRY_INTERVAL_MS);\n }\n break;\n\n case ROUTE_KEY.HEARTBEAT:\n logger.debug(\"Heartbeat response received\");\n heartbeatConfig.pendingResponse = false;\n break;\n\n default:\n if (response.topic) {\n logger.debug(\"Message received for topic \" + response.topic);\n if (isWebSocketOpen(webSocket.primary) && isWebSocketOpen(webSocket.secondary)\n && topicSubscription.subscriptionHistory.size === 0 && this === webSocket.primary) {\n /**\n * This block is to handle scenario when both primary and secondary socket have subscribed to\n * a common topic but we are facing difficulty in closing the primary socket, then in this\n * situation messages will be received by both primary and secondary web socket\n */\n logger.warn(\"Ignoring Message for Topic \" + response.topic + \", to avoid duplicates\");\n return;\n }\n\n if (callbacks.allMessage.size === 0 && callbacks.topic.size === 0) {\n logger.warn('No registered callback listener for Topic', response.topic);\n return;\n }\n invokeCallbacks(callbacks.allMessage, response);\n if (callbacks.topic.has(response.topic)) {\n invokeCallbacks(callbacks.topic.get(response.topic), response);\n }\n\n } else if (response.message) {\n logger.warn(\"WebSocketManager Message Error\", response);\n } else {\n logger.warn(\"Invalid incoming message\", response);\n }\n }\n };\n\n const subscribePendingTopics = function() {\n if (topicSubscriptionConfig.consecutiveNoResponseRequest > MAX_CONSECUTIVE_SUB_REQUEST_WITH_NO_RESPONSE) {\n logger.warn(\"Ignoring subscribePendingTopics since we have exhausted max subscription retries with no response\");\n invokeCallbacks(callbacks.subscriptionFailure, Utils.getSubscriptionResponse(ROUTE_KEY.SUBSCRIBE, false, Array.from(topicSubscription.pending)));\n return;\n }\n if (!isDefaultWebSocketOpen()) {\n logger.warn(\"Ignoring subscribePendingTopics call since Default WebSocket is not open\");\n return;\n }\n\n clearInterval(topicSubscriptionConfig.responseCheckIntervalId);\n\n getDefaultWebSocket().send(createWebSocketPayload(ROUTE_KEY.SUBSCRIBE, {\n \"topics\": Array.from(topicSubscription.pending)\n }));\n topicSubscriptionConfig.requestCompleted = false;\n\n // This callback ensure that some response was received for subscription request\n topicSubscriptionConfig.responseCheckIntervalId = setInterval(function () {\n if (!topicSubscriptionConfig.requestCompleted) {\n ++topicSubscriptionConfig.consecutiveNoResponseRequest;\n subscribePendingTopics();\n }\n }, MAX_WAIT_TIME_SUB_REQUEST_WITH_NO_RESPONSE_MS);\n };\n\n const closeSpecificWebSocket = function(ws, reason) {\n if (isWebSocketState(ws, WebSocket.CONNECTING) || isWebSocketState(ws, WebSocket.OPEN)) {\n ws.close(1000, reason);\n } else {\n logger.warn(\"Ignoring WebSocket Close request, WebSocket State: \" + getWebSocketStates(ws));\n }\n };\n\n const closeWebSocket = function(reason) {\n closeSpecificWebSocket(webSocket.primary, \"[Primary] WebSocket \" + reason);\n closeSpecificWebSocket(webSocket.secondary, \"[Secondary] WebSocket \" + reason);\n };\n\n const retryWebSocketInitialization = function () {\n metrics.connectWebSocketRetryCount++;\n const waitTime = Utils.addJitter(reconnectConfig.exponentialBackOffTime, WEBSOCKET_REINIT_JITTER);\n if (Date.now() + waitTime <= webSocketConfig.connConfig.urlConnValidTime) {\n logger.debug(\"Scheduling WebSocket reinitialization, after delay \" + waitTime + \" ms\");\n reconnectConfig.exponentialTimeoutHandle = setTimeout(() => initWebSocket(), waitTime);\n reconnectConfig.exponentialBackOffTime *= 2;\n } else {\n logger.warn(\"WebSocket URL is cannot be used to establish connection\");\n getWebSocketConnConfig();\n }\n };\n\n const terminateWebSocketManager = function (response) {\n resetWebSocketState();\n resetSubscriptions();\n logger.error(\"WebSocket Initialization failed\");\n reconnectConfig.websocketInitFailed = true;\n closeWebSocket(\"Terminating WebSocket Manager\");\n clearInterval(networkConnectivityChecker);\n invokeCallbacks(callbacks.initFailure, {\n connectWebSocketRetryCount: metrics.connectWebSocketRetryCount,\n connectionAttemptStartTime: metrics.connectionAttemptStartTime,\n reason: response\n });\n resetMetrics();\n };\n\n const createWebSocketPayload = function (key, content) {\n return JSON.stringify({\n \"topic\": key,\n \"content\": content\n });\n };\n\n const sendMessage = function(payload) {\n Utils.assertIsObject(payload, \"payload\");\n if (payload.topic === undefined || invalidSendMessageRouteKeys.has(payload.topic)) {\n logger.warn(\"Cannot send message, Invalid topic\", payload);\n return;\n }\n try {\n payload = JSON.stringify(payload);\n } catch (error) {\n logger.warn(\"Error stringify message\", payload);\n return;\n }\n if (isDefaultWebSocketOpen()) {\n getDefaultWebSocket().send(payload);\n } else {\n logger.warn(\"Cannot send message, web socket connection is not open\");\n }\n };\n\n const subscribeTopics = function(topics) {\n Utils.assertNotNull(topics, 'topics');\n Utils.assertIsList(topics);\n\n topics.forEach(topic => {\n if (!topicSubscription.subscribed.has(topic)) {\n topicSubscription.pending.add(topic);\n }\n });\n // This ensure all participant-request to subscribe to topic chat are served at least once\n topicSubscriptionConfig.consecutiveNoResponseRequest = 0;\n subscribePendingTopics();\n };\n\n const validWebSocketConnConfig = function (connConfig) {\n if (Utils.isObject(connConfig) && Utils.isObject(connConfig.webSocketTransport)\n && Utils.isNonEmptyString(connConfig.webSocketTransport.url)\n && Utils.validWSUrl(connConfig.webSocketTransport.url) &&\n connConfig.webSocketTransport.transportLifeTimeInSeconds * 1000 >= MIN_WEBSOCKET_LIFETIME_MS) {\n return true;\n }\n logger.error(\"Invalid WebSocket Connection Configuration\", connConfig);\n return false;\n };\n\n const getWebSocketConnConfig = function () {\n if (!Utils.isNetworkOnline()) {\n logger.info(\"Network offline, ignoring this getWebSocketConnConfig request\");\n return;\n }\n if (reconnectConfig.websocketInitFailed) {\n logger.debug(\"WebSocket Init had failed, ignoring this getWebSocketConnConfig request\");\n return;\n }\n if (!webSocketConfig.promiseCompleted) {\n logger.debug(\"There is an ongoing getWebSocketConnConfig request, this request will be ignored\");\n return;\n }\n resetWebSocketState();\n logger.info(\"Fetching new WebSocket connection configuration\");\n metrics.connectionAttemptStartTime = metrics.connectionAttemptStartTime || Date.now();\n webSocketConfig.promiseCompleted = false;\n webSocketConfig.promiseHandle = callbacks.getWebSocketTransport();\n return webSocketConfig.promiseHandle\n .then(function(response) {\n webSocketConfig.promiseCompleted = true;\n logger.debug(\"Successfully fetched webSocket connection configuration\", response);\n if (!validWebSocketConnConfig(response)) {\n terminateWebSocketManager(\"Invalid WebSocket connection configuration: \" + response);\n return { webSocketConnectionFailed: true };\n }\n webSocketConfig.connConfig = response;\n // Ideally this URL validity time should be provided by server\n webSocketConfig.connConfig.urlConnValidTime = Date.now() + WEBSOCKET_URL_VALID_TIME_MS;\n return initWebSocket();\n },\n function(reason) {\n webSocketConfig.promiseCompleted = true;\n logger.error(\"Failed to fetch webSocket connection configuration\", reason);\n setTimeout(() => getWebSocketConnConfig(), Utils.addJitter(GET_WEBSOCKET_CONNECTION_INTERVAL_MS, WEBSOCKET_CONN_CONFIG_JITTER));\n return { webSocketConnectionFailed: true };\n });\n };\n\n const initWebSocket = function() {\n if (reconnectConfig.websocketInitFailed) {\n logger.info(\"web-socket initializing had failed, aborting re-init\");\n return { webSocketConnectionFailed: true };\n }\n if (!Utils.isNetworkOnline()) {\n logger.warn(\"System is offline aborting web-socket init\");\n return { webSocketConnectionFailed: true };\n }\n logger.info(\"Initializing Websocket Manager\");\n printWebSocketState(\"initWebSocket\");\n try {\n if (validWebSocketConnConfig(webSocketConfig.connConfig)) {\n let ws = null;\n if (isWebSocketOpen(webSocket.primary)) {\n logger.debug(\"Primary Socket connection is already open\");\n if (!isWebSocketState(webSocket.secondary, WebSocket.CONNECTING)) {\n logger.debug(\"Establishing a secondary web-socket connection\");\n webSocket.secondary = getNewWebSocket();\n }\n ws = webSocket.secondary;\n } else {\n if (!isWebSocketState(webSocket.primary, WebSocket.CONNECTING)) {\n logger.debug(\"Establishing a primary web-socket connection\");\n webSocket.primary = getNewWebSocket();\n }\n ws = webSocket.primary;\n }\n\n // WebSocket creation is async task hence we Wait for 1sec before any potential retry\n reconnectConfig.webSocketInitCheckerTimeoutId = setTimeout(function() {\n if (!isWebSocketOpen(ws)) {\n retryWebSocketInitialization();\n }\n }, 1000);\n return { webSocketConnectionFailed: false };\n }\n } catch (error) {\n logger.error(\"Error Initializing web-socket-manager\", error);\n terminateWebSocketManager(\"Failed to initialize new WebSocket: \" + error.message);\n return { webSocketConnectionFailed: true };\n }\n };\n\n const getNewWebSocket = function() {\n let ws = new WebSocket(webSocketConfig.connConfig.webSocketTransport.url);\n ws.addEventListener(\"open\", webSocketOnOpen);\n ws.addEventListener(\"message\", webSocketOnMessage);\n ws.addEventListener(\"error\", webSocketOnError);\n ws.addEventListener(\"close\", event => webSocketOnClose(event, ws));\n return ws;\n };\n\n const onConnectionOpen = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionOpen.add(cb);\n return () => callbacks.connectionOpen.delete(cb);\n };\n\n const onConnectionClose = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionClose.add(cb);\n return () => callbacks.connectionClose.delete(cb);\n };\n\n const onConnectionGain = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionGain.add(cb);\n if (isDefaultWebSocketOpen()) {\n cb();\n }\n return () => callbacks.connectionGain.delete(cb);\n };\n\n const onConnectionLost = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionLost.add(cb);\n if (reconnectConfig.connState === CONN_STATE.DISCONNECTED) {\n cb();\n }\n return () => callbacks.connectionLost.delete(cb);\n };\n\n const onInitFailure = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.initFailure.add(cb);\n if (reconnectConfig.websocketInitFailed) {\n cb();\n }\n return () => callbacks.initFailure.delete(cb);\n };\n\n const init = function(transportHandle) {\n Utils.assertTrue(Utils.isFunction(transportHandle), 'transportHandle must be a function');\n if (callbacks.getWebSocketTransport !== null) {\n logger.warn(\"Web Socket Manager was already initialized\");\n return;\n }\n callbacks.getWebSocketTransport = transportHandle;\n\n return getWebSocketConnConfig();\n };\n\n const onSubscriptionUpdate = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.subscriptionUpdate.add(cb);\n return () => callbacks.subscriptionUpdate.delete(cb);\n };\n\n const onSubscriptionFailure = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.subscriptionFailure.add(cb);\n return () => callbacks.subscriptionFailure.delete(cb);\n };\n\n const onMessage = function(topicName, cb) {\n Utils.assertNotNull(topicName, 'topicName');\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n if (callbacks.topic.has(topicName)) {\n callbacks.topic.get(topicName).add(cb);\n } else {\n callbacks.topic.set(topicName, new Set([cb]));\n }\n return () => callbacks.topic.get(topicName).delete(cb);\n };\n\n const onAllMessage = function (cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.allMessage.add(cb);\n return () => callbacks.allMessage.delete(cb);\n };\n\n this.init = init;\n this.onInitFailure = onInitFailure;\n this.onConnectionOpen = onConnectionOpen;\n this.onConnectionClose = onConnectionClose;\n this.onConnectionGain = onConnectionGain;\n this.onConnectionLost = onConnectionLost;\n this.onSubscriptionUpdate = onSubscriptionUpdate;\n this.onSubscriptionFailure = onSubscriptionFailure;\n this.onMessage = onMessage;\n this.onAllMessage = onAllMessage;\n this.subscribeTopics = subscribeTopics;\n this.sendMessage = sendMessage;\n\n this.closeWebSocket = function() {\n resetWebSocketState();\n resetSubscriptions();\n reconnectConfig.reconnectWebSocket = false;\n clearInterval(networkConnectivityChecker);\n closeWebSocket(\"User request to close WebSocket\");\n };\n\n this.terminateWebSocketManager = terminateWebSocketManager;\n};\n\nconst WebSocketManagerConstructor = () => {\n return new WebSocketManager();\n};\n\nconst setGlobalConfig = config => {\n const loggerConfig = config.loggerConfig;\n LogManager.updateLoggerConfig(loggerConfig);\n};\n\nconst WebSocketManagerObject = {\n create: WebSocketManagerConstructor,\n setGlobalConfig: setGlobalConfig,\n LogLevel: LogLevel,\n Logger: Logger\n};\n\nexport { WebSocketManagerObject };","/* global window, exports, define */\n\n!function() {\n 'use strict'\n\n var re = {\n not_string: /[^s]/,\n not_bool: /[^t]/,\n not_type: /[^T]/,\n not_primitive: /[^v]/,\n number: /[diefg]/,\n numeric_arg: /[bcdiefguxX]/,\n json: /[j]/,\n not_json: /[^j]/,\n text: /^[^\\x25]+/,\n modulo: /^\\x25{2}/,\n placeholder: /^\\x25(?:([1-9]\\d*)\\$|\\(([^)]+)\\))?(\\+)?(0|'[^$])?(-)?(\\d+)?(?:\\.(\\d+))?([b-gijostTuvxX])/,\n key: /^([a-z_][a-z_\\d]*)/i,\n key_access: /^\\.([a-z_][a-z_\\d]*)/i,\n index_access: /^\\[(\\d+)\\]/,\n sign: /^[+-]/\n }\n\n function sprintf(key) {\n // `arguments` is not an array, but should be fine for this call\n return sprintf_format(sprintf_parse(key), arguments)\n }\n\n function vsprintf(fmt, argv) {\n return sprintf.apply(null, [fmt].concat(argv || []))\n }\n\n function sprintf_format(parse_tree, argv) {\n var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign\n for (i = 0; i < tree_length; i++) {\n if (typeof parse_tree[i] === 'string') {\n output += parse_tree[i]\n }\n else if (typeof parse_tree[i] === 'object') {\n ph = parse_tree[i] // convenience purposes only\n if (ph.keys) { // keyword argument\n arg = argv[cursor]\n for (k = 0; k < ph.keys.length; k++) {\n if (arg == undefined) {\n throw new Error(sprintf('[sprintf] Cannot access property \"%s\" of undefined value \"%s\"', ph.keys[k], ph.keys[k-1]))\n }\n arg = arg[ph.keys[k]]\n }\n }\n else if (ph.param_no) { // positional argument (explicit)\n arg = argv[ph.param_no]\n }\n else { // positional argument (implicit)\n arg = argv[cursor++]\n }\n\n if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {\n arg = arg()\n }\n\n if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {\n throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))\n }\n\n if (re.number.test(ph.type)) {\n is_positive = arg >= 0\n }\n\n switch (ph.type) {\n case 'b':\n arg = parseInt(arg, 10).toString(2)\n break\n case 'c':\n arg = String.fromCharCode(parseInt(arg, 10))\n break\n case 'd':\n case 'i':\n arg = parseInt(arg, 10)\n break\n case 'j':\n arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)\n break\n case 'e':\n arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()\n break\n case 'f':\n arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)\n break\n case 'g':\n arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)\n break\n case 'o':\n arg = (parseInt(arg, 10) >>> 0).toString(8)\n break\n case 's':\n arg = String(arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 't':\n arg = String(!!arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'T':\n arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'u':\n arg = parseInt(arg, 10) >>> 0\n break\n case 'v':\n arg = arg.valueOf()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'x':\n arg = (parseInt(arg, 10) >>> 0).toString(16)\n break\n case 'X':\n arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()\n break\n }\n if (re.json.test(ph.type)) {\n output += arg\n }\n else {\n if (re.number.test(ph.type) && (!is_positive || ph.sign)) {\n sign = is_positive ? '+' : '-'\n arg = arg.toString().replace(re.sign, '')\n }\n else {\n sign = ''\n }\n pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '\n pad_length = ph.width - (sign + arg).length\n pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''\n output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)\n }\n }\n }\n return output\n }\n\n var sprintf_cache = Object.create(null)\n\n function sprintf_parse(fmt) {\n if (sprintf_cache[fmt]) {\n return sprintf_cache[fmt]\n }\n\n var _fmt = fmt, match, parse_tree = [], arg_names = 0\n while (_fmt) {\n if ((match = re.text.exec(_fmt)) !== null) {\n parse_tree.push(match[0])\n }\n else if ((match = re.modulo.exec(_fmt)) !== null) {\n parse_tree.push('%')\n }\n else if ((match = re.placeholder.exec(_fmt)) !== null) {\n if (match[2]) {\n arg_names |= 1\n var field_list = [], replacement_field = match[2], field_match = []\n if ((field_match = re.key.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {\n if ((field_match = re.key_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else if ((field_match = re.index_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n }\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n match[2] = field_list\n }\n else {\n arg_names |= 2\n }\n if (arg_names === 3) {\n throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')\n }\n\n parse_tree.push(\n {\n placeholder: match[0],\n param_no: match[1],\n keys: match[2],\n sign: match[3],\n pad_char: match[4],\n align: match[5],\n width: match[6],\n precision: match[7],\n type: match[8]\n }\n )\n }\n else {\n throw new SyntaxError('[sprintf] unexpected placeholder')\n }\n _fmt = _fmt.substring(match[0].length)\n }\n return sprintf_cache[fmt] = parse_tree\n }\n\n /**\n * export to either browser or node.js\n */\n /* eslint-disable quote-props */\n if (typeof exports !== 'undefined') {\n exports['sprintf'] = sprintf\n exports['vsprintf'] = vsprintf\n }\n if (typeof window !== 'undefined') {\n window['sprintf'] = sprintf\n window['vsprintf'] = vsprintf\n\n if (typeof define === 'function' && define['amd']) {\n define(function() {\n return {\n 'sprintf': sprintf,\n 'vsprintf': vsprintf\n }\n })\n }\n }\n /* eslint-enable quote-props */\n}(); // eslint-disable-line\n","/*eslint no-unused-vars: \"off\"*/\nimport { WebSocketManagerObject } from \"./webSocketManager\";\n\nglobal.connect = global.connect || {};\nconnect.WebSocketManager = WebSocketManagerObject;\n\nexport const WebSocketManager = WebSocketManagerObject;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/utils.js","webpack:///./src/constants.js","webpack:///./src/log.js","webpack:///./src/webSocketManager.js","webpack:///./node_modules/sprintf-js/src/sprintf.js","webpack:///./src/index.js","webpack:///(webpack)/buildin/global.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","Utils","premise","message","Error","assertTrue","undefined","_typeof","sprintf","length","Array","isArray","obj","constructor","apply","wsRegex","RegExp","validWSUrl","wsUrl","test","getSubscriptionResponse","routeKey","isSuccess","topicList","topic","content","status","topics","assertIsObject","isObject","addJitter","base","maxJitter","arguments","Math","min","sign","random","floor","isNetworkOnline","navigator","onLine","LOGS_DESTINATION","ROUTE_KEY","CONN_STATE","Logger","data","LogLevel","DEBUG","INFO","WARN","ERROR","LogManagerImpl","_classCallCheck","this","updateLoggerConfig","consoleLoggerWrapper","createConsoleLogger","level","logStatement","hasClientLogger","_clientLogger","debug","info","warn","error","_level","options","prefix","_logsDestination","LoggerWrapperImpl","inputConfig","config","logger","LoggerWrapper","_this","_possibleConstructorReturn","_getPrototypeOf","_len","args","_key","_log","_len2","_key2","_len3","_key3","_len4","_key4","LogManager","isLevelEnabled","writeToClientLogger","_shouldLog","_convertToSingleStatement","_writeToClientLogger","index","arg","_convertToString","isString","isFunction","toString","toStringResult","JSON","stringify","console","__webpack_exports__","WebSocketManagerObject","WebSocketManager","getLogger","online","webSocket","primary","secondary","reconnectConfig","reconnectWebSocket","websocketInitFailed","exponentialBackOffTime","exponentialTimeoutHandle","lifeTimeTimeoutHandle","webSocketInitCheckerTimeoutId","connState","metrics","connectWebSocketRetryCount","connectionAttemptStartTime","noOpenConnectionsTimestamp","heartbeatConfig","pendingResponse","intervalHandle","callbacks","initFailure","Set","getWebSocketTransport","subscriptionUpdate","subscriptionFailure","Map","allMessage","connectionGain","connectionLost","connectionOpen","connectionClose","webSocketConfig","connConfig","promiseHandle","promiseCompleted","topicSubscription","subscribed","pending","subscriptionHistory","topicSubscriptionConfig","responseCheckIntervalId","requestCompleted","reSubscribeIntervalId","consecutiveFailedSubscribeAttempts","consecutiveNoResponseRequest","invalidSendMessageRouteKeys","networkConnectivityChecker","setInterval","ws","getDefaultWebSocket","isWebSocketState","WebSocket","CLOSING","CLOSED","getWebSocketConnConfig","invokeCallbacks","response","forEach","callback","getWebSocketStates","readyState","CONNECTING","OPEN","printWebSocketState","event","webSocketStateCode","isWebSocketOpen","isWebSocketClosed","isDefaultWebSocketOpen","sendHeartBeat","clearInterval","send","createWebSocketPayload","resetWebSocketState","clearTimeout","resetSubscriptions","resetMetrics","webSocketOnOpen","now","Date","connectionEstablishedTime","timeToConnect","timeWithoutConnection","openTimestamp","size","closeSpecificWebSocket","add","clear","subscribePendingTopics","webSocketLifetimeTimeout","webSocketTransport","transportLifeTimeInSeconds","setTimeout","webSocketOnError","webSocketOnMessage","parse","topicName","has","from","reason","close","closeWebSocket","retryWebSocketInitialization","waitTime","urlConnValidTime","initWebSocket","terminateWebSocketManager","validWebSocketConnConfig","isNonEmptyString","url","then","webSocketConnectionFailed","getNewWebSocket","addEventListener","closeTimestamp","connectionDuration","code","webSocketOnClose","init","transportHandle","onInitFailure","cb","onConnectionOpen","onConnectionClose","onConnectionGain","onConnectionLost","onSubscriptionUpdate","onSubscriptionFailure","onMessage","assertNotNull","set","onAllMessage","subscribeTopics","assertIsList","sendMessage","payload","setGlobalConfig","loggerConfig","__WEBPACK_AMD_DEFINE_RESULT__","re","not_string","not_bool","not_type","not_primitive","number","numeric_arg","json","not_json","text","modulo","placeholder","key_access","index_access","parse_tree","argv","k","ph","pad","pad_character","pad_length","is_positive","cursor","tree_length","output","keys","param_no","type","Function","isNaN","TypeError","parseInt","String","fromCharCode","width","precision","parseFloat","toExponential","toFixed","Number","toPrecision","substring","slice","toLowerCase","valueOf","toUpperCase","replace","pad_char","charAt","repeat","align","sprintf_format","fmt","sprintf_cache","match","_fmt","arg_names","exec","push","SyntaxError","field_list","replacement_field","field_match","sprintf_parse","vsprintf","concat","window","global","_webSocketManager__WEBPACK_IMPORTED_MODULE_0__","connect","g","e"],"mappings":"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","file":"amazon-connect-websocket-manager.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","import { sprintf } from \"sprintf-js\";\nconst Utils = {};\n\n/**\n * Asserts that a premise is true.\n */\nUtils.assertTrue = function(premise, message) {\n if (!premise) {\n throw new Error(message);\n }\n};\n\n/**\n * Asserts that a value is not null or undefined.\n */\nUtils.assertNotNull = function(value, name) {\n Utils.assertTrue(\n value !== null && typeof value !== undefined,\n sprintf(\"%s must be provided\", name || \"A value\")\n );\n return value;\n};\n\nUtils.isNonEmptyString = function(value) {\n return typeof value === \"string\" && value.length > 0;\n};\n\nUtils.assertIsList = function(value, key) {\n if (!Array.isArray(value)) {\n throw new Error(key + \" is not an array\");\n }\n};\n\n/**\n * Determine if the given value is a callable function type.\n * Borrowed from Underscore.js.\n */\nUtils.isFunction = function(obj) {\n return !!(obj && obj.constructor && obj.call && obj.apply);\n};\n\nUtils.isObject = function(value) {\n return !(typeof value !== \"object\" || value === null);\n};\n\nUtils.isString = function(value) {\n return typeof value === \"string\";\n};\n\nUtils.isNumber = function(value) {\n return typeof value === \"number\";\n};\n\nconst wsRegex = new RegExp(\"^(wss://)\\\\w*\");\nUtils.validWSUrl = function (wsUrl) {\n return wsRegex.test(wsUrl);\n};\n\nUtils.getSubscriptionResponse = (routeKey, isSuccess, topicList) => {\n return {\n topic: routeKey,\n content : {\n status: isSuccess ? \"success\" : \"failure\",\n topics: topicList\n }\n };\n};\n\nUtils.assertIsObject = function(value, key) {\n if (!Utils.isObject(value)) {\n throw new Error(key + \" is not an object!\");\n }\n};\n\nUtils.addJitter = function (base, maxJitter = 1) {\n maxJitter = Math.min(maxJitter, 1.0);\n const sign = Math.random() > 0.5 ? 1 : -1;\n return Math.floor(base + sign * base * Math.random() * maxJitter);\n};\n\nUtils.isNetworkOnline = () => navigator.onLine;\n\nexport default Utils;\n\n","\nexport const LOGS_DESTINATION = {\n NULL: \"NULL\",\n CLIENT_LOGGER: \"CLIENT_LOGGER\",\n DEBUG: \"DEBUG\"\n};\n\nexport const MIN_WEBSOCKET_LIFETIME_MS = 300000;\nexport const WEBSOCKET_LIFETIME_BASE_MS = 3000000;\nexport const HEARTBEAT_INTERVAL_MS = 10000;\nexport const WEBSOCKET_URL_VALID_TIME_MS = 85000;\nexport const TOPIC_SUBSCRIPTION_RETRY_INTERVAL_MS = 500;\nexport const MAX_CONSECUTIVE_FAILED_SUB_ATTEMPTS = 5;\nexport const MAX_WAIT_TIME_SUB_REQUEST_WITH_NO_RESPONSE_MS = 1000;\nexport const MAX_CONSECUTIVE_SUB_REQUEST_WITH_NO_RESPONSE = 3;\nexport const NETWORK_CONN_CHECK_INTERVAL_MS = 250;\nexport const WEBSOCKET_REINIT_JITTER = 0.3;\nexport const WEBSOCKET_LIFETIME_JITTER = 0.1;\n\nexport const ROUTE_KEY = {\n SUBSCRIBE: \"aws/subscribe\",\n UNSUBSCRIBE: \"aws/unsubscribe\",\n HEARTBEAT: \"aws/heartbeat\"\n};\n\nexport const CONN_STATE = {\n CONNECTED: \"connected\",\n DISCONNECTED: \"disconnected\"\n};\n","import Utils from \"./utils\";\nimport { LOGS_DESTINATION } from \"./constants\";\n\n/*eslint-disable no-unused-vars*/\nclass Logger {\n debug(data) {}\n\n info(data) {}\n\n warn(data) {}\n\n error(data) {}\n}\n/*eslint-enable no-unused-vars*/\n\nconst LogLevel = {\n DEBUG: 10,\n INFO: 20,\n WARN: 30,\n ERROR: 40\n};\n\nclass LogManagerImpl {\n constructor() {\n this.updateLoggerConfig();\n this.consoleLoggerWrapper = createConsoleLogger();\n }\n\n writeToClientLogger(level, logStatement) {\n if (!this.hasClientLogger()) {\n return;\n }\n switch (level) {\n case LogLevel.DEBUG:\n return this._clientLogger.debug(logStatement);\n case LogLevel.INFO:\n return this._clientLogger.info(logStatement);\n case LogLevel.WARN:\n return this._clientLogger.warn(logStatement);\n case LogLevel.ERROR:\n return this._clientLogger.error(logStatement);\n }\n }\n\n isLevelEnabled(level) {\n return level >= this._level;\n }\n\n hasClientLogger() {\n return this._clientLogger !== null;\n }\n\n getLogger(options) {\n var prefix = options.prefix || \"\";\n if (this._logsDestination === LOGS_DESTINATION.DEBUG) {\n return this.consoleLoggerWrapper;\n }\n return new LoggerWrapperImpl(prefix);\n }\n\n updateLoggerConfig(inputConfig) {\n var config = inputConfig || {};\n this._level = config.level || LogLevel.DEBUG;\n this._clientLogger = config.logger || null;\n this._logsDestination = LOGS_DESTINATION.NULL;\n if (config.debug) {\n this._logsDestination = LOGS_DESTINATION.DEBUG;\n }\n if (config.logger) {\n this._logsDestination = LOGS_DESTINATION.CLIENT_LOGGER;\n }\n }\n}\n\nclass LoggerWrapper {\n debug() {}\n\n info() {}\n\n warn() {}\n\n error() {}\n}\n\nclass LoggerWrapperImpl extends LoggerWrapper {\n constructor(prefix) {\n super();\n this.prefix = prefix || \"\";\n }\n\n debug(...args) {\n this._log(LogLevel.DEBUG, args);\n }\n\n info(...args) {\n this._log(LogLevel.INFO, args);\n }\n\n warn(...args) {\n this._log(LogLevel.WARN, args);\n }\n\n error(...args) {\n this._log(LogLevel.ERROR, args);\n }\n\n _shouldLog(level) {\n return LogManager.hasClientLogger() && LogManager.isLevelEnabled(level);\n }\n\n _writeToClientLogger(level, logStatement) {\n LogManager.writeToClientLogger(level, logStatement);\n }\n\n _log(level, args) {\n if (this._shouldLog(level)) {\n var logStatement = this._convertToSingleStatement(args);\n this._writeToClientLogger(level, logStatement);\n }\n }\n\n _convertToSingleStatement(args) {\n var logStatement = \"\";\n if (this.prefix) {\n logStatement += this.prefix + \" \";\n }\n for (var index = 0; index < args.length; index++) {\n var arg = args[index];\n logStatement += this._convertToString(arg) + \" \";\n }\n return logStatement;\n }\n\n _convertToString(arg) {\n try {\n if (!arg) {\n return \"\";\n }\n if (Utils.isString(arg)) {\n return arg;\n }\n if (Utils.isObject(arg) && Utils.isFunction(arg.toString)) {\n var toStringResult = arg.toString();\n if (toStringResult !== \"[object Object]\") {\n return toStringResult;\n }\n }\n return JSON.stringify(arg);\n } catch (error) {\n console.error(\"Error while converting argument to string\", arg, error);\n return \"\";\n }\n }\n}\n\nvar createConsoleLogger = () => {\n var logger = new LoggerWrapper();\n logger.debug = console.debug;\n logger.info = console.info;\n logger.warn = console.warn;\n logger.error = console.error;\n return logger;\n};\n\nconst LogManager = new LogManagerImpl();\n\nexport { LogManager, Logger, LogLevel };\n","import Utils from \"./utils\";\nimport { LogManager, LogLevel, Logger } from \"./log\";\nimport {\n MIN_WEBSOCKET_LIFETIME_MS,\n WEBSOCKET_LIFETIME_BASE_MS,\n WEBSOCKET_URL_VALID_TIME_MS,\n HEARTBEAT_INTERVAL_MS,\n ROUTE_KEY,\n CONN_STATE,\n MAX_CONSECUTIVE_FAILED_SUB_ATTEMPTS,\n TOPIC_SUBSCRIPTION_RETRY_INTERVAL_MS,\n MAX_WAIT_TIME_SUB_REQUEST_WITH_NO_RESPONSE_MS,\n MAX_CONSECUTIVE_SUB_REQUEST_WITH_NO_RESPONSE,\n NETWORK_CONN_CHECK_INTERVAL_MS,\n WEBSOCKET_REINIT_JITTER,\n WEBSOCKET_LIFETIME_JITTER\n} from \"./constants\";\n\n\nconst WebSocketManager = function() {\n\n const logger = LogManager.getLogger({});\n\n let online = Utils.isNetworkOnline();\n\n let webSocket = {\n primary: null,\n secondary: null\n };\n\n let reconnectConfig = {\n reconnectWebSocket: true,\n websocketInitFailed: false,\n exponentialBackOffTime: 1000,\n exponentialTimeoutHandle: null,\n lifeTimeTimeoutHandle: null,\n webSocketInitCheckerTimeoutId: null,\n connState: null\n };\n\n let metrics = {\n connectWebSocketRetryCount: 0,\n connectionAttemptStartTime: null,\n noOpenConnectionsTimestamp: null\n };\n\n let heartbeatConfig = {\n pendingResponse: false,\n intervalHandle: null\n };\n\n let callbacks = {\n initFailure: new Set(),\n getWebSocketTransport: null,\n subscriptionUpdate: new Set(),\n subscriptionFailure: new Set(),\n topic: new Map(),\n allMessage: new Set(),\n connectionGain: new Set(),\n connectionLost: new Set(),\n connectionOpen: new Set(),\n connectionClose: new Set()\n };\n\n let webSocketConfig = {\n connConfig: null,\n promiseHandle: null,\n promiseCompleted: true\n };\n\n let topicSubscription = {\n subscribed: new Set(),\n pending: new Set(),\n subscriptionHistory: new Set()\n };\n\n let topicSubscriptionConfig = {\n responseCheckIntervalId: null,\n requestCompleted: true,\n reSubscribeIntervalId: null,\n consecutiveFailedSubscribeAttempts: 0,\n consecutiveNoResponseRequest: 0\n };\n\n const invalidSendMessageRouteKeys = new Set([ROUTE_KEY.SUBSCRIBE, ROUTE_KEY.UNSUBSCRIBE, ROUTE_KEY.HEARTBEAT]);\n\n const networkConnectivityChecker = setInterval(function () {\n if (online !== Utils.isNetworkOnline()) {\n online = Utils.isNetworkOnline();\n if (!online) {\n logger.info(\"Network offline\");\n return;\n }\n const ws = getDefaultWebSocket();\n if (online && (!ws || isWebSocketState(ws, WebSocket.CLOSING) || isWebSocketState(ws, WebSocket.CLOSED))) {\n logger.info(\"Network online, connecting to WebSocket server\");\n getWebSocketConnConfig();\n }\n }\n }, NETWORK_CONN_CHECK_INTERVAL_MS);\n\n const invokeCallbacks = function(callbacks, response) {\n callbacks.forEach(function (callback) {\n try {\n callback(response);\n } catch (error) {\n logger.error(\"Error executing callback\", error);\n }\n });\n };\n\n const getWebSocketStates = function(ws) {\n if (ws === null) return \"NULL\";\n switch (ws.readyState) {\n case WebSocket.CONNECTING:\n return \"CONNECTING\";\n case WebSocket.OPEN:\n return \"OPEN\";\n case WebSocket.CLOSING:\n return \"CLOSING\";\n case WebSocket.CLOSED:\n return \"CLOSED\";\n default:\n return \"UNDEFINED\";\n }\n };\n\n const printWebSocketState = function (event = \"\") {\n logger.debug(\"[\" + event + \"] Primary WebSocket: \" + getWebSocketStates(webSocket.primary)\n + \" | \" + \"Secondary WebSocket: \" + getWebSocketStates(webSocket.secondary) );\n };\n\n const isWebSocketState = function(ws, webSocketStateCode) {\n return ws && ws.readyState === webSocketStateCode;\n };\n\n const isWebSocketOpen = function(ws) {\n return isWebSocketState(ws, WebSocket.OPEN);\n };\n\n const isWebSocketClosed = function(ws) {\n // undefined check is to address the limitation of testing framework\n return ws === null || ws.readyState === undefined || isWebSocketState(ws, WebSocket.CLOSED);\n };\n\n /**\n * This function is meant to handle the scenario when we have two web-sockets open\n * in such a scenario we always select secondary web-socket since all future operations\n * are supposed to be done by this secondary web-socket\n */\n const getDefaultWebSocket = function() {\n if (webSocket.secondary !== null) {\n return webSocket.secondary;\n }\n return webSocket.primary;\n };\n\n const isDefaultWebSocketOpen = function() {\n return isWebSocketOpen(getDefaultWebSocket());\n };\n\n const sendHeartBeat = function() {\n if (heartbeatConfig.pendingResponse) {\n logger.warn(\"Heartbeat response not received\");\n clearInterval(heartbeatConfig.intervalHandle);\n heartbeatConfig.pendingResponse = false;\n getWebSocketConnConfig();\n return;\n }\n if (isDefaultWebSocketOpen()) {\n logger.debug(\"Sending heartbeat\");\n getDefaultWebSocket().send(createWebSocketPayload(ROUTE_KEY.HEARTBEAT));\n heartbeatConfig.pendingResponse = true;\n } else {\n logger.warn(\"Failed to send heartbeat since WebSocket is not open\");\n printWebSocketState(\"sendHeartBeat\");\n getWebSocketConnConfig();\n }\n };\n\n const resetWebSocketState = function() {\n reconnectConfig.exponentialBackOffTime = 1000;\n heartbeatConfig.pendingResponse = false;\n reconnectConfig.reconnectWebSocket = true;\n\n clearTimeout(reconnectConfig.lifeTimeTimeoutHandle);\n clearInterval(heartbeatConfig.intervalHandle);\n clearTimeout(reconnectConfig.exponentialTimeoutHandle);\n clearTimeout(reconnectConfig.webSocketInitCheckerTimeoutId);\n };\n\n const resetSubscriptions = function() {\n topicSubscriptionConfig.consecutiveFailedSubscribeAttempts = 0;\n topicSubscriptionConfig.consecutiveNoResponseRequest = 0;\n clearInterval(topicSubscriptionConfig.responseCheckIntervalId);\n clearInterval(topicSubscriptionConfig.reSubscribeIntervalId);\n };\n\n const resetMetrics = function() {\n metrics.connectWebSocketRetryCount = 0;\n metrics.connectionAttemptStartTime = null;\n metrics.noOpenConnectionsTimestamp = null;\n };\n\n const webSocketOnOpen = function() {\n try {\n logger.info(\"WebSocket connection established!\");\n printWebSocketState(\"webSocketOnOpen\");\n if (reconnectConfig.connState === null || reconnectConfig.connState === CONN_STATE.DISCONNECTED) {\n invokeCallbacks(callbacks.connectionGain);\n }\n reconnectConfig.connState = CONN_STATE.CONNECTED;\n\n // Report number of retries to open and record ws open time\n const now = Date.now();\n invokeCallbacks(callbacks.connectionOpen, {\n connectWebSocketRetryCount: metrics.connectWebSocketRetryCount,\n connectionAttemptStartTime: metrics.connectionAttemptStartTime,\n noOpenConnectionsTimestamp: metrics.noOpenConnectionsTimestamp,\n connectionEstablishedTime: now,\n timeToConnect: now - metrics.connectionAttemptStartTime,\n timeWithoutConnection:\n metrics.noOpenConnectionsTimestamp ? now - metrics.noOpenConnectionsTimestamp : null\n });\n\n resetMetrics();\n resetWebSocketState();\n getDefaultWebSocket().openTimestamp = Date.now(); // record open time\n\n // early closure of primary web socket\n if (topicSubscription.subscribed.size === 0 && isWebSocketOpen(webSocket.secondary)) {\n closeSpecificWebSocket(webSocket.primary, \"[Primary WebSocket] Closing WebSocket\");\n }\n if (topicSubscription.subscribed.size > 0 || topicSubscription.pending.size > 0) {\n if (isWebSocketOpen(webSocket.secondary)) {\n logger.info(\"Subscribing secondary websocket to topics of primary websocket\");\n }\n topicSubscription.subscribed.forEach(topic => {\n topicSubscription.subscriptionHistory.add(topic);\n topicSubscription.pending.add(topic);\n });\n topicSubscription.subscribed.clear();\n subscribePendingTopics();\n }\n\n sendHeartBeat();\n heartbeatConfig.intervalHandle = setInterval(sendHeartBeat, HEARTBEAT_INTERVAL_MS);\n\n const webSocketLifetimeTimeout = Math.min(Utils.addJitter(WEBSOCKET_LIFETIME_BASE_MS, WEBSOCKET_LIFETIME_JITTER),\n webSocketConfig.connConfig.webSocketTransport.transportLifeTimeInSeconds * 1000);\n logger.debug(\"Scheduling WebSocket manager reconnection, after delay \" + webSocketLifetimeTimeout + \" ms\");\n reconnectConfig.lifeTimeTimeoutHandle = setTimeout(function() {\n logger.debug(\"Starting scheduled WebSocket manager reconnection\");\n getWebSocketConnConfig();\n }, webSocketLifetimeTimeout);\n } catch (error) {\n logger.error(\"Error after establishing WebSocket connection\", error);\n }\n };\n\n const webSocketOnClose = function(event, ws) {\n logger.info(\"Socket connection is closed\", event);\n printWebSocketState(\"webSocketOnClose before-cleanup\");\n\n invokeCallbacks(callbacks.connectionClose, {\n openTimestamp: ws.openTimestamp,\n closeTimestamp: Date.now(),\n connectionDuration: Date.now() - ws.openTimestamp,\n code: event.code,\n reason: event.reason\n });\n\n if (isWebSocketClosed(webSocket.primary)) {\n webSocket.primary = null;\n }\n if (isWebSocketClosed(webSocket.secondary)) {\n webSocket.secondary = null;\n }\n if (!reconnectConfig.reconnectWebSocket) {\n return;\n }\n if (!isWebSocketOpen(webSocket.primary) && !isWebSocketOpen(webSocket.secondary)) {\n logger.warn(\"Neither primary websocket and nor secondary websocket have open connections, attempting to re-establish connection\");\n if (reconnectConfig.connState === CONN_STATE.DISCONNECTED) {\n /**\n * This check is required in the scenario where WS Server shuts-down and closes all active\n * WS Client connections and WS Server takes about a minute to become active again, in this\n * scenario WS Client's onClose is triggered and then WSM start reconnect logic immediately but all\n * connect request to WS Server would fail and WS Client's onError callback would be triggered\n * followed WS Client's onClose callback and hence \"connectionLost\" callback would be invoked several\n * times and this behavior is redundant\n */\n logger.info(\"Ignoring connectionLost callback invocation\");\n } else {\n invokeCallbacks(callbacks.connectionLost, {\n openTimestamp: ws.openTimestamp,\n closeTimestamp: Date.now(),\n connectionDuration: Date.now() - ws.openTimestamp,\n code: event.code,\n reason: event.reason\n });\n metrics.noOpenConnectionsTimestamp = Date.now();\n }\n reconnectConfig.connState = CONN_STATE.DISCONNECTED;\n getWebSocketConnConfig();\n } else if (isWebSocketClosed(webSocket.primary) && isWebSocketOpen(webSocket.secondary)) {\n logger.info(\"[Primary] WebSocket Cleanly Closed\");\n webSocket.primary = webSocket.secondary;\n webSocket.secondary = null;\n }\n printWebSocketState(\"webSocketOnClose after-cleanup\");\n };\n\n const webSocketOnError = function(event) {\n printWebSocketState(\"webSocketOnError\");\n logger.error(\"WebSocketManager Error, error_event: \", JSON.stringify(event));\n getWebSocketConnConfig();\n };\n\n const webSocketOnMessage = function(event) {\n const response = JSON.parse(event.data);\n\n switch (response.topic) {\n\n case ROUTE_KEY.SUBSCRIBE:\n logger.debug(\"Subscription Message received from webSocket server\", event.data);\n topicSubscriptionConfig.requestCompleted = true;\n topicSubscriptionConfig.consecutiveNoResponseRequest = 0;\n\n if (response.content.status === \"success\") {\n topicSubscriptionConfig.consecutiveFailedSubscribeAttempts = 0;\n response.content.topics.forEach( topicName => {\n topicSubscription.subscriptionHistory.delete(topicName);\n topicSubscription.pending.delete(topicName);\n topicSubscription.subscribed.add(topicName);\n });\n if (topicSubscription.subscriptionHistory.size === 0) {\n if (isWebSocketOpen(webSocket.secondary)) {\n logger.info(\"Successfully subscribed secondary websocket to all topics of primary websocket\");\n closeSpecificWebSocket(webSocket.primary, \"[Primary WebSocket] Closing WebSocket\");\n }\n } else {\n subscribePendingTopics();\n }\n invokeCallbacks(callbacks.subscriptionUpdate, response);\n\n } else {\n clearInterval(topicSubscriptionConfig.reSubscribeIntervalId);\n ++topicSubscriptionConfig.consecutiveFailedSubscribeAttempts;\n if (topicSubscriptionConfig.consecutiveFailedSubscribeAttempts === MAX_CONSECUTIVE_FAILED_SUB_ATTEMPTS) {\n invokeCallbacks(callbacks.subscriptionFailure, response);\n topicSubscriptionConfig.consecutiveFailedSubscribeAttempts = 0;\n return;\n }\n topicSubscriptionConfig.reSubscribeIntervalId = setInterval(function () {\n subscribePendingTopics();\n }, TOPIC_SUBSCRIPTION_RETRY_INTERVAL_MS);\n }\n break;\n\n case ROUTE_KEY.HEARTBEAT:\n logger.debug(\"Heartbeat response received\");\n heartbeatConfig.pendingResponse = false;\n break;\n\n default:\n if (response.topic) {\n logger.debug(\"Message received for topic \" + response.topic);\n if (isWebSocketOpen(webSocket.primary) && isWebSocketOpen(webSocket.secondary)\n && topicSubscription.subscriptionHistory.size === 0 && this === webSocket.primary) {\n /**\n * This block is to handle scenario when both primary and secondary socket have subscribed to\n * a common topic but we are facing difficulty in closing the primary socket, then in this\n * situation messages will be received by both primary and secondary web socket\n */\n logger.warn(\"Ignoring Message for Topic \" + response.topic + \", to avoid duplicates\");\n return;\n }\n\n if (callbacks.allMessage.size === 0 && callbacks.topic.size === 0) {\n logger.warn('No registered callback listener for Topic', response.topic);\n return;\n }\n invokeCallbacks(callbacks.allMessage, response);\n if (callbacks.topic.has(response.topic)) {\n invokeCallbacks(callbacks.topic.get(response.topic), response);\n }\n\n } else if (response.message) {\n logger.warn(\"WebSocketManager Message Error\", response);\n } else {\n logger.warn(\"Invalid incoming message\", response);\n }\n }\n };\n\n const subscribePendingTopics = function() {\n if (topicSubscriptionConfig.consecutiveNoResponseRequest > MAX_CONSECUTIVE_SUB_REQUEST_WITH_NO_RESPONSE) {\n logger.warn(\"Ignoring subscribePendingTopics since we have exhausted max subscription retries with no response\");\n invokeCallbacks(callbacks.subscriptionFailure, Utils.getSubscriptionResponse(ROUTE_KEY.SUBSCRIBE, false, Array.from(topicSubscription.pending)));\n return;\n }\n if (!isDefaultWebSocketOpen()) {\n logger.warn(\"Ignoring subscribePendingTopics call since Default WebSocket is not open\");\n return;\n }\n\n clearInterval(topicSubscriptionConfig.responseCheckIntervalId);\n\n getDefaultWebSocket().send(createWebSocketPayload(ROUTE_KEY.SUBSCRIBE, {\n \"topics\": Array.from(topicSubscription.pending)\n }));\n topicSubscriptionConfig.requestCompleted = false;\n\n // This callback ensure that some response was received for subscription request\n topicSubscriptionConfig.responseCheckIntervalId = setInterval(function () {\n if (!topicSubscriptionConfig.requestCompleted) {\n ++topicSubscriptionConfig.consecutiveNoResponseRequest;\n subscribePendingTopics();\n }\n }, MAX_WAIT_TIME_SUB_REQUEST_WITH_NO_RESPONSE_MS);\n };\n\n const closeSpecificWebSocket = function(ws, reason) {\n if (isWebSocketState(ws, WebSocket.CONNECTING) || isWebSocketState(ws, WebSocket.OPEN)) {\n ws.close(1000, reason);\n } else {\n logger.warn(\"Ignoring WebSocket Close request, WebSocket State: \" + getWebSocketStates(ws));\n }\n };\n\n const closeWebSocket = function(reason) {\n closeSpecificWebSocket(webSocket.primary, \"[Primary] WebSocket \" + reason);\n closeSpecificWebSocket(webSocket.secondary, \"[Secondary] WebSocket \" + reason);\n };\n\n const retryWebSocketInitialization = function () {\n metrics.connectWebSocketRetryCount++;\n const waitTime = Utils.addJitter(reconnectConfig.exponentialBackOffTime, WEBSOCKET_REINIT_JITTER);\n if (Date.now() + waitTime <= webSocketConfig.connConfig.urlConnValidTime) {\n logger.debug(\"Scheduling WebSocket reinitialization, after delay \" + waitTime + \" ms\");\n reconnectConfig.exponentialTimeoutHandle = setTimeout(() => initWebSocket(), waitTime);\n reconnectConfig.exponentialBackOffTime *= 2;\n } else {\n logger.warn(\"WebSocket URL cannot be used to establish connection\");\n getWebSocketConnConfig();\n }\n };\n\n const terminateWebSocketManager = function (response) {\n resetWebSocketState();\n resetSubscriptions();\n logger.error(\"WebSocket Initialization failed\");\n reconnectConfig.websocketInitFailed = true;\n closeWebSocket(\"Terminating WebSocket Manager\");\n clearInterval(networkConnectivityChecker);\n invokeCallbacks(callbacks.initFailure, {\n connectWebSocketRetryCount: metrics.connectWebSocketRetryCount,\n connectionAttemptStartTime: metrics.connectionAttemptStartTime,\n reason: response\n });\n resetMetrics();\n };\n\n const createWebSocketPayload = function (key, content) {\n return JSON.stringify({\n \"topic\": key,\n \"content\": content\n });\n };\n\n const sendMessage = function(payload) {\n Utils.assertIsObject(payload, \"payload\");\n if (payload.topic === undefined || invalidSendMessageRouteKeys.has(payload.topic)) {\n logger.warn(\"Cannot send message, Invalid topic\", payload);\n return;\n }\n try {\n payload = JSON.stringify(payload);\n } catch (error) {\n logger.warn(\"Error stringify message\", payload);\n return;\n }\n if (isDefaultWebSocketOpen()) {\n getDefaultWebSocket().send(payload);\n } else {\n logger.warn(\"Cannot send message, web socket connection is not open\");\n }\n };\n\n const subscribeTopics = function(topics) {\n Utils.assertNotNull(topics, 'topics');\n Utils.assertIsList(topics);\n\n topics.forEach(topic => {\n if (!topicSubscription.subscribed.has(topic)) {\n topicSubscription.pending.add(topic);\n }\n });\n // This ensure all participant-request to subscribe to topic chat are served at least once\n topicSubscriptionConfig.consecutiveNoResponseRequest = 0;\n subscribePendingTopics();\n };\n\n const validWebSocketConnConfig = function (connConfig) {\n if (Utils.isObject(connConfig) && Utils.isObject(connConfig.webSocketTransport)\n && Utils.isNonEmptyString(connConfig.webSocketTransport.url)\n && Utils.validWSUrl(connConfig.webSocketTransport.url) &&\n connConfig.webSocketTransport.transportLifeTimeInSeconds * 1000 >= MIN_WEBSOCKET_LIFETIME_MS) {\n return true;\n }\n logger.error(\"Invalid WebSocket Connection Configuration\", connConfig);\n return false;\n };\n\n const getWebSocketConnConfig = function () {\n if (!Utils.isNetworkOnline()) {\n logger.info(\"Network offline, ignoring this getWebSocketConnConfig request\");\n return;\n }\n if (reconnectConfig.websocketInitFailed) {\n logger.debug(\"WebSocket Init had failed, ignoring this getWebSocketConnConfig request\");\n return;\n }\n if (!webSocketConfig.promiseCompleted) {\n logger.debug(\"There is an ongoing getWebSocketConnConfig request, this request will be ignored\");\n return;\n }\n resetWebSocketState();\n logger.info(\"Fetching new WebSocket connection configuration\");\n metrics.connectionAttemptStartTime = metrics.connectionAttemptStartTime || Date.now();\n webSocketConfig.promiseCompleted = false;\n webSocketConfig.promiseHandle = callbacks.getWebSocketTransport();\n return webSocketConfig.promiseHandle\n .then(function(response) {\n webSocketConfig.promiseCompleted = true;\n logger.debug(\"Successfully fetched webSocket connection configuration\", response);\n if (!validWebSocketConnConfig(response)) {\n terminateWebSocketManager(\"Invalid WebSocket connection configuration: \" + response);\n return { webSocketConnectionFailed: true };\n }\n webSocketConfig.connConfig = response;\n // Ideally this URL validity time should be provided by server\n webSocketConfig.connConfig.urlConnValidTime = Date.now() + WEBSOCKET_URL_VALID_TIME_MS;\n return initWebSocket();\n },\n function(reason) {\n webSocketConfig.promiseCompleted = true;\n logger.error(\"Failed to fetch webSocket connection configuration\", reason);\n return { webSocketConnectionFailed: true };\n });\n };\n\n const initWebSocket = function() {\n if (reconnectConfig.websocketInitFailed) {\n logger.info(\"web-socket initializing had failed, aborting re-init\");\n return { webSocketConnectionFailed: true };\n }\n if (!Utils.isNetworkOnline()) {\n logger.warn(\"System is offline aborting web-socket init\");\n return { webSocketConnectionFailed: true };\n }\n logger.info(\"Initializing Websocket Manager\");\n printWebSocketState(\"initWebSocket\");\n try {\n if (validWebSocketConnConfig(webSocketConfig.connConfig)) {\n let ws = null;\n if (isWebSocketOpen(webSocket.primary)) {\n logger.debug(\"Primary Socket connection is already open\");\n if (!isWebSocketState(webSocket.secondary, WebSocket.CONNECTING)) {\n logger.debug(\"Establishing a secondary web-socket connection\");\n webSocket.secondary = getNewWebSocket();\n }\n ws = webSocket.secondary;\n } else {\n if (!isWebSocketState(webSocket.primary, WebSocket.CONNECTING)) {\n logger.debug(\"Establishing a primary web-socket connection\");\n webSocket.primary = getNewWebSocket();\n }\n ws = webSocket.primary;\n }\n\n // WebSocket creation is async task hence we Wait for 1sec before any potential retry\n reconnectConfig.webSocketInitCheckerTimeoutId = setTimeout(function() {\n if (!isWebSocketOpen(ws)) {\n retryWebSocketInitialization();\n }\n }, 1000);\n return { webSocketConnectionFailed: false };\n }\n } catch (error) {\n logger.error(\"Error Initializing web-socket-manager\", error);\n terminateWebSocketManager(\"Failed to initialize new WebSocket: \" + error.message);\n return { webSocketConnectionFailed: true };\n }\n };\n\n const getNewWebSocket = function() {\n let ws = new WebSocket(webSocketConfig.connConfig.webSocketTransport.url);\n ws.addEventListener(\"open\", webSocketOnOpen);\n ws.addEventListener(\"message\", webSocketOnMessage);\n ws.addEventListener(\"error\", webSocketOnError);\n ws.addEventListener(\"close\", event => webSocketOnClose(event, ws));\n return ws;\n };\n\n const onConnectionOpen = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionOpen.add(cb);\n return () => callbacks.connectionOpen.delete(cb);\n };\n\n const onConnectionClose = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionClose.add(cb);\n return () => callbacks.connectionClose.delete(cb);\n };\n\n const onConnectionGain = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionGain.add(cb);\n if (isDefaultWebSocketOpen()) {\n cb();\n }\n return () => callbacks.connectionGain.delete(cb);\n };\n\n const onConnectionLost = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.connectionLost.add(cb);\n if (reconnectConfig.connState === CONN_STATE.DISCONNECTED) {\n cb();\n }\n return () => callbacks.connectionLost.delete(cb);\n };\n\n const onInitFailure = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.initFailure.add(cb);\n if (reconnectConfig.websocketInitFailed) {\n cb();\n }\n return () => callbacks.initFailure.delete(cb);\n };\n\n const init = function(transportHandle) {\n Utils.assertTrue(Utils.isFunction(transportHandle), 'transportHandle must be a function');\n if (callbacks.getWebSocketTransport !== null) {\n logger.warn(\"Web Socket Manager was already initialized\");\n return;\n }\n callbacks.getWebSocketTransport = transportHandle;\n\n return getWebSocketConnConfig();\n };\n\n const onSubscriptionUpdate = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.subscriptionUpdate.add(cb);\n return () => callbacks.subscriptionUpdate.delete(cb);\n };\n\n const onSubscriptionFailure = function(cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.subscriptionFailure.add(cb);\n return () => callbacks.subscriptionFailure.delete(cb);\n };\n\n const onMessage = function(topicName, cb) {\n Utils.assertNotNull(topicName, 'topicName');\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n if (callbacks.topic.has(topicName)) {\n callbacks.topic.get(topicName).add(cb);\n } else {\n callbacks.topic.set(topicName, new Set([cb]));\n }\n return () => callbacks.topic.get(topicName).delete(cb);\n };\n\n const onAllMessage = function (cb) {\n Utils.assertTrue(Utils.isFunction(cb), 'cb must be a function');\n callbacks.allMessage.add(cb);\n return () => callbacks.allMessage.delete(cb);\n };\n\n this.init = init;\n this.onInitFailure = onInitFailure;\n this.onConnectionOpen = onConnectionOpen;\n this.onConnectionClose = onConnectionClose;\n this.onConnectionGain = onConnectionGain;\n this.onConnectionLost = onConnectionLost;\n this.onSubscriptionUpdate = onSubscriptionUpdate;\n this.onSubscriptionFailure = onSubscriptionFailure;\n this.onMessage = onMessage;\n this.onAllMessage = onAllMessage;\n this.subscribeTopics = subscribeTopics;\n this.sendMessage = sendMessage;\n\n this.closeWebSocket = function() {\n resetWebSocketState();\n resetSubscriptions();\n reconnectConfig.reconnectWebSocket = false;\n clearInterval(networkConnectivityChecker);\n closeWebSocket(\"User request to close WebSocket\");\n };\n\n this.terminateWebSocketManager = terminateWebSocketManager;\n};\n\nconst WebSocketManagerConstructor = () => {\n return new WebSocketManager();\n};\n\nconst setGlobalConfig = config => {\n const loggerConfig = config.loggerConfig;\n LogManager.updateLoggerConfig(loggerConfig);\n};\n\nconst WebSocketManagerObject = {\n create: WebSocketManagerConstructor,\n setGlobalConfig: setGlobalConfig,\n LogLevel: LogLevel,\n Logger: Logger\n};\n\nexport { WebSocketManagerObject };\n","/* global window, exports, define */\n\n!function() {\n 'use strict'\n\n var re = {\n not_string: /[^s]/,\n not_bool: /[^t]/,\n not_type: /[^T]/,\n not_primitive: /[^v]/,\n number: /[diefg]/,\n numeric_arg: /[bcdiefguxX]/,\n json: /[j]/,\n not_json: /[^j]/,\n text: /^[^\\x25]+/,\n modulo: /^\\x25{2}/,\n placeholder: /^\\x25(?:([1-9]\\d*)\\$|\\(([^)]+)\\))?(\\+)?(0|'[^$])?(-)?(\\d+)?(?:\\.(\\d+))?([b-gijostTuvxX])/,\n key: /^([a-z_][a-z_\\d]*)/i,\n key_access: /^\\.([a-z_][a-z_\\d]*)/i,\n index_access: /^\\[(\\d+)\\]/,\n sign: /^[+-]/\n }\n\n function sprintf(key) {\n // `arguments` is not an array, but should be fine for this call\n return sprintf_format(sprintf_parse(key), arguments)\n }\n\n function vsprintf(fmt, argv) {\n return sprintf.apply(null, [fmt].concat(argv || []))\n }\n\n function sprintf_format(parse_tree, argv) {\n var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign\n for (i = 0; i < tree_length; i++) {\n if (typeof parse_tree[i] === 'string') {\n output += parse_tree[i]\n }\n else if (typeof parse_tree[i] === 'object') {\n ph = parse_tree[i] // convenience purposes only\n if (ph.keys) { // keyword argument\n arg = argv[cursor]\n for (k = 0; k < ph.keys.length; k++) {\n if (arg == undefined) {\n throw new Error(sprintf('[sprintf] Cannot access property \"%s\" of undefined value \"%s\"', ph.keys[k], ph.keys[k-1]))\n }\n arg = arg[ph.keys[k]]\n }\n }\n else if (ph.param_no) { // positional argument (explicit)\n arg = argv[ph.param_no]\n }\n else { // positional argument (implicit)\n arg = argv[cursor++]\n }\n\n if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {\n arg = arg()\n }\n\n if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {\n throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))\n }\n\n if (re.number.test(ph.type)) {\n is_positive = arg >= 0\n }\n\n switch (ph.type) {\n case 'b':\n arg = parseInt(arg, 10).toString(2)\n break\n case 'c':\n arg = String.fromCharCode(parseInt(arg, 10))\n break\n case 'd':\n case 'i':\n arg = parseInt(arg, 10)\n break\n case 'j':\n arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)\n break\n case 'e':\n arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()\n break\n case 'f':\n arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)\n break\n case 'g':\n arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)\n break\n case 'o':\n arg = (parseInt(arg, 10) >>> 0).toString(8)\n break\n case 's':\n arg = String(arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 't':\n arg = String(!!arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'T':\n arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'u':\n arg = parseInt(arg, 10) >>> 0\n break\n case 'v':\n arg = arg.valueOf()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'x':\n arg = (parseInt(arg, 10) >>> 0).toString(16)\n break\n case 'X':\n arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()\n break\n }\n if (re.json.test(ph.type)) {\n output += arg\n }\n else {\n if (re.number.test(ph.type) && (!is_positive || ph.sign)) {\n sign = is_positive ? '+' : '-'\n arg = arg.toString().replace(re.sign, '')\n }\n else {\n sign = ''\n }\n pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '\n pad_length = ph.width - (sign + arg).length\n pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''\n output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)\n }\n }\n }\n return output\n }\n\n var sprintf_cache = Object.create(null)\n\n function sprintf_parse(fmt) {\n if (sprintf_cache[fmt]) {\n return sprintf_cache[fmt]\n }\n\n var _fmt = fmt, match, parse_tree = [], arg_names = 0\n while (_fmt) {\n if ((match = re.text.exec(_fmt)) !== null) {\n parse_tree.push(match[0])\n }\n else if ((match = re.modulo.exec(_fmt)) !== null) {\n parse_tree.push('%')\n }\n else if ((match = re.placeholder.exec(_fmt)) !== null) {\n if (match[2]) {\n arg_names |= 1\n var field_list = [], replacement_field = match[2], field_match = []\n if ((field_match = re.key.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {\n if ((field_match = re.key_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else if ((field_match = re.index_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n }\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n match[2] = field_list\n }\n else {\n arg_names |= 2\n }\n if (arg_names === 3) {\n throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')\n }\n\n parse_tree.push(\n {\n placeholder: match[0],\n param_no: match[1],\n keys: match[2],\n sign: match[3],\n pad_char: match[4],\n align: match[5],\n width: match[6],\n precision: match[7],\n type: match[8]\n }\n )\n }\n else {\n throw new SyntaxError('[sprintf] unexpected placeholder')\n }\n _fmt = _fmt.substring(match[0].length)\n }\n return sprintf_cache[fmt] = parse_tree\n }\n\n /**\n * export to either browser or node.js\n */\n /* eslint-disable quote-props */\n if (typeof exports !== 'undefined') {\n exports['sprintf'] = sprintf\n exports['vsprintf'] = vsprintf\n }\n if (typeof window !== 'undefined') {\n window['sprintf'] = sprintf\n window['vsprintf'] = vsprintf\n\n if (typeof define === 'function' && define['amd']) {\n define(function() {\n return {\n 'sprintf': sprintf,\n 'vsprintf': vsprintf\n }\n })\n }\n }\n /* eslint-enable quote-props */\n}(); // eslint-disable-line\n","/*eslint no-unused-vars: \"off\"*/\nimport { WebSocketManagerObject } from \"./webSocketManager\";\n\nglobal.connect = global.connect || {};\nconnect.WebSocketManager = WebSocketManagerObject;\n\nexport const WebSocketManager = WebSocketManagerObject;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n"],"sourceRoot":""} diff --git a/src/log.js b/src/log.js index 394e1db5..e681777e 100644 --- a/src/log.js +++ b/src/log.js @@ -9,8 +9,11 @@ global.connect = connect; global.lily = connect; - // How frequently logs should be collected and reported to shared worker. - var LOG_REPORT_INTERVAL_MILLIS = 5000; + // How frequently softphone logs should be collected and reported to shared worker. + var SOFTPHONE_LOG_REPORT_INTERVAL_MILLIS = 5000; + + // How frequently logs should be collected and sent downstream + var LOGS_REPORT_INTERVAL_MILLIS = 5000; // The default log roll interval (30min) var DEFAULT_LOG_ROLL_INTERVAL = 1800000; @@ -35,7 +38,8 @@ var LogComponent = { CCP: "ccp", SOFTPHONE: "softphone", - CHAT: "chat" + CHAT: "chat", + TASK: "task" }; /** @@ -74,7 +78,7 @@ */ var isValidLogComponent = function (component) { - return [LogComponent.SOFTPHONE, LogComponent.CCP, LogComponent.CHAT].indexOf(component) !== -1; + return Object.values(LogComponent).indexOf(component) !== -1; }; /** @@ -85,6 +89,7 @@ var firstArg = args.shift(); var format; var component; + if (isValidLogComponent(firstArg)) { component = firstArg; format = args.shift(); @@ -93,6 +98,7 @@ format = firstArg; component = LogComponent.CCP; } + return { format: format, component: component, @@ -207,6 +213,15 @@ return this; }; + /** + * Indicate that this log entry should be sent to the server + * NOTE: This should be used for internal logs only + */ + LogEntry.prototype.sendInternalLogToServer = function () { + connect.getLog()._serverBoundInternalLogs.push(this); + return this; + }; + /** * The logger instance. */ @@ -214,6 +229,7 @@ this._logs = []; this._rolledLogs = []; this._logsToPush = []; + this._serverBoundInternalLogs = []; this._echoLevel = LogLevelOrder.INFO; this._logLevel = LogLevelOrder.INFO; this._lineCount = 0; @@ -286,6 +302,7 @@ Logger.prototype.addLogEntry = function (logEntry) { this._logs.push(logEntry); + //For now only send softphone logs only. //TODO add CCP logs once we are sure that no sensitive data is being logged. if (LogComponent.SOFTPHONE === logEntry.component) { @@ -303,6 +320,20 @@ } }; + Logger.prototype.sendInternalLogEntryToServer = function (logEntry) { + this._serverBoundInternalLogs.push(logEntry); + + if (logEntry.level in LogLevelOrder && + LogLevelOrder[logEntry.level] >= this._logLevel) { + + if (LogLevelOrder[logEntry.level] >= this._echoLevel) { + CONSOLE_LOGGER_MAP[logEntry.getLevel()](logEntry.toString()); + } + + logEntry.line = this._lineCount++; + } + }; + /** * Remove all objects from all log entries. */ @@ -424,7 +455,7 @@ if (!connect.upstreamLogPushScheduled) { connect.upstreamLogPushScheduled = true; /** Schedule pushing logs frequently to sharedworker upstream, sharedworker will report to LARS*/ - global.setInterval(connect.hitch(this, this.reportMasterLogsUpStream, conduit), LOG_REPORT_INTERVAL_MILLIS); + global.setInterval(connect.hitch(this, this.reportMasterLogsUpStream, conduit), SOFTPHONE_LOG_REPORT_INTERVAL_MILLIS); } }; @@ -442,9 +473,33 @@ return this._loggerId; }; + Logger.prototype.scheduleDownstreamClientSideLogsPush = function () { + global.setInterval(connect.hitch(this, this.pushClientSideLogsDownstream), LOGS_REPORT_INTERVAL_MILLIS); + } + + Logger.prototype.pushClientSideLogsDownstream = function () { + var logs = []; + + // We do not send a request if we have less than 50 records so that we minimize the number of + // requests per second. + // 500 is the max we accept on the server. + // We chose 500 because this is the limit imposed by Firehose for a put batch request + if (this._serverBoundInternalLogs.length < 50) { + return; + } else if (this._serverBoundInternalLogs.length > 500) { + logs = this._serverBoundInternalLogs.splice(0, 500); + } else { + logs = this._serverBoundInternalLogs; + this._serverBoundInternalLogs = []; + } + + connect.publishClientSideLogs(logs); + } + var DownstreamConduitLogger = function (conduit) { Logger.call(this); this.conduit = conduit; + global.setInterval(connect.hitch(this, this._pushLogsDownstream), DownstreamConduitLogger.LOG_PUSH_INTERVAL); @@ -467,10 +522,17 @@ DownstreamConduitLogger.prototype._pushLogsDownstream = function () { var self = this; + this._logs.forEach(function (log) { self.conduit.sendDownstream(connect.EventType.LOG, log); }); this._logs = []; + + for (var i = 0; i < this._serverBoundInternalLogs.length; i++) { + this.conduit.sendDownstream(connect.EventType.SERVER_BOUND_INTERNAL_LOG, this._serverBoundInternalLogs[i]); + } + + this._serverBoundInternalLogs = []; }; /** Create the singleton logger instance. */ diff --git a/src/mediaControllers/chat.js b/src/mediaControllers/chat.js index 6a5ba883..16970e4a 100644 --- a/src/mediaControllers/chat.js +++ b/src/mediaControllers/chat.js @@ -24,7 +24,8 @@ var createMediaInstance = function () { publishTelemetryEvent("Chat media controller init", mediaInfo.contactId); - logger.info(logComponent, "Chat media controller init").withObject(mediaInfo); + logger.info(logComponent, "Chat media controller init") + .withObject(mediaInfo).sendInternalLogToServer(); connect.ChatSession.setGlobalConfig({ loggerConfig: { @@ -44,12 +45,14 @@ return controller .connect() .then(function (data) { - logger.info(logComponent, "Chat Session Successfully established for contactId %s", mediaInfo.contactId); + logger.info(logComponent, "Chat Session Successfully established for contactId %s", mediaInfo.contactId) + .sendInternalLogToServer(); publishTelemetryEvent("Chat Session Successfully established", mediaInfo.contactId); return controller; }) .catch(function (error) { - logger.error(logComponent, "Chat Session establishement failed for contact %s", mediaInfo.contactId).withException(error); + logger.error(logComponent, "Chat Session establishement failed for contact %s", mediaInfo.contactId) + .withException(error).sendInternalLogToServer(); publishTelemetryEvent("Chat Session establishement failed", mediaInfo.contactId, error); throw error; }); @@ -65,12 +68,14 @@ var trackChatConnectionStatus = function (controller) { controller.onConnectionBroken(function (data) { - logger.error(logComponent, "Chat Session connection broken").withException(data); + logger.error(logComponent, "Chat Session connection broken") + .withException(data).sendInternalLogToServer(); publishTelemetryEvent("Chat Session connection broken", data); }); controller.onConnectionEstablished(function (data) { - logger.info(logComponent, "Chat Session connection established").withObject(data); + logger.info(logComponent, "Chat Session connection established") + .withObject(data).sendInternalLogToServer(); publishTelemetryEvent("Chat Session connection established", data); }); } diff --git a/src/mediaControllers/factory.js b/src/mediaControllers/factory.js index fc2f9c4c..81743616 100644 --- a/src/mediaControllers/factory.js +++ b/src/mediaControllers/factory.js @@ -21,11 +21,12 @@ connect.MediaFactory = function (params) { /** controller holder */ var mediaControllers = {}; + var toBeDestroyed = new Set(); var logger = connect.getLog(); var logComponent = connect.LogComponent.CHAT; - var metadata = params || {}; + var metadata = connect.merge({}, params) || {}; metadata.region = metadata.region || "us-west-2"; // Default it to us-west-2 var getMediaController = function (connectionObj) { @@ -33,19 +34,24 @@ var mediaInfo = connectionObj.getMediaInfo(); /** if we do not have the media info then just reject the request */ if (!mediaInfo) { - logger.error(logComponent, "Media info does not exists for a media type %s").withObject(connectionObj); + logger.error(logComponent, "Media info does not exists for a media type %s") + .withObject(connectionObj).sendInternalLogToServer(); return Promise.reject("Media info does not exists for this connection"); } if (!mediaControllers[connectionId]) { - logger.info(logComponent, "media controller of type %s init", connectionObj.getMediaType()).withObject(connectionObj); + logger.info(logComponent, "media controller of type %s init", connectionObj.getMediaType()) + .withObject(connectionObj).sendInternalLogToServer(); switch (connectionObj.getMediaType()) { case connect.MediaType.CHAT: return mediaControllers[connectionId] = new connect.ChatMediaController(connectionObj.getMediaInfo(), metadata).get(); case connect.MediaType.SOFTPHONE: return mediaControllers[connectionId] = new connect.SoftphoneMediaController(connectionObj.getMediaInfo()).get(); + case connect.MediaType.TASK: + return mediaControllers[connectionId] = new connect.TaskMediaController(connectionObj.getMediaInfo()).get(); default: - logger.error(logComponent, "Unrecognized media type %s ", connectionObj.getMediaType()); + logger.error(logComponent, "Unrecognized media type %s ", connectionObj.getMediaType()) + .sendInternalLogToServer(); return Promise.reject(); } } else { @@ -68,9 +74,23 @@ }; var destroy = function (connectionId) { - if (mediaControllers[connectionId]) { - logger.info(logComponent, "Destroying mediaController for %s", connectionId); - delete mediaControllers[connectionId]; + if (mediaControllers[connectionId] && !toBeDestroyed.has(connectionId)) { + logger.info( + logComponent, + "Destroying mediaController for %s", + connectionId + ); + toBeDestroyed.add(connectionId); + mediaControllers[connectionId] + .then(function() { + if (typeof controller.cleanUp === "function") controller.cleanUp(); + delete mediaControllers[connectionId]; + toBeDestroyed.delete(connectionId); + }) + .catch(function() { + delete mediaControllers[connectionId]; + toBeDestroyed.delete(connectionId); + }); } }; diff --git a/src/mediaControllers/task.js b/src/mediaControllers/task.js new file mode 100644 index 00000000..f2dc736e --- /dev/null +++ b/src/mediaControllers/task.js @@ -0,0 +1,100 @@ +/* + * Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Amazon Software License (the "License"). You may not use + * this file except in compliance with the License. A copy of the License is + * located at + * + * http://aws.amazon.com/asl/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +(function () { + var global = this; + connect = global.connect || {}; + global.connect = connect; + + connect.TaskMediaController = function (mediaInfo) { + var logger = connect.getLog(); + var logComponent = connect.LogComponent.TASK; + + var createMediaInstance = function () { + publishTelemetryEvent("Task media controller init", mediaInfo.contactId); + logger + .info(logComponent, "Task media controller init") + .withObject(mediaInfo); + + var controller = connect.TaskSession.create({ + contactId: mediaInfo.contactId, + initialContactId: mediaInfo.initialContactId, + websocketManager: connect.core.getWebSocketManager(), + }); + + trackTaskConnectionStatus(controller); + + return controller + .connect() + .then(function () { + logger.info( + logComponent, + "Task Session Successfully established for contactId %s", + mediaInfo.contactId + ); + publishTelemetryEvent( + "Task Session Successfully established", + mediaInfo.contactId + ); + return controller; + }) + .catch(function (error) { + logger + .error( + logComponent, + "Task Session establishement failed for contact %s", + mediaInfo.contactId + ) + .withException(error); + publishTelemetryEvent( + "Chat Session establishement failed", + mediaInfo.contactId, + error + ); + throw error; + }); + }; + + var publishTelemetryEvent = function (eventName, data) { + connect.publishMetric({ + name: eventName, + contactId: mediaInfo.contactId, + data: data || mediaInfo, + }); + }; + + var trackTaskConnectionStatus = function (controller) { + controller.onConnectionBroken(function (data) { + logger + .error(logComponent, "Task Session connection broken") + .withException(data); + publishTelemetryEvent("Task Session connection broken", data); + }); + + controller.onConnectionEstablished(function (data) { + logger + .info(logComponent, "Task Session connection established") + .withObject(data); + publishTelemetryEvent("Task Session connection established", data); + }); + }; + + return { + get: function () { + return createMediaInstance(); + }, + }; + }; +})(); diff --git a/src/ringtone.js b/src/ringtone.js index 3b64bf02..11e138a0 100644 --- a/src/ringtone.js +++ b/src/ringtone.js @@ -30,7 +30,7 @@ } else { this._audio = null; - connect.getLog().error("Unable to provide a ringtone."); + connect.getLog().error("Unable to provide a ringtone.").sendInternalLogToServer(); } self._driveRingtone(); @@ -171,6 +171,28 @@ }); }; + var TaskRingtoneEngine = function (ringtoneConfig) { + RingtoneEngineBase.call(this, ringtoneConfig); + }; + TaskRingtoneEngine.prototype = Object.create(RingtoneEngineBase.prototype); + TaskRingtoneEngine.prototype.constructor = TaskRingtoneEngine; + + TaskRingtoneEngine.prototype._driveRingtone = function () { + var self = this; + + var onContactConnect = function (contact) { + if (contact.getType() === lily.ContactType.TASK && contact.isInbound()) { + self._ringtoneSetup(contact); + self._publishTelemetryEvent("Task Ringtone Connecting", contact); + } + }; + + connect.contact(function (contact) { + contact.onConnecting(onContactConnect); + }); + }; + + var QueueCallbackRingtoneEngine = function (ringtoneConfig) { RingtoneEngineBase.call(this, ringtoneConfig); }; @@ -193,5 +215,6 @@ /* export connect.RingtoneEngine */ connect.VoiceRingtoneEngine = VoiceRingtoneEngine; connect.ChatRingtoneEngine = ChatRingtoneEngine; + connect.TaskRingtoneEngine = TaskRingtoneEngine; connect.QueueCallbackRingtoneEngine = QueueCallbackRingtoneEngine; })(); diff --git a/src/softphone.js b/src/softphone.js index 5c6580ed..943540a9 100644 --- a/src/softphone.js +++ b/src/softphone.js @@ -120,7 +120,7 @@ delete callsDetected[agentConnectionId]; session.hangup(); }).catch(function (err) { - lily.getLog().warn("Clean up the session locally " + agentConnectionId, err.message); + lily.getLog().warn("Clean up the session locally " + agentConnectionId, err.message).sendInternalLogToServer(); }); } }; @@ -160,7 +160,7 @@ // Set to true, this will block subsequent invokes from entering. callsDetected[agentConnectionId] = true; - logger.info("Softphone call detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId); + logger.info("Softphone call detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId).sendInternalLogToServer(); // Ensure our session state matches our contact state to prevent issues should we lose track of a contact. sanityCheckActiveSessions(rtcSessions); @@ -252,7 +252,7 @@ var onInitContact = function (contact) { var agentConnectionId = contact.getAgentConnection().connectionId; - logger.info("Contact detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId); + logger.info("Contact detected:", "contactId " + contact.getContactId(), "agent connectionId " + agentConnectionId).sendInternalLogToServer(); if (!callsDetected[agentConnectionId]) { contact.onRefresh(function () { @@ -266,7 +266,8 @@ // Contact already in connecting state scenario - In this case contact INIT is missed hence the OnRefresh callback is missed. new connect.Agent().getContacts().forEach(function (contact) { var agentConnectionId = contact.getAgentConnection().connectionId; - logger.info("Contact exist in the snapshot. Reinitiate the Contact and RTC session creation for contactId" + contact.getContactId(), "agent connectionId " + agentConnectionId); + logger.info("Contact exist in the snapshot. Reinitiate the Contact and RTC session creation for contactId" + contact.getContactId(), "agent connectionId " + agentConnectionId) + .sendInternalLogToServer(); onInitContact(contact); onRefreshContact(contact, agentConnectionId); }); @@ -276,24 +277,26 @@ var conduit = connect.core.getUpstream(); var agentConnection = contact.getAgentConnection(); if (!agentConnection) { - logger.info("Not able to retrieve the auto-accept setting from null AgentConnection, ignoring event publish.."); + logger.info("Not able to retrieve the auto-accept setting from null AgentConnection, ignoring event publish..").sendInternalLogToServer(); return; } var softphoneMediaInfo = agentConnection.getSoftphoneMediaInfo(); if (!softphoneMediaInfo) { - logger.info("Not able to retrieve the auto-accept setting from null SoftphoneMediaInfo, ignoring event publish.."); + logger.info("Not able to retrieve the auto-accept setting from null SoftphoneMediaInfo, ignoring event publish..").sendInternalLogToServer(); return; } if (softphoneMediaInfo.autoAccept === true) { - logger.info("Auto-accept is enabled, sending out Accepted event to stop ringtone.."); + logger.info("Auto-accept is enabled, sending out Accepted event to stop ringtone..").sendInternalLogToServer(); conduit.sendUpstream(connect.EventType.BROADCAST, { - event: connect.ContactEvents.ACCEPTED + event: connect.ContactEvents.ACCEPTED, + data: new connect.Contact(contact.contactId) }); conduit.sendUpstream(connect.EventType.BROADCAST, { - event: connect.core.getContactEventName(connect.ContactEvents.ACCEPTED, contact.contactId) + event: connect.core.getContactEventName(connect.ContactEvents.ACCEPTED, contact.contactId), + data: new connect.Contact(contact.contactId) }); } else { - logger.info("Auto-accept is disabled, ringtone will be stopped by user action."); + logger.info("Auto-accept is disabled, ringtone will be stopped by user action.").sendInternalLogToServer(); } }; @@ -334,9 +337,9 @@ localMediaStream[connectionId].muted = status; if (status) { - logger.info("Agent has muted the contact, connectionId - " + connectionId); + logger.info("Agent has muted the contact, connectionId - " + connectionId).sendInternalLogToServer(); } else { - logger.info("Agent has unmuted the contact, connectionId - " + connectionId); + logger.info("Agent has unmuted the contact, connectionId - " + connectionId).sendInternalLogToServer(); } } else { @@ -379,7 +382,7 @@ rtcSession._signalingUri); } else if (reason === connect.RTCErrors.CALL_NOT_FOUND) { // No need to publish any softphone error for this case. CCP UX will handle this case. - logger.error("Softphone call failed due to CallNotFoundException."); + logger.error("Softphone call failed due to CallNotFoundException.").sendInternalLogToServer(); } else { publishError(SoftphoneErrorTypes.WEBRTC_ERROR, "webrtc system error. ", @@ -439,7 +442,7 @@ var publishError = function (errorType, message, endPointUrl) { logger.error("Softphone error occurred : ", errorType, - message || ""); + message || "").sendInternalLogToServer(); connect.core.getUpstream().sendUpstream(connect.EventType.BROADCAST, { event: connect.AgentEvents.SOFTPHONE_ERROR, @@ -469,7 +472,8 @@ name: "AgentConnectionId", value: agentConnectionId }]); - logger.info("Publish multiple session error metrics", eventName, "contactId " + contactId, "agent connectionId " + agentConnectionId); + logger.info("Publish multiple session error metrics", eventName, "contactId " + contactId, "agent connectionId " + agentConnectionId) + .sendInternalLogToServer(); }; var isBrowserSoftPhoneSupported = function () { @@ -495,11 +499,13 @@ if (streamStats.length > 0) { contact.sendSoftphoneMetrics(streamStats, { success: function () { - logger.info("sendSoftphoneMetrics success" + JSON.stringify(streamStats)); + logger.info("sendSoftphoneMetrics success" + JSON.stringify(streamStats)) + .sendInternalLogToServer(); }, failure: function (data) { logger.error("sendSoftphoneMetrics failed.") - .withObject(data); + .withObject(data) + .sendInternalLogToServer(); } }); } @@ -534,11 +540,13 @@ }; contact.sendSoftphoneReport(callReport, { success: function () { - logger.info("sendSoftphoneReport success" + JSON.stringify(callReport)); + logger.info("sendSoftphoneReport success" + JSON.stringify(callReport)) + .sendInternalLogToServer(); }, failure: function (data) { logger.error("sendSoftphoneReport failed.") - .withObject(data); + .withObject(data) + .sendInternalLogToServer(); } }); }; @@ -550,14 +558,14 @@ aggregatedUserAudioStats = stats; timeSeriesStreamStatsBuffer.push(getTimeSeriesStats(aggregatedUserAudioStats, previousUserStats, AUDIO_INPUT)); }, function (error) { - logger.debug("Failed to get user audio stats.", error); + logger.debug("Failed to get user audio stats.", error).sendInternalLogToServer(); }); rtcSession.getRemoteAudioStats().then(function (stats) { var previousRemoteStats = aggregatedRemoteAudioStats; aggregatedRemoteAudioStats = stats; timeSeriesStreamStatsBuffer.push(getTimeSeriesStats(aggregatedRemoteAudioStats, previousRemoteStats, AUDIO_OUTPUT)); }, function (error) { - logger.debug("Failed to get remote audio stats.", error); + logger.debug("Failed to get remote audio stats.", error).sendInternalLogToServer(); }); }, 1000); }; @@ -642,25 +650,25 @@ args.forEach(function () { format = format + " %s"; }); - method.apply(self._originalLogger, [connect.LogComponent.SOFTPHONE, format].concat(args)); + return method.apply(self._originalLogger, [connect.LogComponent.SOFTPHONE, format].concat(args)); }; }; }; SoftphoneLogger.prototype.debug = function () { - this._tee(1, this._originalLogger.debug)(arguments); + return this._tee(1, this._originalLogger.debug)(arguments); }; SoftphoneLogger.prototype.info = function () { - this._tee(2, this._originalLogger.info)(arguments); + return this._tee(2, this._originalLogger.info)(arguments); }; SoftphoneLogger.prototype.log = function () { - this._tee(3, this._originalLogger.log)(arguments); + return this._tee(3, this._originalLogger.log)(arguments); }; SoftphoneLogger.prototype.warn = function () { - this._tee(4, this._originalLogger.warn)(arguments); + return this._tee(4, this._originalLogger.warn)(arguments); }; SoftphoneLogger.prototype.error = function () { - this._tee(5, this._originalLogger.error)(arguments); + return this._tee(5, this._originalLogger.error)(arguments); }; connect.SoftphoneManager = SoftphoneManager; diff --git a/src/util.js b/src/util.js index 099bdd5b..28ecc7c9 100644 --- a/src/util.js +++ b/src/util.js @@ -207,6 +207,14 @@ return enumObj; }; + connect.makeGenericNamespacedEnum = function (prefix, values, delimiter) { + var enumObj = connect.makeEnum(values); + connect.keys(enumObj).forEach(function (key) { + enumObj[key] = connect.sprintf("%s"+delimiter+"%s", prefix, enumObj[key]); + }); + return enumObj; + }; + /** * Methods to determine browser type and versions, used for softphone initialization. */ @@ -330,6 +338,14 @@ return connect.sprintf("%s//%s:%s", location.protocol, location.hostname, location.port); }; + connect.getUrlWithProtocol = function(url) { + var protocol = global.location.protocol; + if (url.substr(0, protocol.length) !== protocol) { + return connect.sprintf("%s//%s", protocol, url); + } + return url; + } + /** * Determine if the current window is in an iframe. * Courtesy: http://stackoverflow.com/questions/326069/ @@ -403,6 +419,21 @@ bus.trigger(connect.EventType.CLIENT_METRIC, metricData); }; + connect.publishSoftphoneStats = function(stats) { + var bus = connect.core.getEventBus(); + bus.trigger(connect.EventType.SOFTPHONE_STATS, stats); + }; + + connect.publishSoftphoneReport = function(report) { + var bus = connect.core.getEventBus(); + bus.trigger(connect.EventType.SOFTPHONE_REPORT, report); + }; + + connect.publishClientSideLogs = function(logs) { + var bus = connect.core.getEventBus(); + bus.trigger(connect.EventType.CLIENT_SIDE_LOGS, logs); + }; + /** * A wrapper around Window.open() for managing single instance popups. */ @@ -481,11 +512,11 @@ connect.NotificationManager.prototype.requestPermission = function () { var self = this; if (!("Notification" in global)) { - connect.getLog().warn("This browser doesn't support notifications."); + connect.getLog().warn("This browser doesn't support notifications.").sendInternalLogToServer(); this.permission = NotificationPermission.DENIED; } else if (global.Notification.permission === NotificationPermission.DENIED) { - connect.getLog().warn("The user has requested to not receive notifications."); + connect.getLog().warn("The user has requested to not receive notifications.").sendInternalLogToServer(); this.permission = NotificationPermission.DENIED; } else if (this.permission !== NotificationPermission.GRANTED) { @@ -506,15 +537,18 @@ return this._showImpl({ title: title, options: options }); } else if (this.permission === NotificationPermission.DENIED) { - connect.getLog().warn("Unable to show notification.").withObject({ - title: title, - options: options - }); + connect.getLog().warn("Unable to show notification.") + .sendInternalLogToServer() + .withObject({ + title: title, + options: options + }); } else { var params = { title: title, options: options }; connect.getLog().warn("Deferring notification until user decides to allow or deny.") - .withObject(params); + .withObject(params) + .sendInternalLogToServer(); this.queue.push(params); } }; @@ -568,4 +602,13 @@ connect.StateError.prototype = Object.create(connect.BaseError.prototype); connect.StateError.prototype.constructor = connect.StateError; + connect.VoiceIdError = function(type, message, err){ + var error = {}; + error.type = type; + error.message = message; + error.stack = Error(message); + error.err = err; + return error; + } + })(); diff --git a/src/worker.js b/src/worker.js index 63048ba3..09cd6d15 100644 --- a/src/worker.js +++ b/src/worker.js @@ -62,23 +62,37 @@ WorkerClient.prototype._callImpl = function (method, params, callbacks) { var self = this; var request_start = new Date().getTime(); - connect.core.getClient()._callImpl(method, params, { - success: function (data) { - self._recordAPILatency(method, request_start); - callbacks.success(data); - }, - failure: function (error, data) { - self._recordAPILatency(method, request_start, error); - callbacks.failure(error, data); - }, - authFailure: function () { - self._recordAPILatency(method, request_start); - callbacks.authFailure(); - }, - accessDenied: function () { - callbacks.accessDenied && callbacks.accessDenied(); - } - }); + if(connect.containsValue(connect.AgentAppClientMethods, method)) { + connect.core.getAgentAppClient()._callImpl(method, params, { + success: function (data) { + self._recordAPILatency(method, request_start); + callbacks.success(data); + }, + failure: function (error, data) { + self._recordAPILatency(method, request_start, error); + callbacks.failure(error, data); + } + }) + } else { + connect.core.getClient()._callImpl(method, params, { + success: function (data) { + self._recordAPILatency(method, request_start); + callbacks.success(data); + }, + failure: function (error, data) { + self._recordAPILatency(method, request_start, error); + callbacks.failure(error, data); + }, + authFailure: function () { + self._recordAPILatency(method, request_start); + callbacks.authFailure(); + }, + accessDenied: function () { + callbacks.accessDenied && callbacks.accessDenied(); + } + }); + } + }; WorkerClient.prototype._recordAPILatency = function (method, request_start, err) { @@ -141,7 +155,8 @@ // init only once. if (!webSocketManager) { - connect.getLog().info("Creating a new Websocket connection for CCP"); + connect.getLog().info("Creating a new Websocket connection for CCP") + .sendInternalLogToServer(); connect.WebSocketManager.setGlobalConfig({ loggerConfig: { logger: connect.getLog() } @@ -194,13 +209,16 @@ webSocketManager.init(connect.hitch(self, self.getWebSocketUrl)).then(function(response) { if (response && !response.webSocketConnectionFailed) { // Start polling for agent data. - connect.getLog().info("Kicking off agent polling"); + connect.getLog().info("Kicking off agent polling") + .sendInternalLogToServer(); self.pollForAgent(); - connect.getLog().info("Kicking off config polling"); + connect.getLog().info("Kicking off config polling") + .sendInternalLogToServer(); self.pollForAgentConfiguration({ repeatForever: true }); - connect.getLog().info("Kicking off auth token polling"); + connect.getLog().info("Kicking off auth token polling") + .sendInternalLogToServer(); global.setInterval(connect.hitch(self, self.checkAuthToken), CHECK_AUTH_TOKEN_INTERVAL_MS); } else { if (!connect.webSocketInitFailed) { @@ -210,7 +228,8 @@ } }); } else { - connect.getLog().info("Not Creating a Websocket instance, since there's already one exist"); + connect.getLog().info("Not Initializing a new WebsocketManager instance, since one already exists") + .sendInternalLogToServer(); } } }); @@ -275,10 +294,15 @@ self.agent.snapshot.localTimestamp = connect.now(); self.agent.snapshot.skew = self.agent.snapshot.snapshotTimestamp - self.agent.snapshot.localTimestamp; self.nextToken = data.nextToken; - connect.getLog().trace("GET_AGENT_SNAPSHOT succeeded.").withObject(data); + connect.getLog().trace("GET_AGENT_SNAPSHOT succeeded.") + .withObject(data) + .sendInternalLogToServer(); self.updateAgent(); } catch (e) { - connect.getLog().error("Long poll failed to update agent.").withObject(data).withException(e); + connect.getLog().error("Long poll failed to update agent.") + .withObject(data) + .withException(e) + .sendInternalLogToServer(); } finally { global.setTimeout(connect.hitch(self, self.pollForAgent), GET_AGENT_SUCCESS_TIMEOUT_MS); } @@ -286,6 +310,7 @@ failure: function (err, data) { try { connect.getLog().error("Failed to get agent data.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -324,6 +349,7 @@ failure: function (err, data) { try { connect.getLog().error("Failed to fetch agent configuration data.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -367,6 +393,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch agent states list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -402,6 +429,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch agent permissions list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -436,6 +464,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch dialable country codes list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -471,6 +500,7 @@ }, failure: function (err, data) { connect.getLog().error("Failed to fetch routing profile queues list.") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -493,7 +523,9 @@ var response = connect.EventFactory.createResponse(connect.EventType.API_RESPONSE, request, data, JSON.stringify(err)); portConduit.sendDownstream(response.event, response); connect.getLog().error("'%s' API request failed", request.method) - .withObject({ request: self.filterAuthToken(request), response: response }).withException(err); + .withObject({ request: self.filterAuthToken(request), response: response }) + .withException(err) + .sendInternalLogToServer(); }, authFailure: connect.hitch(self, self.handleAuthFail) }); @@ -549,19 +581,23 @@ this.updateAgent(); } else { - connect.getLog().trace("Waiting to update agent configuration until all config data has been fetched."); + connect.getLog().trace("Waiting to update agent configuration until all config data has been fetched.") + .sendInternalLogToServer(); } }; ClientEngine.prototype.updateAgent = function () { if (!this.agent) { - connect.getLog().trace("Waiting to update agent until the agent has been fully constructed."); + connect.getLog().trace("Waiting to update agent until the agent has been fully constructed.") + .sendInternalLogToServer(); } else if (!this.agent.snapshot) { - connect.getLog().trace("Waiting to update agent until the agent snapshot is available."); + connect.getLog().trace("Waiting to update agent until the agent snapshot is available.") + .sendInternalLogToServer(); } else if (!this.agent.configuration) { - connect.getLog().trace("Waiting to update agent until the agent configuration is available."); + connect.getLog().trace("Waiting to update agent until the agent configuration is available.") + .sendInternalLogToServer(); } else { // Alias some of the properties for backwards compatibility. @@ -612,11 +648,12 @@ return new Promise(function (resolve, reject) { client.call(connect.ClientMethods.CREATE_TRANSPORT, { transportType: connect.TRANSPORT_TYPES.WEB_SOCKET }, { success: function (data) { - connect.getLog().info("getWebSocketUrl succeeded"); + connect.getLog().info("getWebSocketUrl succeeded").sendInternalLogToServer(); resolve(data); }, failure: function (err, data) { connect.getLog().error("getWebSocketUrl failed") + .sendInternalLogToServer() .withObject({ err: err, data: data @@ -624,12 +661,12 @@ reject(Error("getWebSocketUrl failed")); }, authFailure: function () { - connect.getLog().error("getWebSocketUrl Auth Failure"); + connect.getLog().error("getWebSocketUrl Auth Failure").sendInternalLogToServer(); reject(Error("Authentication failed while getting getWebSocketUrl")); onAuthFail(); }, accessDenied: function () { - connect.getLog().error("getWebSocketUrl Access Denied Failure"); + connect.getLog().error("getWebSocketUrl Access Denied Failure").sendInternalLogToServer(); reject(Error("Access Denied Failure while getting getWebSocketUrl")); onAccessDenied(); } @@ -656,10 +693,12 @@ }); this.client.call(connect.ClientMethods.SEND_CLIENT_LOGS, { logEvents: logEvents }, { success: function (data) { - connect.getLog().info("SendLogs request succeeded."); + connect.getLog().info("SendLogs request succeeded.").sendInternalLogToServer(); }, failure: function (err, data) { - connect.getLog().error("SendLogs request failed.").withObject(data).withException(err); + connect.getLog().error("SendLogs request failed.") + .withObject(data).withException(err) + .sendInternalLogToServer(); }, authFailure: connect.hitch(self, self.handleAuthFail) }); @@ -683,7 +722,8 @@ // refresh token 30 minutes before expiration if (expirationDate.getTime() < (currentTimeStamp + thirtyMins)) { - connect.getLog().info("Auth token expires at " + expirationDate + " Start refreshing token with retry."); + connect.getLog().info("Auth token expires at " + expirationDate + " Start refreshing token with retry.") + .sendInternalLogToServer(); connect.backoff(connect.hitch(self, self.authorize), REFRESH_AUTH_TOKEN_INTERVAL_MS, REFRESH_AUTH_TOKEN_MAX_TRY); } }; @@ -693,13 +733,16 @@ var self = this; connect.core.authorize(this.initData.authorizeEndpoint).then(function (response) { var expiration = new Date(response.expiration); - connect.getLog().info("Authorization succeeded and the token expires at %s", expiration); + connect.getLog().info("Authorization succeeded and the token expires at %s", expiration) + .sendInternalLogToServer(); self.initData.authToken = response.accessToken; self.initData.authTokenExpiration = expiration; connect.core.initClient(self.initData); + connect.core.initAgentAppClient(self.initData); callbacks.success(); }).catch(function (response) { - connect.getLog().error("Authorization failed with code %s", response.status); + connect.getLog().error("Authorization failed with code %s", response.status) + .sendInternalLogToServer(); if (response.status === 401) { self.handleAuthFail(); } else { diff --git a/test/unit/agent-app.spec.js b/test/unit/agent-app.spec.js new file mode 100644 index 00000000..91658dd9 --- /dev/null +++ b/test/unit/agent-app.spec.js @@ -0,0 +1,155 @@ +require("../unit/test-setup.js"); + +describe('agent-app', function () { + var sandbox = sinon.createSandbox(); + jsdom({ url: "http://localhost" }); + + var endpoint = 'https://www.amazon.com/ccp-v2'; + var domCon; + var bus; + var conduit; + + before(function () { + bus = new connect.EventBus(); + conduit = new connect.IFrameConduit(endpoint, window, document.createElement('iframe')); + conduit.upstreamBus = bus; + conduit.downstreamBus = bus; + }); + + beforeEach(function () { + if (!domCon) { + domCon = document.createElement('div'); + domCon.setAttribute('id', 'agent-app-dom'); + document.body.appendChild(domCon); + } + sandbox.spy(connect.agentApp.AppRegistry, 'register'); + sandbox.spy(connect.agentApp.AppRegistry, 'start'); + sandbox.spy(connect.agentApp.AppRegistry, 'stop'); + sandbox.spy(conduit, "sendUpstream"); + sandbox.spy(bus, "subscribe"); + sandbox.stub(connect.core, "getEventBus").returns(bus); + sandbox.stub(connect.core, "getUpstream").returns(conduit); + sandbox.stub(connect, "IFrameConduit").returns(conduit); + }); + + afterEach(function () { + sandbox.restore(); + }); + + describe('initCCP()', function () { + it('should be same to core.initCCP', function () { + expect(connect.agentApp.initCCP).to.equal(connect.core.initCCP); + }); + }); + + describe('initAppCommunication', function () { + it('should trigger sendUpstream', function () { + connect.agentApp.initAppCommunication('agent-app-dom', endpoint); + var event = document.createEvent('Event'); + event.initEvent('load', true, true); + domCon.dispatchEvent(event); + bus.trigger(connect.EventType.ACKNOWLEDGE); + expect(connect.core.getUpstream().sendUpstream.called).to.be.true; + }); + }); + + describe('initApp()', function () { + beforeEach(function () { + sandbox.spy(connect.core, "initCCP"); + sandbox.spy(connect.agentApp, 'initAppCommunication'); + sandbox.spy(connect, 'fetch'); + }); + + afterEach(function () { + sandbox.restore(); + }); + + it('start an app', function () { + connect.agentApp.initApp('agentApp', 'agent-app-dom', endpoint, {}); + expect(connect.agentApp.AppRegistry.register.called).to.be.true; + expect(connect.agentApp.AppRegistry.start.called).to.be.true; + }); + + it('start CCP without config', function () { + var expectedParams = { + ccpUrl: 'https://www.amazon.com/ccp-v2/', + ccpLoadTimeout: 10000, + loginPopup: true, + loginUrl: 'https://www.amazon.com/login', + softphone: { + allowFramedSoftphone: true, + disableRingtone: false, + } + }; + connect.agentApp.initApp('ccp', 'agent-app-dom', endpoint); + console.log(connect.core.initCCP.firstCall.args); + expect(connect.core.initCCP.calledWith(domCon, expectedParams)).to.be.true; + }); + + it('start CCP with config', function () { + var expectedParams = { + ccpUrl: 'https://www.amazon.com/ccp-v2/', + ccpLoadTimeout: 10000, + loginPopup: false, + loginUrl: 'https://www.amazon.com/login', + softphone: { + allowFramedSoftphone: true, + disableRingtone: false, + } + }; + connect.agentApp.initApp('ccp', 'agent-app-dom', endpoint, { ccpParams: { loginPopup: false } }); + expect(connect.core.initCCP.calledWith(domCon, expectedParams)).to.be.true; + expect(connect.core.getEventBus().subscribe.called).to.be.true; + }); + + it('adds a trailing slash to the url', function () { + connect.agentApp.initApp('customer-profiles', 'agent-app-dom', endpoint); + expect(connect.agentApp.initAppCommunication.calledWith('customer-profiles', endpoint + '/')).to.be.true; + }); + + it('leaves trailing slash on the url', function () { + connect.agentApp.initApp('customer-profiles', 'agent-app-dom', endpoint + '/'); + expect(connect.agentApp.initAppCommunication.calledWith('customer-profiles', endpoint + '/')).to.be.true; + }); + + it('signs out of ccp on destroy with correct cf url', async function () { + var ccpEndpoint = 'https://amazon.awsapps.com/connect/ccp-v2'; + connect.agentApp.initApp('ccp', 'agent-app-dom', ccpEndpoint, {}); + connect.agentApp.stopApp('ccp'); + expect(connect.fetch.calledWith('https://amazon.awsapps.com/connect/logout')).to.be.true; + }); + + it('signs out of ccp on destroy with correct nginx url', function () { + var ccpEndpoint = 'https://amazon.my.connect.aws/ccp-v2'; + connect.agentApp.initApp('ccp', 'agent-app-dom', ccpEndpoint, {}); + connect.agentApp.stopApp('ccp'); + expect(connect.fetch.calledWith('https://amazon.my.connect.aws/logout')).to.be.true; + }); + + it('signs out of ccp on destroy with longer softphone ccp url', function () { + var ccpEndpoint = 'https://amazon.my.connect.aws/ccp-v2/softphone/'; + connect.agentApp.initApp('ccp', 'agent-app-dom', ccpEndpoint, {}); + connect.agentApp.stopApp('ccp'); + expect(connect.fetch.calledWith('https://amazon.my.connect.aws/logout')).to.be.true; + }); + }); + + describe('stopApp()', function () { + it('Stop an app', function () { + connect.agentApp.initApp('agentApp', 'agent-app-dom', endpoint, {}); + connect.agentApp.stopApp('agentApp'); + expect(connect.agentApp.AppRegistry.stop.called).to.be.true; + }); + + it('Stop CCP when fetch fails', function (done) { + try { + connect.agentApp.initApp('ccp', 'agent-app-dom', endpoint, {}); + connect.agentApp.stopApp('ccp'); + expect(connect.agentApp.AppRegistry.stop.called).to.be.true; + } catch (e) { + expect(window.location.href).to.equal('endpoint/logout'); + } + done(); + }); + }); +}); diff --git a/test/unit/app-registry.spec.js b/test/unit/app-registry.spec.js new file mode 100644 index 00000000..aba8ff37 --- /dev/null +++ b/test/unit/app-registry.spec.js @@ -0,0 +1,53 @@ +require("./test-setup.js"); + +describe('app-registry', function () { + var sandbox = sinon.createSandbox(); + jsdom({ url: "http://localhost" }); + + after(function () { + sandbox.restore(); + }); + + describe('register', function () { + it('can start a app with dom', function () { + var domContainer = document.createElement('agentApp'); + domContainer.setAttribute('id', 'agentApp'); + document.body.appendChild(domContainer); + sandbox.spy(domContainer, 'appendChild'); + sandbox.spy(document.body, 'appendChild'); + var initFunc = sandbox.spy(); + var creator = function () { return { init: initFunc } }; + + connect.agentApp.AppRegistry.register('agentApp', { endpoint: 'test' }, domContainer); + connect.agentApp.AppRegistry.start('fake', creator); + expect(initFunc.called).to.be.false; + expect(document.body.appendChild.called).to.be.false; + connect.agentApp.AppRegistry.start('agentApp', creator); + expect(initFunc.called).to.be.true; + expect(document.body.appendChild.called).to.be.false; + expect(domContainer.appendChild.called).to.be.true; + }); + }); + + describe('stop', function () { + it('can stop a given app', function () { + var initFunc = sandbox.spy(); + var destoryFunc = sandbox.spy(); + var domContainer = document.getElementById('agentApp'); + sandbox.spy(domContainer, 'removeChild'); + var creator = function () { return { init: initFunc, destroy: destoryFunc } }; + + connect.agentApp.AppRegistry.register('agentApp', { endpoint: 'test' }, domContainer); + connect.agentApp.AppRegistry.start('agentApp', creator); + expect(initFunc.called).to.be.true; + + connect.agentApp.AppRegistry.stop('test'); + expect(destoryFunc.called).to.be.false; + expect(domContainer.removeChild.called).to.be.false; + + connect.agentApp.AppRegistry.stop('agentApp'); + expect(destoryFunc.called).to.be.true; + expect(domContainer.removeChild.called).to.be.true; + }); + }); +}); diff --git a/test/unit/connections.spec.js b/test/unit/connections.spec.js index 749c19bd..055de12e 100644 --- a/test/unit/connections.spec.js +++ b/test/unit/connections.spec.js @@ -66,6 +66,156 @@ describe('Connections API', function () { const monitorInfo = chatConnection.getMonitorInfo(); assert.deepEqual(monitorInfo, chatMonitorInfo); }); + }); + + describe('#Voice Connection API', function () { + + const connectionId = "connectionId"; + const contactId = "contactId"; + const instanceId = "instanceId"; + const AWSAccountId = "AWSAccountId"; + const initMediaController = sinon.spy(); + + before(function () { + connect.core.getClient = sinon.stub(); + connect.core.getAgentDataProvider = sinon.stub().returns({ + getContactData: () => { return {connections:[{}]} }, + _initMediaController: initMediaController, + getConnectionData: () => { + return { + state: {}, + getMediaController: () => { } + } + }, + getInstanceId: () => {return instanceId}, + getAWSAccountId: () => {return AWSAccountId}, + }); + }); + + after(function () { + initMediaController.resetHistory(); + connect.core.getAgentDataProvider.resetBehavior(); + }); + + it('Should create new Voice connection Object given the Voice Contact and Connection Id with Speaker Authenticator ', function () { + const voiceConnection = new connect.VoiceConnection(contactId, connectionId); + assert.equal(voiceConnection.connectionId, connectionId); + assert.equal(voiceConnection.contactId, contactId); + assert.equal(voiceConnection.getMediaType(), connect.MediaType.SOFTPHONE); + assert.equal(typeof(voiceConnection.getVoiceIdSpeakerId), 'function'); + assert.equal(typeof(voiceConnection.getVoiceIdSpeakerStatus), 'function') + }); + + describe('getVoiceIdSpeakerId', function() { + it('Should return SpeakerId promise.', function () { + const voiceConnection = new connect.VoiceConnection(contactId, connectionId); + var speakerId = voiceConnection.getVoiceIdSpeakerId(); + assert.equal(Promise.resolve(speakerId), speakerId); + }); + }); + + describe('getVoiceIdSpeakerStatus', function() { + it('Should return getVoiceIdSpeakerStatus promise.', function () { + const voiceConnection = new connect.VoiceConnection(contactId, connectionId); + var getVoiceIdSpeakerStatus = voiceConnection.getVoiceIdSpeakerStatus(); + assert.equal(Promise.resolve(getVoiceIdSpeakerStatus), getVoiceIdSpeakerStatus); + }); + }); + + describe('optOutVoiceIdSpeaker', function() { + it('Should return optOutVoiceIdSpeaker promise.', function () { + const voiceConnection = new connect.VoiceConnection(contactId, connectionId); + var optOutVoiceIdSpeaker = voiceConnection.optOutVoiceIdSpeaker(); + assert.equal(Promise.resolve(optOutVoiceIdSpeaker), optOutVoiceIdSpeaker); + }); + }); + + describe('evaluateSpeakerWithVoiceId', function() { + it('Should return evaluateSpeakerWithVoiceId promise.', function () { + const voiceConnection = new connect.VoiceConnection(contactId, connectionId); + var evaluateSpeakerWithVoiceId = voiceConnection.evaluateSpeakerWithVoiceId(); + assert.equal(Promise.resolve(evaluateSpeakerWithVoiceId), evaluateSpeakerWithVoiceId); + }); + }); + + describe('enrollSpeakerInVoiceId', function() { + it('Should return enrollSpeakerInVoiceId promise.', function () { + const voiceConnection = new connect.VoiceConnection(contactId, connectionId); + var enrollSpeakerInVoiceId = voiceConnection.enrollSpeakerInVoiceId(); + assert.equal(Promise.resolve(enrollSpeakerInVoiceId), enrollSpeakerInVoiceId); + }); + }); + + describe('updateVoiceIdSpeakerId', function() { + it('Should return updateVoiceIdSpeakerId promise.', function () { + const voiceConnection = new connect.VoiceConnection(contactId, connectionId); + var updateVoiceIdSpeakerId = voiceConnection.updateVoiceIdSpeakerId(); + assert.equal(Promise.resolve(updateVoiceIdSpeakerId), updateVoiceIdSpeakerId); + }); + }); + }); + + describe('#Task Connection API', function () { + + const connectionId = "connectionId"; + const contactId = "contactId"; + const initialContactId = "initialContactId"; + const initMediaController = sinon.spy(); + + var taskMediaInfo = { + contactId, + initialContactId + }; + + const mediaFactoryGet = () => Promise.resolve(); + + connect.core.mediaFactory = {}; + + before(function () { + + connect.core.getAgentDataProvider = sinon.stub().returns({ + getContactData: () => { return { + initialContactId: taskMediaInfo.initialContactId + } }, + _initMediaController: initMediaController, + getConnectionData: () => { + return { + state: {}, + taskMediaInfo, + getMediaController: () => { } + } + }, + }); + + connect.core.mediaFactory.get = sinon.stub(mediaFactoryGet); + connect.TaskConnection.prototype._initMediaController = initMediaController; + }); + + afterEach(function () { + initMediaController.resetHistory(); + }); + + after(function() { + connect.core.getAgentDataProvider.resetBehavior(); + }); + + it('Should create new Task connection Object given the task Contact and Connection Id ', function () { + const taskConnection = new connect.TaskConnection(contactId, connectionId); + assert.equal(taskConnection.connectionId, connectionId); + assert.equal(taskConnection.contactId, contactId); + assert.equal(taskConnection.getMediaType(), connect.MediaType.TASK); + }); + + it('Should call InitMediaController method on new TaskConnection creation', function () { + const taskConnection = new connect.TaskConnection(contactId, connectionId); + expect(initMediaController.calledOnce).to.be.true; + }); + + it('Should return valid taskMedia Info on getMediaInfo method ', function () { + const taskConnection = new connect.TaskConnection(contactId, connectionId); + const mediaInfo = taskConnection.getMediaInfo(); + assert.equal(mediaInfo.contactId, taskMediaInfo.contactId); + }); }); }); diff --git a/test/unit/core.spec.js b/test/unit/core.spec.js index 4a922c26..c980d962 100644 --- a/test/unit/core.spec.js +++ b/test/unit/core.spec.js @@ -20,16 +20,20 @@ describe('Core', function () { ringtoneUrl: this.defaultRingtoneUrl } }; - this.ringtoneEngineParams = { - ringtone: { - voice: { ringtoneUrl: this.defaultRingtoneUrl }, - queue_callback: { ringtoneUrl: this.defaultRingtoneUrl }, - chat: { ringtoneUrl: this.defaultRingtoneUrl } - } + this.defaultRingtone = { + voice: { ringtoneUrl: this.defaultRingtoneUrl }, + queue_callback: { ringtoneUrl: this.defaultRingtoneUrl } + }; + this.extraRingtone = { + voice: { ringtoneUrl: this.defaultRingtoneUrl }, + queue_callback: { ringtoneUrl: this.defaultRingtoneUrl }, + chat: { ringtoneUrl: this.defaultRingtoneUrl }, + task: { ringtoneUrl: this.defaultRingtoneUrl } }; }); describe('#connect.core.initSharedWorker()', function () { + jsdom({ url: "http://localhost" }); beforeEach(function () { sandbox.stub(connect.core, "checkNotInitialized").returns(true); @@ -59,18 +63,67 @@ describe('Core', function () { connect.core.initSharedWorker(this.params); expect(connect.core.checkNotInitialized.called); expect(SharedWorker.calledWith(this.params.sharedWorkerUrl, "ConnectSharedWorker")); + expect(connect.core.region).not.to.be.a("null"); + }); + }); + + describe('legacy endpoint', function () { + jsdom({ url: "https://abc.awsapps.com/connect/ccp-v2" }); + + beforeEach(function () { + sandbox.stub(connect.core, "checkNotInitialized").returns(true); + global.SharedWorker = sandbox.stub().returns({ + port: { + start: sandbox.spy(), + addEventListener: sandbox.spy() + }, + }) + + global.connect.agent.initialized = true; + sandbox.stub(connect.core, 'getNotificationManager').returns({ + requestPermission: sandbox.spy() + }); + + sandbox.stub(connect.Conduit.prototype, 'sendUpstream').returns(null); + }); + + afterEach(function () { + sandbox.restore(); }); + it("uses the legacy endpoint for a legacy url", function () { - const href = "https://abc.awsapps.com/connect/ccp-v2"; - window.location.href = href; connect.core.initSharedWorker(this.params); assert.isTrue(connect.Conduit.prototype.sendUpstream.called); assert.isTrue(connect.Conduit.prototype.sendUpstream.getCalls()[0].lastArg.authorizeEndpoint === "/connect/auth/authorize"); }); + }); + + describe('legacy endpoint', function () { + jsdom({ url: "https://abc.my.connect.aws/ccp-v2" }); + + beforeEach(function () { + sandbox.stub(connect.core, "checkNotInitialized").returns(true); + global.SharedWorker = sandbox.stub().returns({ + port: { + start: sandbox.spy(), + addEventListener: sandbox.spy() + }, + }) + + global.connect.agent.initialized = true; + sandbox.stub(connect.core, 'getNotificationManager').returns({ + requestPermission: sandbox.spy() + }); + + sandbox.stub(connect.Conduit.prototype, 'sendUpstream').returns(null); + }); + + afterEach(function () { + sandbox.restore(); + }); + it("uses new endpoint for new url", function () { - const href = "https://abc.my.connect.aws/ccp-v2"; this.params.baseUrl = "https://abc.my.connect.aws"; - window.location.href = href; connect.core.initSharedWorker(this.params); assert.isTrue(connect.Conduit.prototype.sendUpstream.called); assert.isTrue(connect.Conduit.prototype.sendUpstream.getCalls()[0].lastArg.authorizeEndpoint === "/auth/authorize"); @@ -79,6 +132,8 @@ describe('Core', function () { }); describe('#initSoftphoneManager()', function () { + jsdom({ url: "http://localhost" }); + before(function () { sandbox.stub(connect.core, "checkNotInitialized").returns(false); sandbox.stub(connect, "SoftphoneManager").returns({}) @@ -91,16 +146,16 @@ describe('Core', function () { connect.core.getAgentDataProvider = sandbox.stub().returns({ getAgentData: () => { - return { - configuration: { - routingProfile: { - channelConcurrencyMap: { - CHAT: 0, - VOICE: 1 + return { + configuration: { + routingProfile: { + channelConcurrencyMap: { + CHAT: 0, + VOICE: 1 + } + } } - } - } - }; + }; } }); }); @@ -119,45 +174,104 @@ describe('Core', function () { }); describe('#connect.core.initRingtoneEngines()', function () { - before(function () { - sandbox.stub(connect, "ifMaster"); - sandbox.stub(connect, "VoiceRingtoneEngine"); - sandbox.stub(connect, "QueueCallbackRingtoneEngine"); - sandbox.stub(connect, "ChatRingtoneEngine"); - connect.core.initRingtoneEngines(this.ringtoneEngineParams); - }); + jsdom({ url: "http://localhost" }); + + describe('with default settings', function () { + beforeEach(function () { + sandbox.stub(connect, "ifMaster"); + sandbox.stub(connect, "VoiceRingtoneEngine"); + sandbox.stub(connect, "QueueCallbackRingtoneEngine"); + sandbox.stub(connect, "ChatRingtoneEngine"); + sandbox.stub(connect, "TaskRingtoneEngine"); + connect.core.initRingtoneEngines({ ringtone: this.defaultRingtone }); + }); - after(function () { - sandbox.restore(); - }); + afterEach(function () { + sandbox.restore(); + }); - it("Ringtone init with VoiceRingtoneEngine", function () { - connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); - connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); - connect.ifMaster.callArg(1); - assert.isTrue(connect.VoiceRingtoneEngine.calledWithNew(this.ringtoneEngineParams.voice)); - }); + it("Ringtone init with VoiceRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isTrue(connect.VoiceRingtoneEngine.calledWithNew(this.defaultRingtone.voice)); + }); - it("Ringtone init with QueueCallbackRingtoneEngine", function () { - connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); - connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); - connect.ifMaster.callArg(1); - assert.isTrue(connect.QueueCallbackRingtoneEngine.calledWithNew(this.ringtoneEngineParams.queue_callback)); + it("Ringtone init with QueueCallbackRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isTrue(connect.QueueCallbackRingtoneEngine.calledWithNew(this.defaultRingtone.queue_callback)); + }); + + it("Ringtone no init with ChatRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isFalse(connect.ChatRingtoneEngine.calledWithNew()); + }); + + it("Ringtone no init with TaskRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isFalse(connect.TaskRingtoneEngine.calledWithNew()); + }); }); - it("Ringtone init with ChatRingtoneEngine", function () { - connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); - connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); - connect.ifMaster.callArg(1); - assert.isTrue(connect.ChatRingtoneEngine.calledWithNew(this.ringtoneEngineParams.chat)); + describe('with optional chat and task ringtone params', function () { + before(function () { + sandbox.stub(connect, "ifMaster"); + sandbox.stub(connect, "VoiceRingtoneEngine"); + sandbox.stub(connect, "QueueCallbackRingtoneEngine"); + sandbox.stub(connect, "ChatRingtoneEngine"); + sandbox.stub(connect, "TaskRingtoneEngine"); + connect.core.initRingtoneEngines({ ringtone: this.extraRingtone }); + }); + + after(function () { + sandbox.restore(); + }); + + it("Ringtone init with VoiceRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isTrue(connect.VoiceRingtoneEngine.calledWithNew(this.extraRingtone.voice)); + }); + + it("Ringtone init with QueueCallbackRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isTrue(connect.QueueCallbackRingtoneEngine.calledWithNew(this.extraRingtone.queue_callback)); + }); + + it("Ringtone init with ChatRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isTrue(connect.ChatRingtoneEngine.calledWithNew(this.extraRingtone.chat)); + }); + + + it("Ringtone init with TaskRingtoneEngine", function () { + connect.core.getEventBus().trigger(connect.AgentEvents.INIT, new connect.Agent()); + connect.core.getEventBus().trigger(connect.AgentEvents.REFRESH, new connect.Agent()); + connect.ifMaster.callArg(1); + assert.isTrue(connect.TaskRingtoneEngine.calledWithNew(this.extraRingtone.task)); + }); }); }); describe('#connect.core.initCCP()', function () { + jsdom({ url: "http://localhost" }); + before(function () { this.containerDiv = { appendChild: sandbox.spy() }; this.params = connect.merge({}, this.params, { ccpUrl: "url.com", + loginUrl: "loginUrl.com", softphone: { ringtoneUrl: "customVoiceRingtone.amazon.com" }, @@ -173,6 +287,7 @@ describe('Core', function () { sandbox.stub(connect, "VoiceRingtoneEngine"); sandbox.stub(connect, "QueueCallbackRingtoneEngine"); sandbox.stub(connect, "ChatRingtoneEngine"); + sandbox.spy(document, "createElement"); connect.core.initCCP(this.containerDiv, this.params); sandbox.spy(connect.core.getUpstream(), "sendUpstream"); }); @@ -220,7 +335,7 @@ describe('Core', function () { }); it("sets up ringtone engines on CONFIGURE with initCCP params", function () { - connect.core.initRingtoneEngines(this.ringtoneEngineParams); + connect.core.initRingtoneEngines({ ringtone: this.extraRingtone }); connect.core.getEventBus().trigger(connect.EventType.CONFIGURE, { softphone: this.params.softphone, chat: this.params.chat @@ -251,7 +366,7 @@ describe('Core', function () { function setup() { sandbox.stub(connect, "isFramed").returns(isFramed); - sandbox.stub(connect, "fetch").returns(Promise.resolve({whitelistedOrigins: whitelistedOrigins})); + sandbox.stub(connect, "fetch").returns(Promise.resolve({ whitelistedOrigins: whitelistedOrigins })); } it('resolves if not iframed', async () => { @@ -263,37 +378,41 @@ describe('Core', function () { it('calls /whitelisted-origins if iframed', async () => { isFramed = true; setup(); - await connect.core.verifyDomainAccess('token', 'endpoint').catch(() => {}).finally(() => { + await connect.core.verifyDomainAccess('token', 'endpoint').catch(() => { }).finally(() => { assert.isTrue(connect.fetch.calledWithMatch('endpoint', { headers: { - 'X-Amz-Bearer': 'token' + 'X-Amz-Bearer': 'token' } })); }); }); - it('matches url correctly', async () => { - isFramed = true; - whitelistedOrigins = ['https://www.abc.com']; - setup(); - const testDomains = { - 'https://www.abc.com': true, - 'http://www.abc.com': false, - 'http://www.xyz.com': false, - 'https://www.abc.de': false, - 'https://xyz.abc.com': false, - 'https://www.abc.com/sub?x=1#123': true - }; - const urls = Object.keys(testDomains); - for (let i = 0; i < urls.length; i++) { - global.window.document.referrer = urls[i]; - await connect.core.verifyDomainAccess('token', 'endpoint').then(() => { - expect(testDomains[urls[i]]).to.be.true; - }).catch(() => { - expect(testDomains[urls[i]]).to.be.false; + var testDomains = { + 'https://www.abc.com': true, + 'http://www.abc.com': false, + 'http://www.xyz.com': false, + 'https://www.abc.de': false, + 'https://xyz.abc.com': false, + 'https://www.abc.com/sub?x=1#123': true + }; + var referrers = Object.keys(testDomains); + for (var i = 0; i < referrers.length; i++) { + describe('matches url ' + referrers[i], function () { + var referrer = referrers[i]; + jsdom({ url: "http://localhost", referrer: referrer }); + + it('matches correctly', async function () { + isFramed = true; + whitelistedOrigins = ['https://www.abc.com']; + setup(); + await connect.core.verifyDomainAccess('token', 'endpoint').then(function () { + expect(testDomains[referrer]).to.be.true; + }).catch(function (error) { + expect(error).to.equal(undefined); + expect(testDomains[referrer]).to.be.false; + }); }); - } - }); + }); + } }); - }); diff --git a/test/unit/ringtone.spec.js b/test/unit/ringtone.spec.js index 57c1023d..e917d0c2 100644 --- a/test/unit/ringtone.spec.js +++ b/test/unit/ringtone.spec.js @@ -16,6 +16,12 @@ describe('RingtoneEngine', function () { contact = new connect.Contact(contactId); }); + function contactStubHelper(contactStubMethodToOutput) { + sandbox.stub(contact, "getType").returns(contactStubMethodToOutput.contactType); + sandbox.stub(contact, "isSoftphoneCall").returns(contactStubMethodToOutput.isSoftphoneCall); + sandbox.stub(contact, "isInbound").returns(contactStubMethodToOutput.isInbound); + } + after(function () { sandbox.restore(); }); @@ -121,4 +127,51 @@ describe('RingtoneEngine', function () { }); }); + describe('#connect.TaskRingtoneEngine', function () { + beforeEach(function () { + sandbox.stub(connect.core, "getEventBus").returns(bus); + + this.ringtoneEngine = new connect.TaskRingtoneEngine(ringtoneObj); + this.ringtoneSetup = sandbox.stub(this.ringtoneEngine, "_ringtoneSetup"); + + assert.doesNotThrow(this.ringtoneEngine._driveRingtone, Error, "Not implemented."); + }); + + afterEach(function () { + sandbox.restore(); + }); + + it('validate the TaskRingtoneEngine implemements the _driveRingtone method and calls the _ringtoneSetup for TASK contacts', function () { + // setup + contactStubHelper({ + contactType: lily.ContactType.TASK, + isSoftphoneCall: false, + isInbound: true + }); + + // enact + bus.trigger(connect.ContactEvents.INIT, contact); + bus.trigger(connect.core.getContactEventName(connect.ContactEvents.CONNECTING, contactId), contact); + + // verify + assert.isTrue(this.ringtoneSetup.withArgs(contact).calledOnce); + }); + + it('validate the TaskRingtoneEngine should not call _ringtoneSetup for non TASK', function () { + // setup + contactStubHelper({ + contactType: lily.ContactType.QUEUE_CALLBACK, + isSoftphoneCall: false, + isInbound: true + }); + + // enact + bus.trigger(connect.ContactEvents.INIT, contact); + bus.trigger(connect.core.getContactEventName(connect.ContactEvents.CONNECTING, contactId), contact); + + // verify + assert.isTrue(this.ringtoneSetup.notCalled); + }); + }); + }); diff --git a/test/unit/streams.spec.js b/test/unit/streams.spec.js index 5be7cefb..222f8e2a 100644 --- a/test/unit/streams.spec.js +++ b/test/unit/streams.spec.js @@ -1,6 +1,7 @@ require("../unit/test-setup.js"); describe('Streams', function () { + jsdom({ url: "http://localhost" }); describe('WindowStream', function () { it('Validate send and onMessage methods are implemented', function () { @@ -58,4 +59,4 @@ describe('Streams', function () { it('Test cases for Iframe condult'); }); -}); \ No newline at end of file +}); diff --git a/test/unit/test-setup.js b/test/unit/test-setup.js index 14232a9f..b6657027 100644 --- a/test/unit/test-setup.js +++ b/test/unit/test-setup.js @@ -1,26 +1,15 @@ -var chai = require("chai"), - sinon = require("sinon"); - -global.assert = chai.assert, - global.expect = chai.expect, - global.should = chai.should, - global.sinon = sinon +var chai = require("chai"); +var sinon = require("sinon"); +var jsdom = require("mocha-jsdom"); + +global.assert = chai.assert; +global.expect = chai.expect; +global.should = chai.should; +global.sinon = sinon; global.navigator = { userAgent: 'browser' -} - -global.document = { - getElementById: sinon.stub().returns({}), - createElement: sinon.stub().returns({}), -} - -global.window = { - addEventListener: sinon.spy(), - document: global.document, - location: { - href: "example" - } }; +global.jsdom = jsdom; global.parent = global.window; @@ -28,7 +17,6 @@ require("../../release/connect-streams.js"); global.connect.RTCSession = function () {}; - // Polyfill for Promise.finally Promise.prototype.finally = function(onFinally) { return this.then(