commit 224edfd2bc8fa09f60f93298566d002992bd94f6 Author: muppeth Date: Tue Dec 1 06:40:41 2020 +0100 initial commit with darkbeet diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..be21f0b --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,1599 @@ +# Changelog + +## 8.0.0 (Unreleased) + +- #1083: Add support for XEP-0393 Message Styling +- #2275: Allow punctuation to immediately precede a mention +- Bugfix: `null` inserted by emoji picker and can't switch between skintones +- New configuration setting: [show_tab_notifications](https://conversejs.org/docs/html/configuration.html#show-tab-notifications) + +### Breaking Changes + +The [afterMessageBodyTransformed](https://conversejs.org/docs/html/api/-_converse.html#event:afterMessageBodyTransformed) and [beforeMessageBodyTransformed](https://conversejs.org/docs/html/api/-_converse.html#event:beforeMessageBodyTransformed) events now has a different signatures. + +## 7.0.2 (2020-11-23) + +- Updated translations: de, nb, gl, tr +- Still more necessary files not included in the 7.0.1 NPM package, causing `Module not found` errors. +- #2337: Newly opened headline chat isn't hidden by default + +## 7.0.1 (2020-11-19) + +- Updated translations: de, es, fi, fr, gl, hu, nb_NO, oc, pl, pt, pt_BR, ru, tr, uk, zh +- #2328: Honor `use_system_emojis` in emoji-picker +- Not all template/*.js files were included in the 7.0.0 NPM package, causing: + `Module not found: Error: Can't resolve 'templates/*.js'` + +## 7.0.0 (2020-11-18) + +*Note for plugin authors:* +configuration settings should now be accessed via `_converse.api.settings.get` and not directly on the `_converse` object. +Soon we'll deprecate the latter, so prepare now. + +- #515 Add support for XEP-0050 Ad-Hoc commands +- #1083 Add support for XEP-0393 Message Styling +- #2231: add sort_by_query and remove sort_by_length +- #1313: Stylistic improvements to the send button +- #1481: MUC OMEMO: Error No record for device +- #1490: Busy-loop when fetching registration form fails +- #1535: Add option to destroy a MUC +- #1715: Update chat state notification after receiving a message correction. +- #1793: Send button doesn't appear in Firefox in 1:1 chats +- #1820: Set focus on jid field after controlbox is loaded +- #1822: Don't log error if user has no bookmarks +- #1823: New config options [muc_roomid_policy](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy) + and [muc_roomid_policy_hint](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy-hint) +- #1826: A user can now add himself as a contact +- #1839: Headline messages are shown in controlbox +- #1924: Configuring an ejabberd room fails +- #1896: Don't send receipts for messages fetched from the archive +- #1937: Editing a message removes the mentions highlight +- #1963: Mentions are visually incorrect when used in message replies +- #1999: Demarcate first unread message +- #2002: fix rendering of `muc_roomid_policy_hint` +- #2006: fix rendering of emojis in case `use_system_emojis == false` +- #2028: Implement XEP-0333 `displayed` chat marker +- #2101: Improve contrast of text in control box +- #2187: Avoid merging initial settings with themselves every time settings are extended. +- #2199: Fix BOSH session restore. +- #2201: added html to converse.env +- #2213: added CustomElement to converse.env +- #2220: fix rendering of emojis in case `use_system_emojis == false` (again). +- #2092: fixes room list update loop when having the `locked_muc_domain` truthy or `'hidden'` +- #2285: Rename config option `muc_hats_from_vcard` to [muc_hats](https://conversejs.org/docs/html/configuration.html#muc-hats). Now accepts a list instead of a boolean and allows for more flexible choices regarding user badges. +- #2300: Fix message reorder issue after message correction. +- #2304: Custom emojis (stickers) images not shown +- #2307: BootstrapModal is not accessible to plugins +- #2308: Allow getHats method to be overriden in the `overrides` object in plugins. +- #2321: When Converse runs inside a browser extension, enable browser sync and local storage for persistent storage +- #1250: Change favicon color when unread messages +- Updated translations: de, es, fi, fr, gl, hu, nb_NO, oc, pl, pt, pt_BR, ru, tr, uk, zh +- The `trusted` configuration setting has been removed in favor of two new settings: + [allow_user_trust_override](https://conversejs.org/docs/html/configuration.html#allow-user-trust-override) + [clear_cache_on_logout](https://conversejs.org/docs/html/configuration.html#clear-cache-on-logout) +- The `persistent_store` setting can now also be set to `sessionStorage` +- The `api.archive.query` method no longer accepts an RSM instance as argument. +- The plugin `converse-uniview` has been removed and its functionality merged into `converse-chatboxviews` +- Removed the mockups from the project. Recommended to use tests instead. +- The API method `api.settings.update` has been deprecated in favor of `api.settings.extend`. +- The API methods under the `api.user.status` namespace are now asynchronous and need to be `await`ed. +- Filter roster contacts via all available information (JID, nickname and VCard full name). +- Allow ignoring of bootstrap modules at build using environment variable. For xample: `export BOOTSTRAP_IGNORE_MODULES="Modal,Dropdown" && make dist` +- Bugfix. Handle stanza that clears the MUC subject +- Replace Backbone with [Skeletor](https://github.com/skeletorjs/skeletor) +- Start using [lit-html](https://lit-html.polymer-project.org/) instead of lodash for templating. +- [muc_fetch_members](https://conversejs.org/docs/html/configuration.html#muc-fetch-members) now also accepts an array of affiliations to fetch. +- Remove the configuration setting `muc_show_join_leave_status`. The optional status message is no longer shown at all. +- Support for XEP-0156 is now enabled by default (which means that + [discover_connection_methods](https://conversejs.org/docs/html/configuration.html#discover-connection-methods) now has a default value of `true`). +- [show_send_button](https://conversejs.org/docs/html/configuration.html#show-send-button) now has a default value of `true`. +- The [api.confirm](https://conversejs.org/docs/html/api/-_converse.api.html#.confirm) method now accepts a list of fields and returns the filled in list upon confirmation. +- New config option [allow_adhoc_commands](https://conversejs.org/docs/html/configuration.html#allow-adhoc-commands) +- New config option [modtools_disable_assign](https://conversejs.org/docs/html/configuration.html#modtools-disable-assign) +- New config option [modtools_disable_query](https://conversejs.org/docs/html/configuration.html#modtools-disable-query) +- New config option [muc_hats_from_vcard](https://conversejs.org/docs/html/configuration.html#muc-hats-from-vcard). +- New config option [muc_send_probes](https://conversejs.org/docs/html/configuration.html#muc-send-probes). +- New config option [notify_nicknames_without_references](https://conversejs.org/docs/html/configuration.html#notify-nicknames-without-references). +- New config option [show_message_avatar](https://conversejs.org/docs/html/configuration.html#show-message-avatar). +- New public API [converse.insertInto](https://conversejs.org/docs/html/api/converse.html#.insertInto) + +## 6.0.0 (2020-01-09) + +- [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks) is not set to `true` by default. +- Refactor some presence and status handling code from `converse-core` into `@converse/headless/converse-status`. +- It's now possible to navigate the emoji-picker via the keyboard arrow keys. + +- Add support for [notifications about affiliation change for users not in a room](https://xmpp.org/extensions/xep-0045.html#example-196) +- Add support for [XEP-0424 Message Retraction](http://xmpps.org/extensions/xep-0424.html) +- Add support for [XEP-0425 Message Moderation](http://xmpps.org/extensions/xep-0425.html) + +- New API [\_converse.api.headlines](https://conversejs.org/docs/html/api/-_converse.api.headlines.html#.get) +- New config option [allow_message_retraction](https://conversejs.org/docs/html/configuration.html#allow-message-retraction) +- New config option [muc-show-logs-before-join](https://conversejs.org/docs/html/configuration.html#muc-show-logs-before-join) +- New config option [muc_mention_autocomplete_filter](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-filter) +- New config option [muc_mention_autocomplete_show_avatar](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-show-avatar) +- New config option [persistent_store](https://conversejs.org/docs/html/configuration.html#persistent-store) + +- Initial support for sending custom emojis. Currently only between Converse + instances. Still working out a wire protocol for compatibility with other clients. + To add custom emojis, edit the `emojis.json` file. + +- #129: Add support for [XEP-0156: Disovering Alternative XMPP Connection Methods](https://xmpp.org/extensions/xep-0156.html). Only XML is supported for now. +- #1105: Support for storing persistent data in IndexedDB +- #1253: Show contacts with unread messages at the top of the roster +- #1322 Display occupants’ avatars in the occupants list +- #1640: Add the ability to resize the occupants sidebar in MUCs +- #1666: Allow scrolling of the OMEMO fingerprints list +- #1691: Fix `collection.chatbox is undefined` errors +- #1767: `credentials_url` is not called when logging out and then in again +- #1764: Incorrect URI encoding in "mention" references +- #1772: `_converse.api.contact.add(jid, nick)` fails, says not a function +- #1791: `auto_focus` set to `false` is ignored when switching back to a MUC +- #1792: Fix: modals don't have scrollbars +- #1796: Don't show "back" arrow navigation (on mobile) in the chat header when in `singleton` mode +- #1821: Errors caused by malformed URLs are now handled +- #1819: Click on a desktop notification now opens corresponding chat. +- #1836: MUC invites appear to come from the MUC name + +### Breaking changes + +- The ``debug`` configuration option has been replaced with [loglevel](https://conversejs.org/docs/html/configuration.html#loglevel). + +- In contrast to sessionStorage and localStorage, IndexedDB is an asynchronous database. + A lot of code that relied on database access to be synchronous had to be + updated to work with asynchronous access via promises. + +- In order to add support for XEP-0156, the XMPP connection needs to be created + only once we know the JID of the user that's logging in. This means that the + [connectionInitialized](https://conversejs.org/docs/html/api/-_converse.html#event:connectionInitialized) + event now fires much later than before. Plugins that rely on `connectionInitialized` + being triggered before the user's JID has been provided will need to be updated. + +- The following API methods now return promises: + * `_converse.api.chats.get` + * `_converse.api.chats.create` + * `_converse.api.rooms.get` + * `_converse.api.rooms.create` + * `_converse.api.roomviews.close` + +- Changes the events: + * The `chatBoxInitialized` event now triggers when a `_converse.ChatBox` (not the view) is opened. + * Renamed the old `chatBoxInitialized` to `chatBoxViewInitialized` and trigger only for `ChatBoxView` instances. + * Renamed `chatRoomOpened` event to `chatRoomViewInitialized` + * The order of certain events have now changed: `statusInitialized` is now triggered after `initialized` and `connected` and `reconnected`. + +- `_converse.api.chats.get()` now only returns one-on-one chats, not the control box or headline notifications. +- The `show_only_online_users` setting has been removed. +- `_converse.api.alert.show` is now `_converse.api.show` and instead of taking + an integer for the `type`, "info", "warn" or "error" should be passed in. +- The `converse-headline` plugin has been split up into `converse-headlines` and `converse-headlines-view`. + +## 5.0.5 (2019-11-20) + +- Prevent editing of sent file uploads. +- #1089: When filtering the roster for `online` users, show all non-offline users. +- #1733: New message notifications for a minimized chat stack on top of each other +- #1757: Chats are hidden behind the controlbox on mobile +- #1760: Private messages no longer received after websocket reconnect + +## 5.0.4 (2019-10-08) + +- New config option [allow_message_corrections](https://conversejs.org/docs/html/configuration.html#allow-message-corrections) + which, if set to `last`, limits editing of sent messages to the last message sent. +- Bugfix: Don't treat every duplicate message ID as a message correction; since some clients don't use globally unique ID's this causes false positives. +- Bugfix: process stanzas from mam one-by-one in order to correctly process message receipts +- #1712: `TypeError: plugin._features is not a function` +- #1714: Don't notify the user in case we're receiving a message delivery receipt only +- #1739: New config option [assets_path](https://conversejs.org/docs/html/configuration.html#assets-path) + which lets you set the path from which "chunks" are loaded. + +## 5.0.3 (2019-09-13) + +- Emit `chatBoxFocused` and `chatBoxBlurred` events for emoji picker input +- SECURITY FIX: Reject unencapsulated forwarded messages, since we don't support XEP-0297 on its own + +## 5.0.2 (2019-09-11) + +- `po` translations files are now loaded via Webpack. As a result the `locales_url` + config option is now removed given that the path to the locale JSON files is now + determined by the webpack config and can't be changed at runtime. +- The JSON representing emojis is now fetched asynchronously as a separate file `converse.emojis.js`. +- Webpack is now configured with a `publicPath` set to `/dist/`. This is necessary + so that chunks (such as the emojis and locales JSON files) can be fetched asynchronously. + This means that all your assets need to be served at `/dist`. If you need to set a + different path, you'll need to set `publicPath` in `webpack.config.js` to + your preferred path and then rebuild all assets (e.g. `make dist`). +- Use `listenTo` to avoid memory leaks when views get removed. +- SECURITY FIX: Ignore MAM `chat` messages not sent from yourself +- #1692 Bugfix: `TypeError: oldest_message is undefined` +- #1704: SECURITY FIX: Impersonation by misusage of groupchat carbons +- #1705: Bugfix: `this.roomspanel` is `undefined` after hibernating + +## 5.0.1 (2019-08-14) + +- Add a new GUI for moderator actions. You can trigger it by entering `/modtools` in a MUC. +- Reconnect if the server doesn't respond to a `ping` within 10 seconds. +- Don't query for MAM MUC messages before the cached messages have been restored (another cause of duplicate messages). +- Show an error message and option to retry when fetching of the MAM archive times out +- Bugfix: `TypeError: o.getAttribute is not a function converse-chatview.js` (can cause messages to not appear). +- #1679: Room invitation fails with singleton and random server assigned room name + +## 5.0.0 (2019-08-08) + +- BOSH support has been moved to a plugin. +- Support for XEP-0410 to check whether we're still present in a room +- Initial support for the [CredentialsContainer](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer) web API +- Allow for synchronous events. When a synchronous event is fired, Converse will + wait for all promises returned by the event's handlers to finish before continuing. +- Properly handle message correction being received before the corrected message +- Groupchat default configuration now supports `list-multi` fields +- Bugfix: Don't set `muc_domain` for roomspanel if `locked_muc_domain` is `true`. +- Bugfix: Modal auto-closes when you open it for a second time. +- Bugfix: `Cannot read property 'parentElement' of null` in shadow DOM +- Take roster nickname into consideration when rendering messages and chat headings. +- Hide the textarea when a user is muted in a groupchat. +- Don't restore a BOSH session without knowing the JID +- In the `/help` menu, only show allowed commands +- Message deduplication bugfixes and improvements +- Continuously retry (in 2s intervals) to fetch login credentials (via [credentials_url](https://conversejs.org/docs/html/configuration.html#credentials-url)) in case of failure +- Replace `moment` with [DayJS](https://github.com/iamkun/dayjs). +- New config option [auto_focus](https://conversejs.org/docs/html/configuration.html#auto-focus) +- New config option [clear_messages_on_reconnection](https://conversejs.org/docs/html/configuration.html#clear-messages-on-reconnection) +- New config option [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks) +- New config option [message_limit](https://conversejs.org/docs/html/configuration.html#message-limit) +- New config option [muc_fetch_members](https://conversejs.org/docs/html/configuration.html#muc-fetch-members) +- New config option [muc_mention_autocomplete_min_chars](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-min-chars) +- New config option [muc_show_join_leave_status](https://conversejs.org/docs/html/configuration.html#muc-show-join-leave-status) +- New config option [singleton](https://conversejs.org/docs/html/configuration.html#singleton) + By setting this option to `false` and `view_mode` to `'embedded'`, it's now possible to + "embed" the full app and not just a single chat. To embed just a single chat, it's now + necessary to explicitly set `singleton` to `true`. +- Re-add the previously removed config option [keepalive](https://conversejs.org/docs/html/configuration.html#keepalive) +- New event: [chatBoxBlurred](https://conversejs.org/docs/html/api/-_converse.html#event:chatBoxBlurred) +- New event: [chatReconnected](https://conversejs.org/docs/html/api/-_converse.html#event:chatReconnected) +- #316: Add support for XEP-0198 Stream Management +- #1071: x clear cross of same size as text +- #1142: Up/down arrow shouldn't erase current message +- #1196: Use alternative connection method upon connfail +- #1296: `embedded` view mode shows `chatbox-navback` arrow in header +- #1330: Missing room name in MUC invitation popup +- #1445: Participants list uses big font in embedded mode +- #1455: Avatar in controlbox status-view not updated +- #1465: When highlighting a roster contact, they're incorrectly shown as online +- #1476: Support OMEMO on by default for chats via a config variable +- #1494: Trim whitespace around messages +- #1495: Mentions should always include a URI attribute +- #1502: Fatal error when using prebind +- #1524: OMEMO libsignal-protocol.js Invalid signature +- #1532: Converse reloads on enter pressed in the filter box +- #1538: Allow adding self as contact +- #1548: Add support for paging through the MAM results when filling in the blanks +- #1550: Legitimate carbons being blocked due to erroneous forgery check +- #1554: Room auto-configuration broke if the config form contained fields with type `fixed` +- #1558: `this.get` is not a function error when `forward_messages` is set to `true`. +- #1561: Don't call `clear` on local or session storage +- #1572: In `fullscreen` view mode the top is cut off on iOS +- #1575: MUC invitation autocomplete list doesn't appear +- #1576: Converse gets stuck with spinner when logging out with `auto_login` set to `true` +- #1579: Trim spaces at the beginning and end of a JID (when adding contact) +- #1585: Upload files by pasting from clipboard +- #1586: Not possible to kick someone with a space in their nickname +- #1664: Blacklisting converse-profile makes the control box totally blank + +### Breaking changes + +- The minimum required NodeJS version for making builds is now 8.9.0 +- Rename `muc_disable_moderator_commands` to [muc_disable_slash_commands](https://conversejs.org/docs/html/configuration.html#muc-disable-slash-commands). +- `_converse.api.archive.query` now returns a Promise instead of accepting a callback functions. +- `_converse.api.disco.supports` now returns a Promise which resolves to a Boolean instead of an Array. +- The `forward_messages` config option (which was set to `false` by default) has been removed. + Use [message_carbons](https://conversejs.org/docs/html/configuration.html#message-carbons) instead. +- Remove the `keepalive` configuration setting. It is now always implicitly `true`. +- Remove the `expose_rid_and_sid` configuration setting. +- A `prebind_url` is now mandatory when setting `authentication` to `prebind`. + It's no longer possible to pass in `rid` and `sid` values to `converse.initialize. +- Removed events `statusChanged` and `statusMessageChanged`. Instead, you can + listen on the `change:status` or `change:status\_message` events on + `_converse.xmppstatus`. +- #1403: Rename show_chatstate_notifications to show_chat_state_notifications + +### API changes + +- `_converse.chats.open` and `_converse.rooms.open` now take a `force` + parameter to force maximizing (in `overlayed` view mode) or bringing a + background chat into the foreground (in `fullscreen` view mode). Previously + this was the default behavior. +- `_converse.api.emit` has been removed in favor of [\_converse.api.trigger](https://conversejs.org/docs/html/api/-_converse.api.html#.trigger) +- `_converse.updateSettings` has been removed in favor of [\_converse.api.settings.update](https://conversejs.org/docs/html/api/-_converse.api.settings.html#.update) +- `_converse.api.roster.get` now returns a promise. +- New API method [\_converse.api.disco.features.get](https://conversejs.org/docs/html/api/-_converse.api.disco.features.html#.get) +- New API method [\_converse.api.connection.reconnect](https://conversejs.org/docs/html/api/-_converse.api.connection.html#.reconnect) + +## 4.2.0 (2019-04-04) + +**Note:** This release introduces a hard requirement on [MAM:2](https://xmpp.org/extensions/xep-0313.html), +specifically the requirement that the MAM archive ID matches the [XEP-0359 stanza-id](https://xmpp.org/extensions/xep-0359.html). +Patches intended to make Converse work with MAM:1 will cause problems and +unexpected behaviour due to the above requirement, which is not met with MAM:1. +This will affect OpenFire users who use the [monitoring plugin](https://www.igniterealtime.org/projects/openfire/plugin-archive.jsp?plugin=monitoring) +version 1.7.0 and below. You're advised to stay on Converse version 4.1.2 until an update to that plugin has been released. + +- Updated translation: af, cz, de, es, gl, he, lt, nl, nl_BE, ru +- Upgrade to Backbone 1.4.0, Strophe 1.3.2 and Jasmine 2.99.2 +- Remove dependency on (our fork of) Awesomplete +- Prevent user from adding themselves as contact +- Fix "flashing" of roster filter when you have less than 5 roster contacts +- Fix handling of CAPTCHAs offered by ejabberd +- Don't send out receipts or markers for MAM messages +- Allow setting of debug mode via URL with `/#converse?debug=true` +- Render inline images served over HTTP if Converse itself was loaded on an unsecured (HTTP) page. +- Make sure `nickname` passed in via `_converse.initialize` has first preference as MUC nickname +- Make sure required registration fields have "required" attribute +- New config setting [autocomplete_add_contact](https://conversejs.org/docs/html/configuration.html#autocomplete-add-contact) +- New config setting [locked_muc_domain](https://conversejs.org/docs/html/configuration.html#locked-muc-domain) +- New config setting [locked_muc_nickname](https://conversejs.org/docs/html/configuration.html#locked-muc-nickname) +- New config setting [show_client_info](https://conversejs.org/docs/html/configuration.html#show-client-info) +- Document new API method [sendMessage](https://conversejs.org/docs/html/api/-_converse.ChatBox.html#sendMessage) +- Don't filter out own device when sending an OMEMO message +- #1149: With `xhr_user_search_url`, contact requests are not being sent out +- #1213: Switch roster filter input and icons +- #1327: fix False mentions positives in URLs and Email addresses +- #1352: Add [Jed](https://github.com/messageformat/Jed) as dependency of `@converse/headless` +- #1373: Re-add support for the [muc_domain](https://conversejs.org/docs/html/configuration.html#muc-domain) setting +- #1400: When a chat message is just an emoji, enlarge the emoji +- #1407: Silent errors when trying to use whitespace as MUC nickname +- #1437: List of groupchats in modal doesn't scroll +- #1457: Wrong tooltip shown for "unbookmark" icon +- #1467: Fix rendering of URLs enclosed with sharp brackets such as +- #1479: Allow file upload by drag & drop also in MUCs +- #1487: New config option [muc_respect_autojoin](https://conversejs.org/docs/html/configuration.html#muc-respect-autojoin) +- #1488: In error message, fall back to JID if name is not available. +- #1501: Don't prompt for a reason if [auto_join_on_invite](https://conversejs.org/docs/html/configuration.html#auto-join-on-invite) is `true` +- #1507: Make message id and origin-id identical in order to fix LMC with Conversations +- #1508: Minimized bookmarked chatboxes should not be always maximized after page reload. +- #1512: Allow manual entry of jid even with [xhr_user_search_url](https://conversejs.org/docs/html/configuration.html#xhr-user-search-url). + The JID input field is now also visible. To hide it simply hide `.add-xmpp-contact__jid` via CSS. + +## 4.1.2 (2019-02-22) + +- Updated translations: af, cz, de, es, he, it, nl, nl_BE, pt_BR, zh_CN +- Bugfix. Prevent duplicate messages by comparing MAM archive id to XEP-0359 stanza ids. +- Bugfix. Open groupchats not shown when logging in after disconnection. +- #1406: `TypeError: e.devicelists is undefined` when unchecking the "trusted device" checkbox + +## 4.1.1 (2019-02-18) + +- Updated translations: af, cz, de, es, eu, ga, he, hi, ja, nb, nl_BE, zh_CN +- New language supported: Esperanto +- Accessibility: Tag the chat-content as an ARIA live region, for screen readers +- Set releases URL to new Github repo +- Rudimentary support for XEP-0333 chat markers +- Better support for XEP-0359 `stanza-id` and `origin-id` elements. +- Bugfix: restore textarea size after sending a message +- Bugfix: MUC invite form not appearing +- #1369 Don't wrongly interpret message with `subject` as a topic change. +- #1405 Status of contacts list are not displayed properly +- #1408 New config option [roomconfig_whitelist](https://conversejs.org/docs/html/configuration.html#roomconfig-whitelist) +- #1410 HTTP upload not working if conversations push proxy is used +- #1412 MUC moderator commands can be disabled selectively by config +- #1413 Fix moderator commands that change affiliation +- #1414 Prevent duplicate messages on MUC join +- #1417 Margin between nickname and badge +- #1421 Fix direct invite for membersonly room +- #1422 Resurrect the `muc_show_join_leave` option +- #1438 Update contact nickname when receiving a roster push +- #1442 MUC read receipts causing empty lines + +## 4.1.0 (2019-01-11) + +- Bugfix: MUC commands were being ignored +- Bugfix: Multiple rooms shown active in the rooms list +- Bugfix: Don't open chats when receiving messages without a `body` +- Bugfix: Typing in the textarea can become very slow in large MUCs +- UI: Always show the OMEMO lock icon (grayed out if not available). +- Use `publish-options` with `pubsub#access_model` set to `open` when publishing OMEMO public keys and devices +- Add a new `converse-pubsub` plugin, for generic PubSub operations +- #1180 It's now possible to use OMEMO in a MUC (if it's members-only and non-anonymous) +- #1334 Force avatar refetch when receiving `vcard-temp:x:update` +- #1337 `send_chat_state_notifications` doesn't work in MUCs +- #1353 Message Delivery Receipts not working because of the message "type" attribute +- #1356 Make triangle icon usable +- #1374 Can't load embedded chat when changing `view_mode` between page reloads +- #1376 Fixed some alignment issues in the sidebar +- #1378 Message Delivery Receipts were being sent for carbons and own messages +- #1379 MUC unread messages indicator is failing +- #1382 Message Delivery Receipts: Set store hint and type='chat' +- #1388 implement muc-owner command `/destroy` + +## 4.0.6 (2018-12-07) + +- Updated translations: ar, cs, de, es, eu, fr, gl, hu, id, it, ja, nb, pt_BR +- Don't render http (i.e. non-TLS) resources +- Bugfix: Converse caused `RID out of range` errors on Prosody +- Bugfix: MUC messages sometimes appear twice after resync. +- #1331 Fix missing checkmarks in old muc messages +- #1333 Don't send receipt requests in MUCs +- #1348 Font gets cut off in Firefox #1348 + +## 4.0.5 (2018-11-15) + +- Error `FATAL: TypeError: Cannot read property 'extend' of undefined` when using `embedded` view mode. +- Default paths in converse-notifications.js are now relative +- Add a button to regenerate OMEMO keys +- Add client info modal which shows Converse's version number +- New config setting [theme](https://conversejs.org/docs/html/configuration.html#theme) +- #141 XEP-0184: Message Delivery Receipts +- #1033 Setting show_send_button to true didn't work +- #1188 Feature request: drag and drop file to HTTP Upload +- #1268 Switch from SASS variables to CSS custom properties +- #1278 Replace the default avatar with a SVG version +- #1288 Add CSS classes to differentiate between incoming and outgoing messages +- #1305 added value 'all' for 'show_desktop_notifications' to notifiy even if converse.js is open +- #1306 added option `notification_delay` +- #1312 Error `unrecognized expression` in Safari +- #1316 show version info in login dialog +- #1317 Don't show errors for CSI messages +- #1318 added values 'on' and 'off' for 'trusted' option which removes the "This is a trusted device" checkbox from the login form +- #1319 Implement sending of presences according to XEP-0319: Last User Interaction in Presence + +## 4.0.4 (2018-10-29) + +- Use [Lerna](https://lernajs.io/) to create the @converse/headless package +- Use ES2015 modules instead of UMD. +- #1252 Correctly reflect the state in bookmark icon title. +- #1257 Prefer 'probably' over 'maybe' when evaluating audio play support. +- #1259 Don't inform of affiliation change after user leaves MUC +- #1261 File upload not working +- #1264 Right Align badges of room occupants +- #1272 Hiding MUC occupants leaves a blank space +- #1278 Replace the default avatar with a SVG version + +## 4.0.3 (2018-10-22) + +- New translations: Arabic, Basque, Czech, French, German, Hungarian, Japanese, Norwegian Bokmål, Polish, Romanian, Spanish +- Bugfix. Converse continuously publishes an empty OMEMO devicelist for itself +- Bugfix. Handler not triggered when submitting MUC password form 2nd time +- Bugfix. MUC features weren't being refreshed when saving the config form +- Don't show duplicate notification messages +- New config setting [show_images_inline](https://conversejs.org/docs/html/configuration.html#show-images-inline) +- Disable OMEMO when the user has indicated that Converse is running on an untrusted device. +- #537 Render `xmpp:` URI as link +- #1058 Send an inactive chat state notification when the user switches to another tab +- #1062 Collapse multiple join/leave messages into one +- #1063 URLs in the topic / subject are not clickable +- #1140 Add support for destroyed chatrooms +- #1169 Non-joined participants display an unwanted status message +- #1185 Added Contact still shown as pending +- #1190 MUC Participants column disappears in certain viewport widths +- #1193 OMEMO messages without a `` fallback are ignored +- #1199 Can't get back from to login screen from registration screen +- #1204 Link encoding issue +- #1209 Bring color codes of users' status in line with other clients +- #1214 Setting `allow_contact_requests` to `false` has no effect +- #1221 Avoid creating a headlines box if we don't have anything to show inside it +- #1222 Adding a bookmark should prefill the room name +- #1228 Converse automatically visits links (to try and determine whether they're images to show inline) + +## 4.0.2 (2018-10-02) + +- M4A and WEBM files, when sent as XEP-0066 Out of Band Data, are now playable directly in chat +- Updated French and Spanish translations +- Two new languages supported, [Hindi](https://hosted.weblate.org/languages/hi/conversejs/) and [Romanian](https://hosted.weblate.org/languages/ro/conversejs/) +- #1176 Add config setting [send_chat_state_notifications](https://conversejs.org/docs/html/configuration.html#send-chat-state-notifications) +- #1187 UTF-8 characters have the wrong encoding when using OMEMO +- #1189 Video playback failure +- #1220 Converse not working in Edge +- #1225 User profile sometimes not displayed when libsignal-protocol.js is used +- #1227 Login form does not work in Epiphany + +## 4.0.1 (2018-09-19) + +- Use https://compliance.conversations.im instead of dead link tot st https://xmpp.net +- New config setting [auto_register_muc_nickname](https://conversejs.org/docs/html/configuration.html#auto-register-muc-nickname) +- New config setting [enable_muc_push](https://conversejs.org/docs/html/configuration.html#enable-muc-push) +- #1182 MUC occupants without nick or JID created +- #1184 Notification error when message has no body +- #1201 Emoji picker appears when pressing enter + +## 4.0.0 (2018-09-07) + +## New Features + +- #161 XEP-0363: HTTP File Upload +- #194 Include entity capabilities in outgoing presence stanzas +- #337 API call to update a VCard +- #421 XEP-0308: Last Message Correction +- #497 XEP-0384: OMEMO encrypted messaging +- #968 Use nickname from VCard when joining a room +- #986 Affiliation changes aren't displayed in the chat +- #1081 Allow for shift-enter to insert newlines +- #1091 There's now only one CSS file for all view modes. +- #1094 Show room members who aren't currently online +- #1106 Support for Roster Versioning +- #1137 Autocompletion and support for [XEP-0372 References](https://xmpp.org/extensions/xep-0372.html), specifically section "3.2 Mentions". +- It's now also possible to edit your VCard via the UI +- Automatically grow/shrink input as text is entered/removed +- MP4 and MP3 files when sent as XEP-0066 Out of Band Data, are now playable directly in chat +- Support for rendering URLs sent according to XEP-0066 Out of Band Data. +- Geo-URIs (e.g. from Conversations) are now replaced by links to openstreetmap (works in reverse also) +- Add a checkbox to indicate whether a trusted device is being used or not. + If the device is not trusted, sessionStorage is used and all user data is deleted from the browser cache upon logout. + If the device is trusted, localStorage is used and user data is cached indefinitely. +- Initial support for [XEP-0357 Push Notifications](https://xmpp.org/extensions/xep-0357.html), specifically registering an "App Server". +- Add support for logging in via OAuth (see the [oauth_providers](https://conversejs.org/docs/html/configuration.html#oauth-providers) setting) + +### Bugfixes + +- Spoiler messages didn't include the message author's name. +- Documentation includes utf-8 charset to make minfied versions compatible across platforms. #1017 +- #1026 Typing in MUC shows "Typing from another device" +- #1039 Multi-option data form elements not shown and saved correctly +- #1143 Able to send blank message + +### API changes + +- `_converse.api.vcard.get` now also accepts a `Backbone.Model` instance and + has an additional `force` parameter to force fetching the vcard even if it + has already been fetched. +- New API method `_converse.api.vcard.update`. +- The `contactStatusChanged` event has been renamed to `contactPresenceChanged` + and a event `presenceChanged` is now also triggered on the contact. +- `_converse.api.chats.open` and `_converse.api.rooms.open` now returns a + `Presence` which resolves with the `Backbone.Model` representing the chat + object. + +## UI changes + +- #956 Conversation pane should show my own identity in pane header +- The UI is now based on Bootstrap4 and Flexbox is used extensively. +- Fontawesome 5 is used for icons. +- User Avatars are now shown in chat messages. + +## Configuration changes + +- Removed the `storage` configuration setting, use [trusted](https://conversejs.org/docs/html/configuration.html#trusted) instead. +- Removed the `use_vcards` configuration setting, instead VCards are always used. +- Removed the `xhr_custom_status` and `xhr_custom_status_url` configuration + settings. If you relied on these settings, you can instead listen for the + [statusMessageChanged](https://conversejs.org/docs/html/events.html#contactstatusmessagechanged) + event and make the XMLHttpRequest yourself. +- Removed `xhr_user_search` in favor of only accepting `xhr_user_search_url` as configuration option. +- `xhr_user_search_url` has to include the `?` character now in favor of more flexibility. See example in the documentation. +- The data returned from the `xhr_user_search_url` must now include the user's + `jid` instead of just an `id`. +- New configuration settings [nickname](https://conversejs.org/docs/html/configuration.html#nickname) + and [auto_join_private_chats](https://conversejs.org/docs/html/configuration.html#auto-join-private-chats). + +## Architectural changes + +- Extracted the views from `converse-muc.js` into `converse-muc-views.js` and + where appropriate moved methods from the views into the models/collections. + This makes MUC possible in headless mode. +- Created a new core plugin `converse-roster.js` which contains the models for + roster-related data. Previously this code was in `converse-core.js`. +- VCards are now stored separately from chats and roster contacts. + +## Other + +- Support for OTR (off-the-record) encryption has been dropped. + +## 3.3.4 (2018-03-05) + +- Don't show bookmark toggles when PEP bookmarking not supported by the XMPP server. +- Emojis are now sent in unicode instead of short names (also in MUCs) + +### Bugfixes + +- Server field in `Rooms` tab showed MUC supporting clients instead of only components. +- Avatars weren't being shown. +- Bookmarks list and open rooms list weren't recreated after logging in for a 2nd time (without reloading the browser). +- #1022 Status message not sent out on subsequent presences +- #1024 null reference on MUC Invite +- #1025 OTR lock icon disappears +- #1027 `new Event` not supported in IE11 +- #1028 Avoid `eval` (crept in via `_.template` from lodash). + +### Translation changes + +- New locale: Bulgarian +- Updated German, Russian, Chinese (traditional), Norwegian Bokmål and French translations. + +## 3.3.3 (2018-02-14) + +### Bugfixes +- Attribute error when empty IQ stanza is returned for vCard query +- In fullscreen view, sometimes a background MUC would come into the foreground + when a new message appears inside it. + +### Security fixes + +- CVE-2018-6591: Don't allow PEP bookmarks if `pubsub#publish-options` is not advertised by the server. + + In previous versions of converse.js, bookmarks sent to servers that don't + support `pubsub#publish-options` were visible to all your contacts, even + though they should be kept private. This is due to those servers simply + ignoring the `pubsub#publish-options` directive and converse.js not checking + first whether `pubsub#publish-options` is supported before setting bookmarks + via PEP. + + More info here: https://gultsch.de/converse_bookmarks.html + +### New features +- XEP-0382 Spoiler Messages (currently only for private chats) +- Listen for new room bookmarks pushed from the user's PEP service. +- Simplified the [embedded](https://conversejs.org/demo/embedded.html) usecase. + - No need to manually blacklist or whitelist any plugins. + - Relies on the [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode) being set to `'embedded'`. + - The main `converse.js` build can be used for the embedded usecase. + - Maintain MUC session upon page reload + +### API changes +- New API method `_converse.api.disco.getIdentity` to check whether a JID has a given identity. + +### Configuration settings +- `auto_reconnect` is now set to `true` by default. +- New configuration setting [allow_public_bookmarks](https://conversejs.org/docs/html/configuration.html#allow-public-bookmarks) +- New configuration setting [root](https://conversejs.org/docs/html/configuration.html#root) +- The [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode) setting now has a new possible value: `embedded` + +### Translation updates +- Chinese (Traditional), French, German, Portuguese (Brazil), Russian, Ukrainian + +## 3.3.2 (2018-01-29) + +### Bugfixes + +- Various fixes for IE11. +- Could not register on Ejabberd 18. `"Missing attribute 'id' in tag qualified by namespace 'jabber:client'"` +- #878 Ending slash in link not recognized +- #921 FATAL error when `visible_toolbar_buttons.emoji = false` +- #959 Add padding for the iPhone X (to the mobile CSS). +- #993 `moment.format` is not a function error when sending a message. +- #994 TypeError when using the `user.login` API. +- #995 `ChildNode.replaceWith` is not available in Internet Explorer or Safari. Use `Node.replaceChild` instead. +- #999 MUC Chat Send button causes page reload +- #1000 Scroll to bottom when maximizing a chat room. +- #1003 Handle bare MUC room JIDs + +### Translation changes + +- Updated Dutch, French, Japanese, Norwegian Bokmål and Ukrainian translations + +## 3.3.1 (2018-01-18) + +### UI/UX changes +- Add new configuration option + [show_message_load_animation](https://conversejs.org/docs/html/configuration.html#show-message-load-animation) + with a default value of `false`. The message load animations (added in 3.3.0) + cause slowness and performance issues in Firefox, so they're now disabled by default. + +### Translation changes +- Updated Spanish and French translations. +- New translation: "Simplified Chinese" +- Rename `zh` language code to `zh_TW` and add Simplified Chinese as `zh_CN` + +## 3.3.0 (2018-01-17) + +### Bugfixes +- #800 Could not register successfully in ejabberd 17.01 +- #949 Don't flash the roster contacts filter (i.e. hide by default) +- #951 Duplicate messages received in an MUC chat room. +- #953 MUC "Features" displayed when exiting configuration +- #967 Rooms list doesn't show when the server doesn't support bookmarks +- Don't require `auto_login` to be `true` when using the API to log in. +- Moment locale wasn't being set to the value passed via the `i18n` option. +- In the chat heading, two avatars sometimes get rendered. +- Refetch the roster from the server after reconnection. + From the perspective of the XMPP server, this is an entirely new login, + and therefore as per [RFC-6121](https://tools.ietf.org/html/rfc6121#section-2.1.6) + the roster SHOULD be queried, making the client an "interested resource". + Otherwise connected contacts might not get your presence updates. +- The way the archive ID of a MAM message is specified, has changed. + See https://xmpp.org/extensions/xep-0313.html#archives_id +- Fixed error building DOM toggle_chats.html span.unread-message-count class attribute +- Bugfix. In a MUC the `/help` command didn't render properly. +- The `/voice` MUC command didn't set the right role in order to grant voice again. + +### New Features +- Emojis are now sent in unicode instead of short names +- #314 Add support for opening chat rooms with a URL fragment such as `#converse/room?jid=room@domain` + and private chats with a URL fragment such as `#converse/chat?jid=user@domain` +- #828 Add routing for the `#converse/login` and `#converse/register` URL + fragments, which will render the registration and login forms respectively. +- New configuration setting [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode) + This removes the need for separate `inverse.js` and `converse-mobile.js` + builds. Instead the `converse.js` build is now used with `view_mode` set to + `fullscreen` and `mobile` respectively. +- Fetch VCard when starting a chat with someone not in the user's roster. +- Show status messages in an MUC room when a user's role changes. +- In MUC chat rooms, collapse multiple, consecutive join/leave messages. +- Performance improvements for rendering private chats, rooms and the contacts roster. +- MUC Leave/Join messages now also show a new day indicator if applicable. + +### API changes +- New API method `_converse.disco.supports` to check whether a certain + service discovery feature is supported by an entity. +- New API method `_converse.api.vcard.get` which fetches the VCard for a + particular JID. + +### Configuration changes +- `hide_open_bookmarks` is now by default `true`. + +### UX/UI changes +- #984 Improve loading of archived messages via "infinite scroll" +- Use CSS3 fade transitions to render various elements. +- Remove `Login` and `Registration` tabs and consolidate into one panel. +- Show validation error messages on the login form. +- Don't hang indefinitely and provide nicer error messages when a connection + can't be established. +- Consolidate error and validation reporting on the registration form. +- Don't close the emojis panel after inserting an emoji. +- Focus the message textarea when the emojis panel is opened or closed. +- MUC chatroom occupants are now sorted alphabetically and according to their roles. + +### Technical changes +- Converse.js now includes a [Virtual DOM](https://github.com/snabbdom/snabbdom) + via [backbone.vdomview](https://github.com/jcbrand/backbone.vdomview) and uses + it to render various views. +- Converse.js no longer includes all the translations in its build. Instead, + only the currently relevant translation is requested. This results in a much + smaller filesize but means that the translations you want to provide need to + be available. See the [locales_url](https://conversejs.org/docs/html/configuration.html#locales-url) + configuration setting for more info. +- The translation machinery has now been moved to a separate module in `src/i18n.js`. +- jQuery has been completely removed as a dependency (still used in tests though). + +## 3.2.1 (2017-08-29) + +### Bugfixes +- Various IE11 fixes. +- #907 Unnecessary login validation error when `default_domain` or `locked_domain` are set. +- #908 Login form for inVerse is only 200px when `allow_registration` is set to `false`. +- #909 Translations written as template literals [aren't parsed properly by xgettext](https://savannah.gnu.org/bugs/?50920). +- #911 Use `getDefaultNickName` consistently to allow better overrides via plugins. +- #912 `maximize` method in `converse-minimize` fails if the `controlbox` is not there. + +## 3.2.0 (2017-08-09) + +### New Plugins +- New plugin `converse-disco` which replaces the original support for + [XEP-0030](https://xmpp.org/extensions/xep-0030.html) and which has been + refactored to allow features for multiple entities to be stored. + +### New features and improvements +- Add support for Emojis (either native, or via Emojione). +- Add JID validation to the contact add form, the occupant invite form and the login form. +- #896 Consistently use `XMPP username` in user-facing text (instead of JID, Jabber ID etc.). + +### New configuration settings +* The `visible_toolbar_buttons.emoticons` configuration option is now changed to `visible_toolbar_buttons.emoji`. +* [use_emojione](https://conversejs.org/docs/html/configuration.html#use-emojione) + is used to determine whether Emojione should be used to render emojis, + otherwise rendering falls back to native browser or OS support. +* [emojione_image_path](https://conversejs.org/docs/html/configuration.html#emojione-image-path) + is used to specify from where Emojione will load images for rendering emojis. + +### New events +* ['discoInitialized'](https://conversejs.org/docs/html/development.html#discoInitialized) +* ['afterMessagesFetched'](https://conversejs.org/docs/html/development.html#afterMessagesFetched) + +### Code changes +- Removed jQuery from `converse-core`, `converse-vcard` and `converse-roomslist`. +- Remove `jquery.easing` from the full build. Was only being used by the + [conversejs.org](https://conversejs.org) website, which has been updated to not rely on it. +- All promises are now native (or polyfilled) ES2015 Promises instead of jQuery's Deferred. +- #866 Add babel in order to support ES2015 syntax + +#### Bugfixes: +- The domain was queried for MAM:2 support, instead of the JID. +- Roster filter is not shown when all groups are collapsed. +- When filtering, contacts in closed groups appear. +- Room name wasn't being updated after changing it in the configuration form. +- Server disco features were "forgotten" after logging out and then logging in again. +- Don't show duplicate sent groupchat messages in Slack chat rooms. +- Bookmark icon shown in the open rooms list when `allow_bookmarks` is to `false`. +- It wasn't possible to add or remove bookmarks via the "Open Rooms" list. +- #879 Text in links are converted to smileys leading to non-clickable links. +- #899: Only touch `stamp-npm` if `npm install` was successful +- #902 `make build` dependends on non-existing files + +## 3.1.1 (2017-07-12) + +- Use a patched version of [awesomplete](https://github.com/LeaVerou/awesomplete) + which doesn't render suggestions as HTML (possible XSS attack vector). [jcbrand] + +More info here: https://github.com/LeaVerou/awesomplete/pull/17082 + +## 3.1.0 (2017-07-05) + +### API changes +- Deprecate the `updateSettings` method in favour of + `_converse.settings.update`. [jcbrand] +- Add a new API method `_converse.promises.add` for exposing promises to be + used with `_converse.waitUntil`. [jcbrand] +- The `message` event now returns a data object with `stanza` and + `chatbox` attributes, instead of just the stanza. [jcbrand] + +### New Plugins +- New non-core plugin `converse-singleton` which ensures that no more than + one chat is visible at any given time. Used in the mobile build: + `converse-mobile.js` and makes the unread messages counter possible there. + [jcbrand] +- New non-core plugin `converse-roomslist`, which shows a list of open rooms + in the `Rooms` tab of the control box. [jcbrand] + +### New configuration settings +- New setting for `converse-bookmarks`: + [hide_open_bookmarks](https://conversejs.org/docs/html/configuration.html#hide-open-bookmarks) + It is meant to be set to `true` when using `converse-roomslist` so that open + rooms aren't listed twice (in the rooms list and the bookmarks list). + [jcbrand] + +### Github tickets resolved +- #567 Unreaded message count reset on page load [novokrest] +- #575 Logging out from converse.js doesn't clear the connection status from the + sessionStorage [jcbrand] +- #591 Unread message counter is reset when the chatbox is closed [novokrest] +- #754 Show unread messages next to roster contacts. [jcbrand] +- #864 Remove all inline CSS to comply with strict Content-Security-Policy headers [mathiasertl] +- #873 Inconsistent unread messages count updating [novokrest] +- #887 Make embedded images clickabe [jcbrand] +- #890 Message carbons not sent out after reconnection [jcbrand] +- #894 Room affiliation lost when connection jid and room presence jid are of different case [Rayzen] + +### Miscellaneous + +- Support for [XMPP-0313 Message Archive Management](https://xmpp.org/extensions/xep-0313.html) + has been upgraded to version 2. [jcbrand] +- Show unread messages for minimized chats. [jcbrand] +- Render nickname form when entering a room via invitation. [jcbrand] + +## 3.0.2 (2017-04-23) + +*Dependency updates*: +- Jasmine 2.5.3 +- Phantomjs 2.1.14 +- moment 2.18.1 +- sinon 2.1.0 +- eslint 3.19.0 + +- Don't rerender the text input when filtering contacts. [jcbrand] +- Show the MUC server in a bookmarked room's info view (in the bookmarks list). [jcbrand] +- Enable creation of `dist/converse-muc-embedded.js` build file for the + embedded MUC room demo. [jcbrand] +- Use `noConflict` to avoid polluting globale namespace with lodash and Backbone. [jcbrand] +- Bugfix: MUC user's nickname wasn't being shown in HTML5 notification messages. [jcbrand] +- Bugfix: OTR meta-messages were being shown in HTML5 notifications. [jcbrand] +- CSS fix: Icon lock wasn't showing. [jcbrand] +- #626 Open chat minimised [novokrest] +- #842 Persistent muc room creation not working [jcbrand] +- #848 OTR doesn't start when `cache_otr_key` is set to `true`. [jcbrand] +- #849 `TypeError: _converse.i18n.locale_data is undefined` when reconnecting. [jcbrand] +- #850 Roster not loading when group names are numbers. [jcbrand] + +## 3.0.1 (2017-04-04) + +- Bugfix. Endless spinner when trying to log in after rendering the registration form. [jcbrand] +- #585 Duplicate contact created due to JID case sensivity [saganshul] +- #628 Fixes the bug in displaying chat status during private chat. [saganshul] +- #628 Changes the message displayed while typing from a different resource of the same user. [smitbose] +- #675 Time format made configurable. + See [time_format](https://conversejs.org/docs/html/configuration.html#time-format) + [smitbose] +- #682 Add "Send" button to input box in chat dialog window. + See [show_send_button](https://conversejs.org/docs/html/configuration.html#show-send-button) + [saganshul] +- #704 Automatic fetching of registration form when + [registration_domain](https://conversejs.org/docs/html/configuration.html#registration-domain) + is set. [smitbose] +- #806 The `_converse.listen` API event listeners aren't triggered. [jcbrand] +- #807 Error: Plugin "converse-dragresize" tried to override HeadlinesBoxView but it's not found. [jcbrand] +- #811 jQuery wasn't being closured in builds. [jcbrand] +- #814 Images from URLs with query strings aren't being rendered. [novokrest] +- #820 Inconsistency in displaying room features. [jcbrand] + +## 3.0.0 (2017-03-05) + +- **Breaking changes**: + * Plugins must now be whitelisted. + See the [whitelisted_plugins](https://conversejs.org/docs/html/configuration.html#whitelisted-plugins) setting. + * Callbacks for `converse.on` now no longer receive an event object as first parameter. + * The API has been split into public and private parts. + The private API methods are now only available to plugins. + For more info, read [developer API](https://conversejs.org/docs/html/developer_api.html) + and the [plugin_development](https://conversejs.org/docs/html/plugin_development.html) + documentation. + * To prevent confusion the private, closured object, only + available to plugins, has been renamed from `converse` to `_converse`. + The public API is accessible via a global `converse` object. + * The `keepalive` and `roster_groups` options are now set to `true` by default. + * Templates are no longer stored as attributes on the `_converse` object. + If you need a particular template, use `require` to load it. + +- Bugfix. After bookmarking a room for which a nickname is required, return to + the nickname form. [jcbrand] +- Show the chat states of room occupants. [jcbrand] +- The no-jQuery build has been renamed from `converse.nojquery.js` to + `converse-no-jquery.js` to fit the convention used for other build names. + [jcbrand] +- 50 is the new default [archived_messages_page_size](https://conversejs.org/docs/html/configuration.html#archived-messages-page-size) + [jcbrand] +- Better support for delayed delivery of presence stanzas (XEP-0203). [jcbrand] +- The chat room `description` is now shown in the heading, not the `subject`. + [jcbrand] +- Chat room features are shown in the sidebar. [jcbrand] +- Hide the chat room invite widget if the room is not open or if the room is members-only + and the user is not the owner. [jcbrand] +- Created a new non-core plugin `converse-muc-embedded` which embeds a single + chat room into a page. An example can be found at https://conversejs.org/demo/embedded.html + [jcbrand] +- Use lodash instead of underscore.js [jcbrand] +- Case insensitive matching of moderation commands. [jcbrand] +- Add `/subject` as alias to `/topic` [jcbrand] +- `message_carbons`, `play_sounds` and `allow_chat_pending_contacts` now default to `true` [jcbrand] +- Improved roster filter UX. [jcbrand] +- Render the login form again upon authfail. [jcbrand] +- New promises API: [waitUntil](https://conversejs.org/docs/html/developer_api.html#waituntil) + [jcbrand] +- New configuration setting: + [show_chatstate_notifications](https://conversejs.org/docs/html/configuration.html#show-chatstate-notifications) + [jcbrand] +- New configuration setting: + [whitelisted_plugins](https://conversejs.org/docs/html/configuration.html#whitelisted-plugins) + [jcbrand] +- New configuration setting: + [blacklisted_plugins](https://conversejs.org/docs/html/configuration.html#blacklisted-plugins) + [jcbrand] +- The API now no longer returns wrapped chatboxes (or rooms) but instead a + Backbone.View object. This means the API of the returned object has changed. + You're still able to do everything from before but now also much more. + [jcbrand] +- Allow JIDs not on the roster to be invited to a chat room. [jcbrand] +- Bugfix. `TypeError: this.sendConfiguration(...).then is not a function` when + an instant room is created. [jcbrand] +- Ensure consistent behavior from `show_controlbox_by_default` [jcbrand] +- #365 Show join/leave messages for chat rooms. + New configuration setting: + [muc_show_join_leave](https://conversejs.org/docs/html/configuration.html#muc-show-join-leave) +- #366 Show the chat room occupant's JID in the tooltip (if you're allowed to see it). [jcbrand] +- #610, #785 Add presence priority handling [w3host, jcbrand] +- #620 `auto_away` shouldn't change the user's status if it's set to `dnd`. [jcbrand] +- #694 The `notification_option` wasn't being used consistently. [jcbrand] +- #745 New config option [priority](https://conversejs.org/docs/html/configuration.html#priority) [jcbrand] +- #770 Allow setting contact attrs on chats.open [Ape] +- #790 MAM retrieval broken [jcbrand] + +## 2.0.6 (2017-02-13) +- Escape user-generated input to prevent JS-injection attacks. (Thanks to SamWhited) [jcbrand] +- #486 Honor existing mam user configuration [throwaway42] +- #749 /me will show your contact's name in the sent field [jcbrand] +- #774 Browser language (fr-fr or fr) is not detected by default [jcbrand] +- #775 Anonymous login form is a text field instead of a push button [jcbrand] + +## 2.0.5 (2017-02-01) +- #743, #751, #753 Update to Strophe 1.2.12. SASL-EXTERNAL now has reduced priority, so it won't + be prioritized above other auth mechanisms. [jcbrand] +- #755: create composer.json to add this project in packagist.org [fabiomontefuscolo] +- #758: Bugfix. Render all resize drag handles for ChatRoomView. [LeoYReyes] +- #762 Allow chatting with users not in your roster. [Ape, jcbrand] +- Bugfix. Cancel button shown while registration form is being fetched wasn't working + properly. [jcbrand] +- Bugfix. Login form wasn't rendered after logging out (when `auto_reconnect` is `true`). [jcbrand] +- Bugfix. Properly disconnect upon "host-unknown" error. [jcbrand] +- Bugfix. Minimized chats weren't removed when logging out. [jcbrand] +- Security fix: Prevent message forging via carbons. (Thanks to ge0rg) [jcbrand] + +## 2.0.4 (2016-12-13) +- #737: Bugfix. Translations weren't being applied. [jcbrand] +- Fetch room info and store it on the room model. + For context, see: https://xmpp.org/extensions/xep-0045.html#disco-roominfo [jcbrand] +- Bugfix. Switching from bookmarks form to config form shows only the spinner. [jcbrand] +- Bugfix. Other room occupants sometimes not shown when reloading the page. [jcbrand] +- Bugfix. Due to changes in `converse-core` the controlbox wasn't aware anymore of + disconnection or reconnection events. [jcbrand] +- Optimize fetching of MAM messages (in some cases happened on each page load). [jcbrand] +- Fix empty controlbox toggle after disconnect. [jcbrand] +- When inviting someone to a members-only room, first add them to the member + list. [jcbrand] +- New configuration setting [muc_disable_moderator_commands](https://conversejs.org/docs/html/configuration.html#muc-disable-moderator-commands) [jcbrand] + +## 2.0.3 (2016-11-30) +- #735 Room configuration button not visible. [jcbrand] +- CSS fix for fadeIn animation. [jcbrand] + +## 2.0.2 (2016-11-30) +- #721 keepalive not working with anonymous authentication [jcbrand] +- #723 Bugfix: Arrays in configuration settings were ignored. [jcbrand] +- #734 Bugfix. `converse.rooms.open` ignored the `muc_nickname_from_jid` setting. [jcbrand] +- Enable new rooms to be configured automatically, with a default config, via `rooms.open`. + For details, refer to the [relevant documentation](https://conversejs.org/docs/html/developer_api.html#the-rooms-grouping) [jcbrand] +- Bugfix: Chatboxes aren't closed when logging out. [jcbrand] +- Bugfix: Trying to save data on the `ControlBox` model before `ChatBoxes` + collection has its `browserStorage` configured. + Causes `Error: A "url" property or function must be specified`. [jcbrand] +- Don't open the controlbox on contact requests. [jcbrand] +- Bugfix: Reconnection fails when original connection was never established. [jcbrand] +- If a `credentials_url` is provided, then keep on attempting to reconnect when connection is down. [jcbrand] +- Remove (undocumented) `callback` config parameter for `converse.initialize`. + Instead, `converse.initialize` returns a promise which will resolve once + initialization is complete. [jcbrand] +- New event ['reconnecting'](https://conversejs.org/docs/html/development.html#reconnecting) [jcbrand] +- New configuration setting [allow_bookmarks](https://conversejs.org/docs/html/configuration.html#allow-bookmarks) [jcbrand] +- The `rooms.open` API method will no longer maximize rooms that are minimized (unless `maximize: true` is passed in). [jcbrand] + +## 2.0.1 (2016-11-07) +- #203 New configuration setting [muc_domain](https://conversejs.org/docs/html/configuration.html#muc-domain) [jcbrand] +- #705 White content after submitting password on chat rooms [jcbrand] +- #712 Controlbox clicks stop responding after auto-reconnect [jcbrand] +- Removed shared state between tests. All tests are now isolated. [jcbrand] +- Allow the context (i.e. `this` value) to be passed in when registering event + listeners with `converse.listen.on` and `converse.listen.once`. [jcbrand] +- New event ['rosterContactsFetched'](https://conversejs.org/docs/html/development.html#rosterContactsFetched) [jcbrand] +- New event ['rosterGroupsFetched'](https://conversejs.org/docs/html/development.html#rosterGroupsFetched) [jcbrand] +- HTML templates are now loaded in the respective modules/plugins. [jcbrand] +- Start improving Content-Security-Policy compatibility by removing inline CSS. [mathiasertl] +- Add support for XEP-0048, chat room bookmarks [jcbrand] +- New configuration setting [connection_options](https://conversejs.org/docs/html/configuration.html#connection-options) [jcbrand] + +## 2.0.0 (2016-09-16) +- #656 Online users count not shown initially [amanzur] +- #674 Polish translation updated [ser] +- Backwards incompatible change: the `_super` attribute in plugins is now named `__super__`. [jcbrand] +- Continuously attempt to resurrect dead connections when `auto_reconnect` is `true`. [jcbrand] +- Update the 'rooms' API to allow user to pass in room attributes. [jcbrand] +- New configuration setting [message_storage](https://conversejs.org/docs/html/configuration.html#message-storage) [jcbrand] +- Hardcode the storage for roster contacts and chat room occupants to `sessionStorage`. [jcbrand] +- Fixed wrong chat state value, should be `chat`, not `chatty`. + See [RFC 3921](https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.1.2.2). [jcbrand] +- Adds support for SASL-EXTERNAL. [jcbrand] + +## 1.0.6 (2016-08-12) +- #632 Offline and Logout states do not properly update once users start + chatting. [chrisuehlinger, jcband] +- #674 Polish translation updated to the current master. [ser] +- #677 Chatbox does not open after close. [jcbrand] +- The behavior of `converse.chats.get` has changed. If the chat box is not + already open, then `undefined` will be returned. [jcbrand] +- Typing (i.e. chat state) notifications are now also sent out from MUC rooms. [jcbrand] +- `ChatRoomView.onChatRoomMessageSubmitted` has been renamed to + `onMessageSubmitted`, to make it the same as the method on `ChatBoxView`. [jcbrand] +- New configuration setting [muc_nickname_from_jid](https://conversejs.org/docs/html/configuration.html#muc-nickname-from-jid) [jcbrand] +- New configuration setting [muc_instant_rooms](https://conversejs.org/docs/html/configuration.html#muc-instant-rooms) [jcbrand] + +## 1.0.5 (2016-07-28) +- In case of nickname conflict when joining a room, allow the user to choose a new one. + [jcbrand] +- Check whether the user has a reserved nickname before entering a room, and if so, + use it. [jcbrand] +- Mention someone in your chat room message by clicking on their name in the occupants + list. [jcbrand] +- #645 When accepting a contact request, the contact didn't appear in the + pending contacts group. [jcbrand] +- Bugfix: allow multiple MAM queries to be made simultaneously. [jcbrand] + +## 1.0.4 (2016-07-26) + +- Restrict occupants sidebar to 30% chat room width. [jcbrand] +- Made requesting contacts more visible, by placing them at the top of the roster. [jcbrand] +- `insertIntoPage` method of `ChatBoxView` has been renamed to `insertIntoDOM`, + to make it the same as the method of `ChatRoomView`. [jcbrand] +- Render error messages received from the server (for undelivered chat messages). [jcbrand] +- Don't hide requesting contacts when filtering by chat state. [jcbrand] +- When logging in anonymously, the server JID can now be passed in via `converse.initialize` + or via `converse.user.login`. [jcbrand] + +## 1.0.3 (2016-06-20) + +- Update the plugin architecture to allow plugins to have optional dependencies [jcbrand] +- Bugfix. Login form doesn't render after logging out, when `auto_reconnect = false` [jcbrand] +- Also indicate new day for the first day's messages. [jcbrand] +- Chat bot messages don't appear when they have the same ids as their commands. [jcbrand] +- Updated onDisconnected method to fire disconnected event even if `auto_reconnect = false`. [kamranzafar] +- Bugfix: MAM messages weren't being fetched oldest first. [jcbrand] +- Add processing hints to chat state notifications [jcbrand] +- Don't use sound and desktop notifications for OTR messages (when setting up the session) [jcbrand] +- New config option [default_state](https://conversejs.org/docs/html/configuration.html#default_state) [jcbrand] +- New API method `converse.rooms.close()` [jcbrand] +- New configuration setting [allow_muc_invites](https://conversejs.org/docs/html/configuration.html#allow-muc-invites) [jcbrand] +- Add new event [pluginsInitialized](https://conversejs.org/docs/html/development.html#pluginsInitialized) [jcbrand] +- #553 Add processing hints to OTR messages [jcbrand] +- #650 Don't ignore incoming messages with same JID as current user (might be MAM archived) [jcbrand] +- #656 online users count in minimized chat window on initialization corrected [amanzur] + +## 1.0.2 (2016-05-24) + +- Bugfix. Bind `sendPresence` to the right context. Bug that slipped in during + the release of `1.0.1`. [jcbrand] + +## 1.0.1 (2016-05-24) + +- Bugfix. Roster filter sometimes gets hidden when it shouldn't. [jcbrand] +- Chat boxes weren't being initialized due to typo. [jcbrand] +- Flush request queue just after connection. Solves a problem with PubSub and + Prosody, whereby BOSH HTTP responses weren't being received. [jcbrand] + +## 1.0.0 (2016-05-03) + +- Add catalan language [JoseMariaRubioMoral] +- Split converse.js up into different plugin modules. [jcbrand] +- Better Sass/CSS for responsive/mobile views. New mobile-only build. [jcbrand] +- Roster contacts can now be filtered by chat state and roster filters are + remembered across page loads. [jcbrand] +- Add support for messages with type `headline`, often used for notifications + from the server. [jcbrand] +- Add stanza-specific event listener `converse.listen.stanza`. + As a result `converse.listen.on('message');` has been deprecated, use + `converse.stanza.on('message');` instead. [jcbrand] +- Emit an event `chatBoxInitialized` once a chat box's initialize method has been called. [jcbrand] +- Emit an event `statusInitialized` once the user's own status has been initialized upon startup. [jcbrand] +- New config option [chatstate_notification_blacklist](https://conversejs.org/docs/html/configuration.html#chatstate-notification-blacklist) [jcbrand] +- New config option [sticky_controlbox](https://conversejs.org/docs/html/configuration.html#sticky-controlbox) [jcbrand] +- New config option [credentials_url](https://conversejs.org/docs/html/configuration.html#credentials-url) [jcbrand] +- Don't play sound notifications for OTR messages which are setting up an + encrypted session. [jcbrand] +- Bugfix: RID, SID and JID tokens ignored when `keepalive` set to `true`. [jcbrand] +- Removed the `account.logout` API, instead use `user.logout`. [jcbrand] +- Use `rel=noopener` with links that contain `target=_blank` to prevent potential + phishing attacks. [More info here](https://mathiasbynens.github.io/rel-noopener/) + [jcbrand] +- #156 Add the option `auto_join_rooms` which allows you to automatically + connect to certain rooms once logged in. [jcbrand] +- #261 `show_controlbox_by_default` config not working [diditopher] +- #443 HTML5 notifications of received messages [jcbrand] +- #534 Updated Russian translation [badfiles] +- #566 Do not steal the focus when the chatbox opens automatically [rlanvin] +- #573 xgettext build error: `'javascript' unknown` [jcbrand] +- #577 New config variable [message_archiving_timeout](https://conversejs.org/docs/html/configuration.html#message-archiving-timeout) [jcbrand] +- #587 Fix issue when logging out with `auto_logout=true` [davec82] +- #589 Save scroll position on minimize and restore it on maximize [rlanvin] +- #592 Add random resource for `auto_login`, add method generateResource to + generate random resource [davec82] +- #598 Add option `synchronize_availability` [davec82] +- #600 Fix change xmpp status also on icon-status click [davec82] +- #616 converse-otr should depend on converse-minimize [jcbrand] +- #609 Remove split of fullname [lixmal] + +## 0.10.1 (2016-02-06) + +- #352 When the user has manually scrolled up in a chat window, don't scroll + down on chat event notifications. [jcbrand] +- #524 Added [auto_join_on_invite](https://conversejs.org/docs/html/configuration.html#auto_join_on_invite) + parameter for automatically joining chat rooms. [ben] +- #520 Set specific domain. Two new options [default_domain](https://conversejs.org/docs/html/configuration.html#default_domain) + and [locked_domain](https://conversejs.org/docs/html/configuration.html#locked_domain). [jcbrand] +- #521 Not sending presence when connecting after disconnection. [jcbrand] +- #535 Messages not received when room with mixed-case JID is used. [jcbrand] +- #536 Presence not sent out (in cases where it should) after page refresh. [jcbrand] +- #540 `bind is not a function` error for plugins without `initialize` method. [jcbrand] +- #547 By default the `offline` state is no longer choosable. + See [include_offline_state](https://conversejs.org/docs/html/configuration.html#include-offline-state) for details. [jcbrand] +- A chat room invite might come from someone not in your roster list. [ben] +- #487 Empty the resources array when the resource is null [rlanvin] +- #534 Updated Russian translation [LaconicTranslator] +- #555 The status restored from sessionStorage is never updated [jcbrand] +- #559 Remove reconnection timer once connected succesfully [m0cs] + +## 0.10.0 (2015-11-05) + +**Note:** +*This release drops CSS support for IE8 and IE9.* + +- #459 Wrong datatype passed to converse.chatboxes.getChatBox. [hobblegobber, jcbrand] +- #493 Roster push fix [jcbrand] +- #403 emit an event `rosterPush` when a roster push happens [teseo] +- #502. Chat room not opened in non_amd version. [rjanbiah] +- #505 Typo caused [object Object] in room info [gromiak] +- #508 "Is typing" doesn't automatically disappear [jcbrand] +- #509 Updated Polish translations [ser] +- #510 MUC room memberlist is being cleared with page reload when keepalive option is set. [jcbrand] +- Add the ability to also drag-resize chat boxes horizontally. [jcbrand] +- Updated Sass files and created a new style. [jcbrand] + + +## 0.9.6 (2015-10-12) + +- Bugfix. Spinner doesn't disappear when scrolling up (when server doesn't support XEP-0313). [jcbrand] +- #462 Fix MUC rooms with names containing special characters not working [1st8] +- #467 Fix outgoing chat messages not having a msgid when being put into sessionStorage [1st8] +- #468 Fix [object Object] being sometimes shown as status [1st8] +- #472 Fix "Cannot read property 'splitOnce' of undefined" when typing /clear in a chat room. [jcbrand] +- #493 Roster wasn't being updated after a Roster push update [teseo, jcbrand] +- #496 Bugfix. Pings weren't being sent out. [teseo, jcbrand] +- #499 Message not received due to non-unique message ids. [jcbrand] + +## 0.9.5 (2015-08-24) + +- #306 XEP-0313: Message Archive Management [jcbrand] +- #439 auto_login and keepalive not working [jcbrand] +- #440 null added as resource to contact [jcbrand] +- Add new event serviceDiscovered [jcbrand] +- Add a new configuration setting [muc_history_max_stanzas](https://conversejs.org/docs/html/configuration.html#muc-history-max-stanzas>). [jcbrand] + +## 0.9.4 (2015-07-04) + +- #144 Add Ping functionality and Pong handler [thierrytiti] +- #234, #431 Messages aren't received when the user logs in with a mixed-case JID. [jcbrand] +- #367 API methods for changing chat status (online, busy, away etc.) and status message [jcbrand] +- #389 Allow login panel placeholders and roster item 'Name' translations. [gbonvehi] +- #394 Option to allow chatting with pending contacts [thierrytiti] +- #396 Add automatic Away mode and XEP-0352 support [thierrytiti] +- #400, #410 Allow offline pretty status and placeholder for "Insert a smiley" to be translated [thierrytiti] +- #401 Updated French translation [thierrytiti] +- #404 CSS fix: position and width of the div #conversejs [thierrytiti] +- #407 CSS: Fonts Path: editabable $font-path via sass/variables.scss [thierrytiti] +- #408 MUC: missing toggle call handler and updated documentation about call [thierrytiti] +- #413 Auto-detect user's locale to show date and time in the right format [thierrytiti] +- #415 closeAllChatBoxes is giving ReferenceError when 2 chats are open [nevcos, jcbrand] +- #416 Add icon for XA status [thierrytiti] +- #418 Logging out with `auto_reconnect=true` causes reconnection retries [jcbrand] +- #420 Updated German translation [1st8] +- #427 Converse.js does not subscribe back to a contact not in the roster. [emmanuel-florent] +- Add offline pretty status to enable translation [thierrytiti] +- Bugfix. ClearSessions during unload event would throw an error when not logged in. [gbonvehi] +- Bugfix. Manual login doesn't work when only websocket_url is set and not bosh_service_url. [jcbrand] +- Bugfix. Wrong callback argument mapping in XmppStatus initialize: fullname is null [thierrytiti] +- CSS fix: room-info bug on hover after room description loaded [thierrytiti] +- CSS: Fonts Path: editabable $font-path via sass/variables.scss [thierrytiti] +- Chat boxes returned by the API now have an `is_chatroom` attribute [jcbrand] +- Decouple automatic away and XEP-0352 support. [jcbrand] +- Don't carbon copy OTR messages. [jcbrand] +- I18N: Autodetection of User Locale if no i18n setting is set. [thierrytiti] +- Refactored in order to remove the strophe.roster.js dependency. [jcbrand] +- Refactored the plugin architecture. Add `overrides` convention for + automatically overriding converse.js's methods and Backbone views and models. [jcbrand] +- With keepalive, don't send out a presence stanza on each page load [jcbrand] + +## 0.9.3 (2015-05-01) + +- Add the ability to log in automatically. [jcbrand] +- Remove `type=email` from JID field in login form. Resulting validation error confuses people. [jcbrand] +- Add Ukranian translations [Andriy Kopystyansky] +- #244 Add the ability to log in anonymously. [jcbrand] +- #344 Enable the path to the sound files to be configured [thierrytiti and jcbrand] +- #370 Unable to register a new user to ejabberd 2.1.11. [gbonvehi] +- #372 Some offline users have a visible empty `
` in the roster. [floriancargoet] +- #374 Fix collapsed group visibility on page load. [floriancargoet] +- #378 Expect full JIDs to be returned via XHR user search [thierrytiti] +- #379 Updated French translations [thierrytiti] +- #379 Fix for bower not finding crypto-js-evanvosberg#3.1.2-5 any more. [jcbrand] + +## 0.9.2 (2015-04-09) + +- Bugfix. Prevent attaching twice during initialization. [jcbrand] +- API method chats.get can now also return chat boxes which haven't been opened yet. [jcbrand] +- Add API method contacts.add. [pzia] +- #356 Fix the plugin extend function. [floriancargoet] +- #357 Fix the known bug where a state notification reopens a chat box. [floriancargoet] +- #358 Bugfix. Chat rooms show the same occupants bug. [floriancargoet] +- #359 Fix a timeout bug in chat state notifications. [floriancargoet] +- #360 Incorrect roster height when `allow_contact_requests=true`. [floriancargoet, jcbrand] +- #362 Add API for retrieving and opening rooms. [pzia] +- #364 Text selection in chat boxes not shown in Firefox. [jcbrand] + +## 0.9.1 (2015-03-26) + +- Set the JID input field in the login form to `type=email`. [chatme] +- New configuration setting [allow_contact_removal](https://conversejs.org/docs/html/configuration.html#allow-contact-removal) [jcbrand] +- Document that event handlers receive 'event' obj as first arg. [jcbrand] +- Add a test to check that notifications are played in chat rooms. [jcbrand] +- #333 Enable automatic reconnection when `prebind` and `prebind_url` are specified. [jcbrand] +- #339 Require the JID to be specified when using `keepalive` with `prebind`. Also add a logout API method. [jcbrand] +- #349 Indicate visitors in chat rooms. [c143] + +## 0.9.0 (2015-03-06) + +- #204 Support websocket connections. [jcbrand] +- #252, 253 Add fullname and jid to contact's tooltip in roster. [gbonvehi] +- #292 Better support for XEP-0085 Chat State Notifications. [jcbrand] +- #295 Document "allow_registration". [gbonvehi] +- #304 Added Polish translations. [ser] +- #305 presence/show text in XMPP request isn't allowed by specification. [gbonvehi] +- Add new API method `chats.open` to open chat boxes. [jcbrand] +- Add new API method to set and get configuration settings. [jcbrand] +- Add responsiveness to CSS. We now use Sass preprocessor for generating CSS. [jcbrand] +- Bugfix. Custom status message form doesn't submit/disappear. [jcbrand] +- Calling the API method `contacts.get()` without parameters now returns all contacts. [jcbrand] +- Don't send out the message carbons IQ stanza on each page load. [jcbrand] +- New Makefile.win to build in Windows environments. [gbonvehi] +- Norwegian Bokmål translations. [Andreas Lorentsen] +- Removed deprecated API methods. [jcbrand] +- Strophe.log and Strophe.error now uses converse.log to output messages. [gbonvehi] +- The API method `chats.get` now only returns already opened chat boxes. [jcbrand] +- Updated Afrikaans translations. [jcbrand] +- Add new configuration setting [prebind_url](https://conversejs.org/docs/html/configuration.html#prebind-url) [jcbrand] + +## 0.8.6 (2014-12-07) + +- Bugfix. Login panel didn't appear under certain conditions. [jcbrand] +- Bugfix. Error when trying to render chat room configuration form. [jcbrand] +- Text on the registration form was not configurable or i18n aware. [jcbrand] +- #285 With prebind the jid, rid and sid settings were ignored. [jcbrand] + +## 0.8.5 (2014-12-01) + +- #117 JIDs or nicknames not shown in chat rooms. [jcbrand] +- #282 XEP-0077 In-band registration. [jcbrand] + +## 0.8.4 (2014-11-15) + +**note:** +*Certain API methods have been deprecated in favor of a new API and will be removed in the 0.9.0 release.* + +- Bugfix. Error when trying to use prebind and keepalive together. [heban and jcbrand] +- Bugfix. Cannot read property "top" of undefined. [jcbrand] +- Add new event, noResumeableSession, for when keepalive=true and there aren't + any prebind session tokens. [jcbrand] +- #46 Refactor the API and add new methods. [jcbrand] +- #151 Browser locks/freezes with many roster users. [jcbrand] +- #177 Setting status to offline does nothing. [jcbrand] +- #232 Always get full name from model. [jcbrand] +- #237 Unable to create room when `hide_muc_server` is `true`. [jcbrand] +- #238 Rooms are not shown when `hide_offline_users` is `true`. [jcbrand] +- #251 Non-minified builds for debugging. [jcbrand] +- #260 Sent message carbons are not displayed. [jcbrand] +- #262 Contact requests are not shown if page is reloaded. [jcbrand] +- #264 Remove unnecessary commas for ie8 compatibility. [Deuteu] +- #267 Unread messages counter wrongly gets incremented by chat state notifications. [Deuteu] +- #274 Roster filtering results change with presence changes. [jcbrand] +- #275 Custom status message doesn't reset. [jcbrand] +- #278 Unread messages counter doesn't unbind it's events. [Deuteu] +- #279 Handle more field types for MUC config forms. [gbonvehi] +- #280 New config option, `hide_offline_users` [gbonvehi] + +## 0.8.3 (2014-09-22) + +- The Javascript build files in the 0.8.2 release weren't updated due to a + unnoticed build error. [jcbrand] + +## 0.8.2 (2014-09-22) + +- Converse.js now has the ability to maintain sessions across page loads. + Previously, the session tokens had to be handled externally and passed in. + See the [keepalive](https://conversejs.org/docs/html/configuration.html#keepalive) configuration setting. [jcbrand] +- Allow changing of nickname in a chat room via /nick command. [jcbrand] +- Allow a chat room user to be muted or unmuted with the /mute and /voice commands. [jcbrand] +- Add a chat room toolbar button for toggling the list of occupants. [jcbrand] +- Converse.js now responds to XEP-0030: Service Discovery requests. [jcbrand] +- Bugfix. Roster groups all appear offline after page reload (with prebind). + See http://librelist.com/browser//conversejs/2014/8/26/problem-with-contact-list-everyone-is-offline/ [heban and jcbrand] +- Bugfix concerning trimmed chats. Chats were being trimmed even though there was enough room. [jcbrand] +- #62 Sound notifications will now also play when you are mentioned in a chat room. [jcbrand] +- #212 Bugfix. Groups weren't being show again after the live filter was cleared. [jcbrand] +- #215 (and also #75) XEP-0249: Direct MUC Invitations. [jcbrand] +- #216 Contacts tab empty when using xhr_user_search. [hcderaad and jcbrand] +- #219 New contacts added need page refresh to be accepted and become visible. [hcderaad and jcbrand] +- #220 Non-AMD example page was not working. [xavier83ar and jcbrand] +- #222 Control box state not remembered. [priyadi and jcbrand] +- #223 Provide API to query buddy status. [priyadi and jcbrand] +- #227 Updated Hebrew translations [GreenLunar] + +## 0.8.1 (2014-08-23) + +- Bugfix: Roster contacts' cache key too vague. [jcbrand] +- Bugfix: Roster contacts weren't properly sorted according to chat status. [jcbrand] +- #63 Support for sound notification when message is received. [jcbrand] +- #212 Provide a live filter of the roster contacts. [jcbrand] + +## 0.8.0 (2014-08-04) + +**note**: + 1. Converse.js is now relicensed under the [Mozilla Public License](http://www.mozilla.org/MPL/2.0/). + 2. Configuration options for the chat toolbar have changed. Please refer to the [relevant documentation](http://devbox:8890/docs/html/configuration.html#visible-toolbar-buttons). + 3. This release has reduced support for IE8 (some features won't work). + 4. Events have been renamed to remove "on" prefix (sorry for any inconvenience). + +- No initial HTML markup is now needed in the document body for converse.js to work. [jcbrand] +- All date handling is now done with moment.js. [jcbrand] +- Add a new toolbar button for clearing chat messages. [jcbrand] +- Chat boxes and rooms can now be resized vertically. [jcbrand] +- Upgraded dependencies to their latest versions. [jcbrand] +- Add new configuration setting [forwarded_messages](https://conversejs.org/docs/html/configuration.html#forwarded-messages). + Message forwarding was before a default behavior but is now optional (and disabled by default). [jcbrand] +- Newly opened chat boxes always appear immediately left of the controlbox. [jcbrand] +- #71 Chat boxes and rooms can be minimized. [jcbrand] +- #83 Roster contacts can be shown according to their groups. [jcbrand] + Note: Converse.js can show users under groups if you have assigned them + already via another client or server configuration. There is not yet a way + to assign contacts to groups from within converse.js itself. +- #123 Show converse.js in the resource assigned to a user. [jcbrand] +- #130 Fixed bootstrap conflicts. [jcbrand] +- #132 Support for [XEP-0280: Message Carbons](https://xmpp.org/extensions/xep-0280.html). + Configured via [message_carbons](https://conversejs.org/docs/html/configuration.html#message-carbons) [hejazee] +- #176 Add support for caching in sessionStorage as opposed to localStorage. [jcbrand] +- #180 RID and SID undefined [g8g3] +- #191 No messages history [heban] +- #192 Error: xhr_user_search_url is not defined. [jcbrand] +- #195 Chinese translations. [lancelothuxi] +- #196 [Safari v7.0.5] TypeError: Attempted to assign to readonly property. [g8g3] +- #199 Improved Spanish translations [chilicuil] +- #201 Add zh-locale to fix build task [schoetty] + +## 0.7.4 (2014-03-05) + +**note:** +*This release contains an important security fix. Thanks to Renaud Dubourguais from [Synacktiv](http://synacktiv.com) for reporting the vulnerability.* + +- #125 Bugfix: crypto dependencies loaded in wrong order [jcbrand] +- Bugfix: action messages (i.e. /me) didn't work in OTR mode. [jcbrand] +- Security fix: Ensure that message URLs are properly encoded. [jcbrand] + +## 0.7.3 (2014-02-23) + +- #93 Add API methods exposing the RID and SID values. Can be disabled. [jcbrand] +- #102 Option to enable OTR by default. [Aupajo] +- #103 Option to display a call button in the chatbox toolbar, to allow third-party libraries to provide a calling feature. [Aupajo] +- #108 Japanese Translations [mako09] +- #111 OTR not working when using converse.js with prebinding. [jseidl, jcbrand] +- #114, #124 Hewbrew Translations [GreenLunar] +- #115 Indonesian Translations [priyadi] + +## 0.7.2 (2013-12-18) + +**note** +*This release contains an important security fix. Thanks to hejsan for reporting the vulnerability.* + +- #48 Add event emitter support and emit events. [jcbrand] +- #97 Wrong number of online contacts shown with config option `show_only_online_users`. [jcbrand] +- #100 Make the fetching of vCards optional (enabled by default). [jcbrand] +- Sanitize message text to avoid Javascript injection attacks. [jcbrand] + +## 0.7.1 (2013-11-17) + +- Don't load OTR crypto if the browser doesn't have a CSRNG [jcbrand] +- Don't break when crypto libraries aren't defined. [jcbrand] +- Check if canvas is supported before trying to render the user avatar [jcbrand] +- Use newest strophe.muc plugin. Fixes #85 [jcbrand] + +**note:** +If you are using the development libraries, you'll need to run ``bower update`` +to fetch the newest strophe.muc.plugin (for bugfix of #85). + +This release contains 3 different builds: +- converse.min.js +- converse-no-otr.min.js (Without OTR encryption) +- converse-no-locales-no-otr.min.js (Without OTR encryption or any translations) + +## 0.7.0 (2013-11-13) + +### Important: + +This release includes support for [Off-the-record encryption](https://otr.cypherpunks.ca). +For this to work, your browser needs a CSPRNG (Cryptographically secure pseudorandom number generator). + +Internet Explorer of all versions doesn't have one at all, neither does older versions of Firefox. + +If you need to support older browsers, please download the latest release from the 0.6 bran + +#### Features: + +- Add a toolbar to the chat boxes [jcbrand] +- Add support for OTR (off-the-record) encryption [jcbrand] +- Add support for smileys [jcbrand] +- Simplified boilerplate markup [jcbrand] +- New configuration settings, `xhr_custom_status_url` and `xhr_user_search_url` [jcbrand] + +**note:** +*This release introduces a backward incompatible change. The boilerplate +HTML needed in your webpage for converse.js to work has been reduced to a +single div: `
`* + +#### Bugfixes: + +- #58 Contact's name gets replaced with their JID [jcbrand] +- #81 Requesting contacts appear as pending contacts [jcbrand] + +## 0.6.6 (2013-10-16) + +- Bugfix: Presence stanza must be sent out after roster has been initialized [jcbrand] +- Bugfix: Don't reconnect while still disconnecting, causes endless authentication loops. [jcbrand] +- Dutch translation [maartenkling] + +## 0.6.5 (2013-10-08) + +- Fetch vCards asynchronously once a roster contact is added [jcbrand] +- Hungarian translation [w3host] +- Russian translation [bkocherov] +- Update CSS to avoid clash with bootstrap [seocam] +- New config option `allow_muc` toggles multi-user chat (MUC) [jcbrand] +- New config option `allow_contact_requests` toggles user adding [jcbrand] +- New config option `show_only_online_users` [jcbrand] + +## 0.6.4 (2013-09-15) + +- Add icon for the unavailable chat state. [jcbrand] +- Chat state descriptions weren't translation aware. [jcbrand] +- Clear messages from localStorage when user types "/clear". [jcbrand] +- The 'xa' chat state wasn't being handled properly. [jcbrand] +- Updated pt-BR translations [seocam] +- Updated af and de translations [jcbrand] + +## 0.6.3 (2013-09-12) + +*NB: This release contains an important security fix. Please don't use older +versions of the 0.6 branch.* + +- French translations. [tdesvenain] +- Bugfix: Messages were stored against buddy JID and not own JID. [jcbrand] + +## 0.6.2 (2013-08-29) + +- Bugfix. The remove icon wasn't appearing in the contacts roster. [jcbrand] +- Bugfix. With auto_subscribe=True, the "Pending Contacts" header didn't disappear + after a new user was accepted. [jcbrand] + +## 0.6.1 (2013-08-28) + +- IE9 and IE8 CSS fixes. [jcbrand] +- Bugfix: Pencil icon not visible (for setting status update). [jcbrand] +- Bugfix: RID, JID and SID initialization values were being ignored. [jcbrand] +- Bugfix: Fall back to English if a non-existing locale was specified. [jcbrand] + +## 0.6.0 (2013-08-26) + +- #39 Documentation for minifying JS is wrong. [jcbrand] +- #41 prebind and show_controlbox_by_default true fails. [jcbrand] +- With prebinding, attaching to the connection now happens inside Converse and + not as a separate step after initialization. [jcbrand] +- Register presence and message handlers before fetching the roster. Otherwise + some presence notifications might be missed. [jcbrand] +- Add a debug option (logs to the browser console). [jcbrand] +- Use font icons from http://icomoon.io [jcbrand] +- Added a static mockup to aid CSS/design process. [jcbrand] +- Save language codes with hyphens. Thanks to @seocam. [jcbrand] +- The combined and minified JS file now uses almond and not require.js. [jcbrand] + +## 0.5.2 (2013-08-05) + +- Important security update. Don't expose the Strophe connection object globally. [jcbrand] + +## 0.5.1 (2013-08-04) + +- #13, #14: Messages sent between to GTalk accounts weren't being received. [jcbrand] +- #32: Default status was offline when user didn't have contacts. [jcbrand] +- Attach panels to the DOM upon initialize. [jcbrand] + +## 0.5.0 (2013-07-30) + +- #09 Remove dependency on AMD/require.js [jcbrand] +- #22 Fixed compare operator in strophe.muc [sonata82] +- #23 Add Italian translations [ctrlaltca] +- #24 Add Spanish translations [macagua] +- #25 Using span with css instead of img [matheus-morfi] +- #26 Only the first minute digit shown in chatbox. [jcbrand] +- #28 Add Brazilian Portuguese translations [matheus-morfi] +- Use Bower to manage 3rd party dependencies. [jcbrand] + +## 0.4.0 (2013-06-03) + +- CSS tweaks: fixed overflowing text in status message and chat rooms list. [jcbrand] +- Bugfix: Couldn't join chat room when clicking from a list of rooms. [jcbrand] +- Add better support for kicking or banning users from chat rooms. [jcbrand] +- Fixed alignment of chat messages in Firefox. [jcbrand] +- More intelligent fetching of vCards. [jcbrand] +- Fixed a race condition bug. Make sure that the roster is populated before sending initial presence. [jcbrand] +- Reconnect automatically when the connection drops. [jcbrand] +- Add support for internationalization. [jcbrand] + +## 0.3.0 (2013-05-21) + +- Add vCard support [jcbrand] +- Remember custom status messages upon reload. [jcbrand] +- Remove jquery-ui dependency. [jcbrand] +- Use backbone.localStorage to store the contacts roster, open chatboxes and chat messages. [jcbrand] +- Fixed user status handling, which wasn't 100% according to the spec. [jcbrand] +- Separate messages according to day in chats. [jcbrand] +- Add support for specifying the BOSH bind URL as configuration setting. [jcbrand] +- #8 Improve the message counter to only increment when the window is not focused [witekdev] +- Make fetching of list of chat rooms on a server a configuration option. [jcbrand] +- Use service discovery to show all available features on a room. [jcbrand] +- Multi-user chat rooms are now configurable. [jcbrand] + +## 0.2.0 (2013-03-28) + +- Performance enhancements and general script cleanup [ichim-david] +- Add "Connecting to chat..." info [alecghica] +- Various smaller improvements and bugfixes [jcbrand] + +## 0.1.0 (2012-06-12) + +- Created [jcbrand] diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..3a93163 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,12 @@ +/** Converse.js + * + * An XMPP chat client that runs in the browser. + * + * Version: 7.0.2 + * + * Copyright: JC Brand 2013-2018 + * Except for 3rd party dependencies. + * Please refer to the unminified version of this file for details. + * + * You can download it at: https://github.com/conversejs/converse.js/releases + */ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..14e2f77 --- /dev/null +++ b/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/dist/converse.css b/dist/converse.css new file mode 100644 index 0000000..927d84d --- /dev/null +++ b/dist/converse.css @@ -0,0 +1,9 @@ +/*! + * Converse.js (Web-based XMPP instant messaging client) + * https://conversejs.org + * + * Copyright (c) 2013-2018, JC Brand + * Licensed under the Mozilla Public License + */#conversejs :root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}#conversejs *,#conversejs ::after,#conversejs ::before{box-sizing:border-box}#conversejs html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}#conversejs article,#conversejs aside,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs header,#conversejs hgroup,#conversejs main,#conversejs nav,#conversejs section{display:block}#conversejs body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}#conversejs [tabindex="-1"]:focus:not(:focus-visible){outline:0!important}#conversejs hr{box-sizing:content-box;height:0;overflow:visible}#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6{margin-top:0;margin-bottom:.5rem}#conversejs p{margin-top:0;margin-bottom:1rem}#conversejs abbr[data-original-title],#conversejs abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}#conversejs address{margin-bottom:1rem;font-style:normal;line-height:inherit}#conversejs dl,#conversejs ol,#conversejs ul{margin-top:0;margin-bottom:1rem}#conversejs ol ol,#conversejs ol ul,#conversejs ul ol,#conversejs ul ul{margin-bottom:0}#conversejs dt{font-weight:700}#conversejs dd{margin-bottom:.5rem;margin-left:0}#conversejs blockquote{margin:0 0 1rem}#conversejs b,#conversejs strong{font-weight:bolder}#conversejs small{font-size:80%}#conversejs sub,#conversejs sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}#conversejs sub{bottom:-.25em}#conversejs sup{top:-.5em}#conversejs a{color:#007bff;text-decoration:none;background-color:transparent}#conversejs a:hover{color:#0056b3;text-decoration:underline}#conversejs a:not([href]){color:inherit;text-decoration:none}#conversejs a:not([href]):hover{color:inherit;text-decoration:none}#conversejs code,#conversejs kbd,#conversejs pre,#conversejs samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}#conversejs pre{margin-top:0;margin-bottom:1rem;overflow:auto}#conversejs figure{margin:0 0 1rem}#conversejs img{vertical-align:middle;border-style:none}#conversejs svg{overflow:hidden;vertical-align:middle}#conversejs table{border-collapse:collapse}#conversejs caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}#conversejs th{text-align:inherit}#conversejs label{display:inline-block;margin-bottom:.5rem}#conversejs button{border-radius:0}#conversejs button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}#conversejs button,#conversejs input,#conversejs optgroup,#conversejs select,#conversejs textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}#conversejs button,#conversejs input{overflow:visible}#conversejs button,#conversejs select{text-transform:none}#conversejs select{word-wrap:normal}#conversejs [type=button],#conversejs [type=reset],#conversejs [type=submit],#conversejs button{-webkit-appearance:button}#conversejs [type=button]:not(:disabled),#conversejs [type=reset]:not(:disabled),#conversejs [type=submit]:not(:disabled),#conversejs button:not(:disabled){cursor:pointer}#conversejs [type=button]::-moz-focus-inner,#conversejs [type=reset]::-moz-focus-inner,#conversejs [type=submit]::-moz-focus-inner,#conversejs button::-moz-focus-inner{padding:0;border-style:none}#conversejs input[type=checkbox],#conversejs input[type=radio]{box-sizing:border-box;padding:0}#conversejs input[type=date],#conversejs input[type=datetime-local],#conversejs input[type=month],#conversejs input[type=time]{-webkit-appearance:listbox}#conversejs textarea{overflow:auto;resize:vertical}#conversejs fieldset{min-width:0;padding:0;margin:0;border:0}#conversejs legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}#conversejs progress{vertical-align:baseline}#conversejs [type=number]::-webkit-inner-spin-button,#conversejs [type=number]::-webkit-outer-spin-button{height:auto}#conversejs [type=search]{outline-offset:-2px;-webkit-appearance:none}#conversejs [type=search]::-webkit-search-decoration{-webkit-appearance:none}#conversejs ::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}#conversejs output{display:inline-block}#conversejs summary{display:list-item;cursor:pointer}#conversejs template{display:none}#conversejs [hidden]{display:none!important}#conversejs .h1,#conversejs .h2,#conversejs .h3,#conversejs .h4,#conversejs .h5,#conversejs .h6,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}#conversejs .h1,#conversejs h1{font-size:2.5rem}#conversejs .h2,#conversejs h2{font-size:2rem}#conversejs .h3,#conversejs h3{font-size:1.75rem}#conversejs .h4,#conversejs h4{font-size:1.5rem}#conversejs .h5,#conversejs h5{font-size:1.25rem}#conversejs .h6,#conversejs h6{font-size:1rem}#conversejs .lead{font-size:1.25rem;font-weight:300}#conversejs .display-1{font-size:6rem;font-weight:300;line-height:1.2}#conversejs .display-2{font-size:5.5rem;font-weight:300;line-height:1.2}#conversejs .display-3{font-size:4.5rem;font-weight:300;line-height:1.2}#conversejs .display-4{font-size:3.5rem;font-weight:300;line-height:1.2}#conversejs hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}#conversejs .small,#conversejs small{font-size:80%;font-weight:400}#conversejs .mark,#conversejs mark{padding:.2em;background-color:#fcf8e3}#conversejs .list-unstyled{padding-left:0;list-style:none}#conversejs .list-inline{padding-left:0;list-style:none}#conversejs .list-inline-item{display:inline-block}#conversejs .list-inline-item:not(:last-child){margin-right:.5rem}#conversejs .initialism{font-size:90%;text-transform:uppercase}#conversejs .blockquote{margin-bottom:1rem;font-size:1.25rem}#conversejs .blockquote-footer{display:block;font-size:80%;color:#6c757d}#conversejs .blockquote-footer::before{content:"\2014\00A0"}#conversejs .img-fluid{max-width:100%;height:auto}#conversejs .img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}#conversejs .figure{display:inline-block}#conversejs .figure-img{margin-bottom:.5rem;line-height:1}#conversejs .figure-caption{font-size:90%;color:#6c757d}#conversejs .container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){#conversejs .container{max-width:540px}}@media (min-width:768px){#conversejs .container{max-width:720px}}@media (min-width:992px){#conversejs .container{max-width:960px}}@media (min-width:1200px){#conversejs .container{max-width:1140px}}#conversejs .container-fluid,#conversejs .container-lg,#conversejs .container-md,#conversejs .container-sm,#conversejs .container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){#conversejs .container,#conversejs .container-sm{max-width:540px}}@media (min-width:768px){#conversejs .container,#conversejs .container-md,#conversejs .container-sm{max-width:720px}}@media (min-width:992px){#conversejs .container,#conversejs .container-lg,#conversejs .container-md,#conversejs .container-sm{max-width:960px}}@media (min-width:1200px){#conversejs .container,#conversejs .container-lg,#conversejs .container-md,#conversejs .container-sm,#conversejs .container-xl{max-width:1140px}}#conversejs .row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}#conversejs .no-gutters{margin-right:0;margin-left:0}#conversejs .no-gutters>.col,#conversejs .no-gutters>[class*=col-]{padding-right:0;padding-left:0}#conversejs .col,#conversejs .col-1,#conversejs .col-10,#conversejs .col-11,#conversejs .col-12,#conversejs .col-2,#conversejs .col-3,#conversejs .col-4,#conversejs .col-5,#conversejs .col-6,#conversejs .col-7,#conversejs .col-8,#conversejs .col-9,#conversejs .col-auto,#conversejs .col-lg,#conversejs .col-lg-1,#conversejs .col-lg-10,#conversejs .col-lg-11,#conversejs .col-lg-12,#conversejs .col-lg-2,#conversejs .col-lg-3,#conversejs .col-lg-4,#conversejs .col-lg-5,#conversejs .col-lg-6,#conversejs .col-lg-7,#conversejs .col-lg-8,#conversejs .col-lg-9,#conversejs .col-lg-auto,#conversejs .col-md,#conversejs .col-md-1,#conversejs .col-md-10,#conversejs .col-md-11,#conversejs .col-md-12,#conversejs .col-md-2,#conversejs .col-md-3,#conversejs .col-md-4,#conversejs .col-md-5,#conversejs .col-md-6,#conversejs .col-md-7,#conversejs .col-md-8,#conversejs .col-md-9,#conversejs .col-md-auto,#conversejs .col-sm,#conversejs .col-sm-1,#conversejs .col-sm-10,#conversejs .col-sm-11,#conversejs .col-sm-12,#conversejs .col-sm-2,#conversejs .col-sm-3,#conversejs .col-sm-4,#conversejs .col-sm-5,#conversejs .col-sm-6,#conversejs .col-sm-7,#conversejs .col-sm-8,#conversejs .col-sm-9,#conversejs .col-sm-auto,#conversejs .col-xl,#conversejs .col-xl-1,#conversejs .col-xl-10,#conversejs .col-xl-11,#conversejs .col-xl-12,#conversejs .col-xl-2,#conversejs .col-xl-3,#conversejs .col-xl-4,#conversejs .col-xl-5,#conversejs .col-xl-6,#conversejs .col-xl-7,#conversejs .col-xl-8,#conversejs .col-xl-9,#conversejs .col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}#conversejs .col{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-3{flex:0 0 25%;max-width:25%}#conversejs .col-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-6{flex:0 0 50%;max-width:50%}#conversejs .col-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-9{flex:0 0 75%;max-width:75%}#conversejs .col-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-12{flex:0 0 100%;max-width:100%}#conversejs .order-first{order:-1}#conversejs .order-last{order:13}#conversejs .order-0{order:0}#conversejs .order-1{order:1}#conversejs .order-2{order:2}#conversejs .order-3{order:3}#conversejs .order-4{order:4}#conversejs .order-5{order:5}#conversejs .order-6{order:6}#conversejs .order-7{order:7}#conversejs .order-8{order:8}#conversejs .order-9{order:9}#conversejs .order-10{order:10}#conversejs .order-11{order:11}#conversejs .order-12{order:12}#conversejs .offset-1{margin-left:8.33333%}#conversejs .offset-2{margin-left:16.66667%}#conversejs .offset-3{margin-left:25%}#conversejs .offset-4{margin-left:33.33333%}#conversejs .offset-5{margin-left:41.66667%}#conversejs .offset-6{margin-left:50%}#conversejs .offset-7{margin-left:58.33333%}#conversejs .offset-8{margin-left:66.66667%}#conversejs .offset-9{margin-left:75%}#conversejs .offset-10{margin-left:83.33333%}#conversejs .offset-11{margin-left:91.66667%}@media (min-width:576px){#conversejs .col-sm{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-sm-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-sm-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-sm-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-sm-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-sm-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-sm-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-sm-3{flex:0 0 25%;max-width:25%}#conversejs .col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-sm-6{flex:0 0 50%;max-width:50%}#conversejs .col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-sm-9{flex:0 0 75%;max-width:75%}#conversejs .col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-sm-12{flex:0 0 100%;max-width:100%}#conversejs .order-sm-first{order:-1}#conversejs .order-sm-last{order:13}#conversejs .order-sm-0{order:0}#conversejs .order-sm-1{order:1}#conversejs .order-sm-2{order:2}#conversejs .order-sm-3{order:3}#conversejs .order-sm-4{order:4}#conversejs .order-sm-5{order:5}#conversejs .order-sm-6{order:6}#conversejs .order-sm-7{order:7}#conversejs .order-sm-8{order:8}#conversejs .order-sm-9{order:9}#conversejs .order-sm-10{order:10}#conversejs .order-sm-11{order:11}#conversejs .order-sm-12{order:12}#conversejs .offset-sm-0{margin-left:0}#conversejs .offset-sm-1{margin-left:8.33333%}#conversejs .offset-sm-2{margin-left:16.66667%}#conversejs .offset-sm-3{margin-left:25%}#conversejs .offset-sm-4{margin-left:33.33333%}#conversejs .offset-sm-5{margin-left:41.66667%}#conversejs .offset-sm-6{margin-left:50%}#conversejs .offset-sm-7{margin-left:58.33333%}#conversejs .offset-sm-8{margin-left:66.66667%}#conversejs .offset-sm-9{margin-left:75%}#conversejs .offset-sm-10{margin-left:83.33333%}#conversejs .offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){#conversejs .col-md{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-md-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-md-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-md-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-md-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-md-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-md-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-md-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-md-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-md-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-md-3{flex:0 0 25%;max-width:25%}#conversejs .col-md-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-md-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-md-6{flex:0 0 50%;max-width:50%}#conversejs .col-md-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-md-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-md-9{flex:0 0 75%;max-width:75%}#conversejs .col-md-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-md-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-md-12{flex:0 0 100%;max-width:100%}#conversejs .order-md-first{order:-1}#conversejs .order-md-last{order:13}#conversejs .order-md-0{order:0}#conversejs .order-md-1{order:1}#conversejs .order-md-2{order:2}#conversejs .order-md-3{order:3}#conversejs .order-md-4{order:4}#conversejs .order-md-5{order:5}#conversejs .order-md-6{order:6}#conversejs .order-md-7{order:7}#conversejs .order-md-8{order:8}#conversejs .order-md-9{order:9}#conversejs .order-md-10{order:10}#conversejs .order-md-11{order:11}#conversejs .order-md-12{order:12}#conversejs .offset-md-0{margin-left:0}#conversejs .offset-md-1{margin-left:8.33333%}#conversejs .offset-md-2{margin-left:16.66667%}#conversejs .offset-md-3{margin-left:25%}#conversejs .offset-md-4{margin-left:33.33333%}#conversejs .offset-md-5{margin-left:41.66667%}#conversejs .offset-md-6{margin-left:50%}#conversejs .offset-md-7{margin-left:58.33333%}#conversejs .offset-md-8{margin-left:66.66667%}#conversejs .offset-md-9{margin-left:75%}#conversejs .offset-md-10{margin-left:83.33333%}#conversejs .offset-md-11{margin-left:91.66667%}}@media (min-width:992px){#conversejs .col-lg{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-lg-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-lg-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-lg-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-lg-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-lg-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-lg-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-lg-3{flex:0 0 25%;max-width:25%}#conversejs .col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-lg-6{flex:0 0 50%;max-width:50%}#conversejs .col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-lg-9{flex:0 0 75%;max-width:75%}#conversejs .col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-lg-12{flex:0 0 100%;max-width:100%}#conversejs .order-lg-first{order:-1}#conversejs .order-lg-last{order:13}#conversejs .order-lg-0{order:0}#conversejs .order-lg-1{order:1}#conversejs .order-lg-2{order:2}#conversejs .order-lg-3{order:3}#conversejs .order-lg-4{order:4}#conversejs .order-lg-5{order:5}#conversejs .order-lg-6{order:6}#conversejs .order-lg-7{order:7}#conversejs .order-lg-8{order:8}#conversejs .order-lg-9{order:9}#conversejs .order-lg-10{order:10}#conversejs .order-lg-11{order:11}#conversejs .order-lg-12{order:12}#conversejs .offset-lg-0{margin-left:0}#conversejs .offset-lg-1{margin-left:8.33333%}#conversejs .offset-lg-2{margin-left:16.66667%}#conversejs .offset-lg-3{margin-left:25%}#conversejs .offset-lg-4{margin-left:33.33333%}#conversejs .offset-lg-5{margin-left:41.66667%}#conversejs .offset-lg-6{margin-left:50%}#conversejs .offset-lg-7{margin-left:58.33333%}#conversejs .offset-lg-8{margin-left:66.66667%}#conversejs .offset-lg-9{margin-left:75%}#conversejs .offset-lg-10{margin-left:83.33333%}#conversejs .offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){#conversejs .col-xl{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-xl-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-xl-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-xl-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-xl-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-xl-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-xl-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-xl-3{flex:0 0 25%;max-width:25%}#conversejs .col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-xl-6{flex:0 0 50%;max-width:50%}#conversejs .col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-xl-9{flex:0 0 75%;max-width:75%}#conversejs .col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-xl-12{flex:0 0 100%;max-width:100%}#conversejs .order-xl-first{order:-1}#conversejs .order-xl-last{order:13}#conversejs .order-xl-0{order:0}#conversejs .order-xl-1{order:1}#conversejs .order-xl-2{order:2}#conversejs .order-xl-3{order:3}#conversejs .order-xl-4{order:4}#conversejs .order-xl-5{order:5}#conversejs .order-xl-6{order:6}#conversejs .order-xl-7{order:7}#conversejs .order-xl-8{order:8}#conversejs .order-xl-9{order:9}#conversejs .order-xl-10{order:10}#conversejs .order-xl-11{order:11}#conversejs .order-xl-12{order:12}#conversejs .offset-xl-0{margin-left:0}#conversejs .offset-xl-1{margin-left:8.33333%}#conversejs .offset-xl-2{margin-left:16.66667%}#conversejs .offset-xl-3{margin-left:25%}#conversejs .offset-xl-4{margin-left:33.33333%}#conversejs .offset-xl-5{margin-left:41.66667%}#conversejs .offset-xl-6{margin-left:50%}#conversejs .offset-xl-7{margin-left:58.33333%}#conversejs .offset-xl-8{margin-left:66.66667%}#conversejs .offset-xl-9{margin-left:75%}#conversejs .offset-xl-10{margin-left:83.33333%}#conversejs .offset-xl-11{margin-left:91.66667%}}#conversejs .form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .form-control{transition:none}}#conversejs .form-control::-ms-expand{background-color:transparent;border:0}#conversejs .form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}#conversejs .form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .form-control::-moz-placeholder{color:#6c757d;opacity:1}#conversejs .form-control:-ms-input-placeholder{color:#6c757d;opacity:1}#conversejs .form-control::-ms-input-placeholder{color:#6c757d;opacity:1}#conversejs .form-control::placeholder{color:#6c757d;opacity:1}#conversejs .form-control:disabled,#conversejs .form-control[readonly]{background-color:#e9ecef;opacity:1}#conversejs select.form-control:focus::-ms-value{color:#495057;background-color:#fff}#conversejs .form-control-file,#conversejs .form-control-range{display:block;width:100%}#conversejs .col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}#conversejs .col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}#conversejs .col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}#conversejs .form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}#conversejs .form-control-plaintext.form-control-lg,#conversejs .form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}#conversejs .form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}#conversejs .form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}#conversejs select.form-control[multiple],#conversejs select.form-control[size]{height:auto}#conversejs textarea.form-control{height:auto}#conversejs .form-group{margin-bottom:1rem}#conversejs .form-text{display:block;margin-top:.25rem}#conversejs .form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}#conversejs .form-row>.col,#conversejs .form-row>[class*=col-]{padding-right:5px;padding-left:5px}#conversejs .form-check{position:relative;display:block;padding-left:1.25rem}#conversejs .form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}#conversejs .form-check-input:disabled~.form-check-label,#conversejs .form-check-input[disabled]~.form-check-label{color:#6c757d}#conversejs .form-check-label{margin-bottom:0}#conversejs .form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}#conversejs .form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}#conversejs .valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}#conversejs .valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}#conversejs.is-valid~.valid-feedback,#conversejs.is-valid~.valid-tooltip,.was-validated #conversejs:valid~.valid-feedback,.was-validated #conversejs:valid~.valid-tooltip{display:block}#conversejs .form-control.is-valid,.was-validated #conversejs .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .form-control.is-valid:focus,.was-validated #conversejs .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs textarea.form-control.is-valid,.was-validated #conversejs textarea.form-control:valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}#conversejs .custom-select.is-valid,.was-validated #conversejs .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .custom-select.is-valid:focus,.was-validated #conversejs .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs .form-check-input.is-valid~.form-check-label,.was-validated #conversejs .form-check-input:valid~.form-check-label{color:#28a745}#conversejs .form-check-input.is-valid~.valid-feedback,#conversejs .form-check-input.is-valid~.valid-tooltip,.was-validated #conversejs .form-check-input:valid~.valid-feedback,.was-validated #conversejs .form-check-input:valid~.valid-tooltip{display:block}#conversejs .custom-control-input.is-valid~.custom-control-label,.was-validated #conversejs .custom-control-input:valid~.custom-control-label{color:#28a745}#conversejs .custom-control-input.is-valid~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}#conversejs .custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}#conversejs .custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}#conversejs .custom-file-input.is-valid~.custom-file-label,.was-validated #conversejs .custom-file-input:valid~.custom-file-label{border-color:#28a745}#conversejs .custom-file-input.is-valid:focus~.custom-file-label,.was-validated #conversejs .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs .invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}#conversejs .invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}#conversejs.is-invalid~.invalid-feedback,#conversejs.is-invalid~.invalid-tooltip,.was-validated #conversejs:invalid~.invalid-feedback,.was-validated #conversejs:invalid~.invalid-tooltip{display:block}#conversejs .form-control.is-invalid,.was-validated #conversejs .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .form-control.is-invalid:focus,.was-validated #conversejs .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs textarea.form-control.is-invalid,.was-validated #conversejs textarea.form-control:invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}#conversejs .custom-select.is-invalid,.was-validated #conversejs .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .custom-select.is-invalid:focus,.was-validated #conversejs .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs .form-check-input.is-invalid~.form-check-label,.was-validated #conversejs .form-check-input:invalid~.form-check-label{color:#dc3545}#conversejs .form-check-input.is-invalid~.invalid-feedback,#conversejs .form-check-input.is-invalid~.invalid-tooltip,.was-validated #conversejs .form-check-input:invalid~.invalid-feedback,.was-validated #conversejs .form-check-input:invalid~.invalid-tooltip{display:block}#conversejs .custom-control-input.is-invalid~.custom-control-label,.was-validated #conversejs .custom-control-input:invalid~.custom-control-label{color:#dc3545}#conversejs .custom-control-input.is-invalid~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}#conversejs .custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}#conversejs .custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}#conversejs .custom-file-input.is-invalid~.custom-file-label,.was-validated #conversejs .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}#conversejs .custom-file-input.is-invalid:focus~.custom-file-label,.was-validated #conversejs .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs .form-inline{display:flex;flex-flow:row wrap;align-items:center}#conversejs .form-inline .form-check{width:100%}@media (min-width:576px){#conversejs .form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}#conversejs .form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}#conversejs .form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}#conversejs .form-inline .form-control-plaintext{display:inline-block}#conversejs .form-inline .custom-select,#conversejs .form-inline .input-group{width:auto}#conversejs .form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}#conversejs .form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}#conversejs .form-inline .custom-control{align-items:center;justify-content:center}#conversejs .form-inline .custom-control-label{margin-bottom:0}}#conversejs .btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .btn{transition:none}}#conversejs .btn:hover{color:#212529;text-decoration:none}#conversejs .btn.focus,#conversejs .btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .btn.disabled,#conversejs .btn:disabled{opacity:.65}#conversejs a.btn.disabled,#conversejs fieldset:disabled a.btn{pointer-events:none}#conversejs .btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}#conversejs .btn-primary.focus,#conversejs .btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}#conversejs .btn-primary.disabled,#conversejs .btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-primary:not(:disabled):not(.disabled).active,#conversejs .btn-primary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}#conversejs .btn-primary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-primary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}#conversejs .btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}#conversejs .btn-secondary.focus,#conversejs .btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}#conversejs .btn-secondary.disabled,#conversejs .btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-secondary:not(:disabled):not(.disabled).active,#conversejs .btn-secondary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}#conversejs .btn-secondary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-secondary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}#conversejs .btn-success{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}#conversejs .btn-success.focus,#conversejs .btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}#conversejs .btn-success.disabled,#conversejs .btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-success:not(:disabled):not(.disabled).active,#conversejs .btn-success:not(:disabled):not(.disabled):active,.show>#conversejs .btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}#conversejs .btn-success:not(:disabled):not(.disabled).active:focus,#conversejs .btn-success:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}#conversejs .btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}#conversejs .btn-info.focus,#conversejs .btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}#conversejs .btn-info.disabled,#conversejs .btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-info:not(:disabled):not(.disabled).active,#conversejs .btn-info:not(:disabled):not(.disabled):active,.show>#conversejs .btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}#conversejs .btn-info:not(:disabled):not(.disabled).active:focus,#conversejs .btn-info:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}#conversejs .btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}#conversejs .btn-warning.focus,#conversejs .btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}#conversejs .btn-warning.disabled,#conversejs .btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-warning:not(:disabled):not(.disabled).active,#conversejs .btn-warning:not(:disabled):not(.disabled):active,.show>#conversejs .btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}#conversejs .btn-warning:not(:disabled):not(.disabled).active:focus,#conversejs .btn-warning:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}#conversejs .btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}#conversejs .btn-danger.focus,#conversejs .btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}#conversejs .btn-danger.disabled,#conversejs .btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-danger:not(:disabled):not(.disabled).active,#conversejs .btn-danger:not(:disabled):not(.disabled):active,.show>#conversejs .btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}#conversejs .btn-danger:not(:disabled):not(.disabled).active:focus,#conversejs .btn-danger:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}#conversejs .btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}#conversejs .btn-light.focus,#conversejs .btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}#conversejs .btn-light.disabled,#conversejs .btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-light:not(:disabled):not(.disabled).active,#conversejs .btn-light:not(:disabled):not(.disabled):active,.show>#conversejs .btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}#conversejs .btn-light:not(:disabled):not(.disabled).active:focus,#conversejs .btn-light:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}#conversejs .btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}#conversejs .btn-dark.focus,#conversejs .btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}#conversejs .btn-dark.disabled,#conversejs .btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-dark:not(:disabled):not(.disabled).active,#conversejs .btn-dark:not(:disabled):not(.disabled):active,.show>#conversejs .btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}#conversejs .btn-dark:not(:disabled):not(.disabled).active:focus,#conversejs .btn-dark:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}#conversejs .btn-outline-primary{color:#007bff;border-color:#007bff}#conversejs .btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-outline-primary.focus,#conversejs .btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}#conversejs .btn-outline-primary.disabled,#conversejs .btn-outline-primary:disabled{color:#007bff;background-color:transparent}#conversejs .btn-outline-primary:not(:disabled):not(.disabled).active,#conversejs .btn-outline-primary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-outline-primary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}#conversejs .btn-outline-secondary{color:#6c757d;border-color:#6c757d}#conversejs .btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-outline-secondary.focus,#conversejs .btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}#conversejs .btn-outline-secondary.disabled,#conversejs .btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}#conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active,#conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}#conversejs .btn-outline-success{color:#28a745;border-color:#28a745}#conversejs .btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-outline-success.focus,#conversejs .btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}#conversejs .btn-outline-success.disabled,#conversejs .btn-outline-success:disabled{color:#28a745;background-color:transparent}#conversejs .btn-outline-success:not(:disabled):not(.disabled).active,#conversejs .btn-outline-success:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-outline-success:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}#conversejs .btn-outline-info{color:#17a2b8;border-color:#17a2b8}#conversejs .btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-outline-info.focus,#conversejs .btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}#conversejs .btn-outline-info.disabled,#conversejs .btn-outline-info:disabled{color:#17a2b8;background-color:transparent}#conversejs .btn-outline-info:not(:disabled):not(.disabled).active,#conversejs .btn-outline-info:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-outline-info:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}#conversejs .btn-outline-warning{color:#ffc107;border-color:#ffc107}#conversejs .btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-outline-warning.focus,#conversejs .btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}#conversejs .btn-outline-warning.disabled,#conversejs .btn-outline-warning:disabled{color:#ffc107;background-color:transparent}#conversejs .btn-outline-warning:not(:disabled):not(.disabled).active,#conversejs .btn-outline-warning:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-outline-warning:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}#conversejs .btn-outline-danger{color:#dc3545;border-color:#dc3545}#conversejs .btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-outline-danger.focus,#conversejs .btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}#conversejs .btn-outline-danger.disabled,#conversejs .btn-outline-danger:disabled{color:#dc3545;background-color:transparent}#conversejs .btn-outline-danger:not(:disabled):not(.disabled).active,#conversejs .btn-outline-danger:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-outline-danger:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}#conversejs .btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-outline-light.focus,#conversejs .btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}#conversejs .btn-outline-light.disabled,#conversejs .btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}#conversejs .btn-outline-light:not(:disabled):not(.disabled).active,#conversejs .btn-outline-light:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-outline-light:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}#conversejs .btn-outline-dark{color:#343a40;border-color:#343a40}#conversejs .btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-outline-dark.focus,#conversejs .btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}#conversejs .btn-outline-dark.disabled,#conversejs .btn-outline-dark:disabled{color:#343a40;background-color:transparent}#conversejs .btn-outline-dark:not(:disabled):not(.disabled).active,#conversejs .btn-outline-dark:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-outline-dark:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}#conversejs .btn-link{font-weight:400;color:#007bff;text-decoration:none}#conversejs .btn-link:hover{color:#0056b3;text-decoration:underline}#conversejs .btn-link.focus,#conversejs .btn-link:focus{text-decoration:underline;box-shadow:none}#conversejs .btn-link.disabled,#conversejs .btn-link:disabled{color:#6c757d;pointer-events:none}#conversejs .btn-group-lg>.btn,#conversejs .btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}#conversejs .btn-group-sm>.btn,#conversejs .btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}#conversejs .btn-block{display:block;width:100%}#conversejs .btn-block+.btn-block{margin-top:.5rem}#conversejs input[type=button].btn-block,#conversejs input[type=reset].btn-block,#conversejs input[type=submit].btn-block{width:100%}#conversejs .fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){#conversejs .fade{transition:none}}#conversejs .fade:not(.show){opacity:0}#conversejs .collapse:not(.show){display:none}#conversejs .collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){#conversejs .collapsing{transition:none}}#conversejs .dropdown,#conversejs .dropleft,#conversejs .dropright,#conversejs .dropup{position:relative}#conversejs .dropdown-toggle{white-space:nowrap}#conversejs .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}#conversejs .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}#conversejs .dropdown-menu-left{right:auto;left:0}#conversejs .dropdown-menu-right{right:0;left:auto}@media (min-width:576px){#conversejs .dropdown-menu-sm-left{right:auto;left:0}#conversejs .dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){#conversejs .dropdown-menu-md-left{right:auto;left:0}#conversejs .dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){#conversejs .dropdown-menu-lg-left{right:auto;left:0}#conversejs .dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){#conversejs .dropdown-menu-xl-left{right:auto;left:0}#conversejs .dropdown-menu-xl-right{right:0;left:auto}}#conversejs .dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}#conversejs .dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}#conversejs .dropup .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}#conversejs .dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}#conversejs .dropright .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropright .dropdown-toggle::after{vertical-align:0}#conversejs .dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}#conversejs .dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}#conversejs .dropleft .dropdown-toggle::after{display:none}#conversejs .dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}#conversejs .dropleft .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropleft .dropdown-toggle::before{vertical-align:0}#conversejs .dropdown-menu[x-placement^=bottom],#conversejs .dropdown-menu[x-placement^=left],#conversejs .dropdown-menu[x-placement^=right],#conversejs .dropdown-menu[x-placement^=top]{right:auto;bottom:auto}#conversejs .dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}#conversejs .dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}#conversejs .dropdown-item:focus,#conversejs .dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}#conversejs .dropdown-item.active,#conversejs .dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}#conversejs .dropdown-item.disabled,#conversejs .dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}#conversejs .dropdown-menu.show{display:block}#conversejs .dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}#conversejs .dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}#conversejs .btn-group,#conversejs .btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}#conversejs .btn-group-vertical>.btn,#conversejs .btn-group>.btn{position:relative;flex:1 1 auto}#conversejs .btn-group-vertical>.btn:hover,#conversejs .btn-group>.btn:hover{z-index:1}#conversejs .btn-group-vertical>.btn.active,#conversejs .btn-group-vertical>.btn:active,#conversejs .btn-group-vertical>.btn:focus,#conversejs .btn-group>.btn.active,#conversejs .btn-group>.btn:active,#conversejs .btn-group>.btn:focus{z-index:1}#conversejs .btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}#conversejs .btn-toolbar .input-group{width:auto}#conversejs .btn-group>.btn-group:not(:first-child),#conversejs .btn-group>.btn:not(:first-child){margin-left:-1px}#conversejs .btn-group>.btn-group:not(:last-child)>.btn,#conversejs .btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .btn-group>.btn-group:not(:first-child)>.btn,#conversejs .btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}#conversejs .dropdown-toggle-split::after,.dropright #conversejs .dropdown-toggle-split::after,.dropup #conversejs .dropdown-toggle-split::after{margin-left:0}.dropleft #conversejs .dropdown-toggle-split::before{margin-right:0}#conversejs .btn-group-sm>.btn+.dropdown-toggle-split,#conversejs .btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}#conversejs .btn-group-lg>.btn+.dropdown-toggle-split,#conversejs .btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}#conversejs .btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}#conversejs .btn-group-vertical>.btn,#conversejs .btn-group-vertical>.btn-group{width:100%}#conversejs .btn-group-vertical>.btn-group:not(:first-child),#conversejs .btn-group-vertical>.btn:not(:first-child){margin-top:-1px}#conversejs .btn-group-vertical>.btn-group:not(:last-child)>.btn,#conversejs .btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}#conversejs .btn-group-vertical>.btn-group:not(:first-child)>.btn,#conversejs .btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}#conversejs .btn-group-toggle>.btn,#conversejs .btn-group-toggle>.btn-group>.btn{margin-bottom:0}#conversejs .btn-group-toggle>.btn input[type=checkbox],#conversejs .btn-group-toggle>.btn input[type=radio],#conversejs .btn-group-toggle>.btn-group>.btn input[type=checkbox],#conversejs .btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}#conversejs .input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}#conversejs .input-group>.custom-file,#conversejs .input-group>.custom-select,#conversejs .input-group>.form-control,#conversejs .input-group>.form-control-plaintext{position:relative;flex:1 1 0%;min-width:0;margin-bottom:0}#conversejs .input-group>.custom-file+.custom-file,#conversejs .input-group>.custom-file+.custom-select,#conversejs .input-group>.custom-file+.form-control,#conversejs .input-group>.custom-select+.custom-file,#conversejs .input-group>.custom-select+.custom-select,#conversejs .input-group>.custom-select+.form-control,#conversejs .input-group>.form-control+.custom-file,#conversejs .input-group>.form-control+.custom-select,#conversejs .input-group>.form-control+.form-control,#conversejs .input-group>.form-control-plaintext+.custom-file,#conversejs .input-group>.form-control-plaintext+.custom-select,#conversejs .input-group>.form-control-plaintext+.form-control{margin-left:-1px}#conversejs .input-group>.custom-file .custom-file-input:focus~.custom-file-label,#conversejs .input-group>.custom-select:focus,#conversejs .input-group>.form-control:focus{z-index:3}#conversejs .input-group>.custom-file .custom-file-input:focus{z-index:4}#conversejs .input-group>.custom-select:not(:last-child),#conversejs .input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .input-group>.custom-select:not(:first-child),#conversejs .input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .input-group>.custom-file{display:flex;align-items:center}#conversejs .input-group>.custom-file:not(:last-child) .custom-file-label,#conversejs .input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .input-group-append,#conversejs .input-group-prepend{display:flex}#conversejs .input-group-append .btn,#conversejs .input-group-prepend .btn{position:relative;z-index:2}#conversejs .input-group-append .btn:focus,#conversejs .input-group-prepend .btn:focus{z-index:3}#conversejs .input-group-append .btn+.btn,#conversejs .input-group-append .btn+.input-group-text,#conversejs .input-group-append .input-group-text+.btn,#conversejs .input-group-append .input-group-text+.input-group-text,#conversejs .input-group-prepend .btn+.btn,#conversejs .input-group-prepend .btn+.input-group-text,#conversejs .input-group-prepend .input-group-text+.btn,#conversejs .input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}#conversejs .input-group-prepend{margin-right:-1px}#conversejs .input-group-append{margin-left:-1px}#conversejs .input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}#conversejs .input-group-text input[type=checkbox],#conversejs .input-group-text input[type=radio]{margin-top:0}#conversejs .input-group-lg>.custom-select,#conversejs .input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}#conversejs .input-group-lg>.custom-select,#conversejs .input-group-lg>.form-control,#conversejs .input-group-lg>.input-group-append>.btn,#conversejs .input-group-lg>.input-group-append>.input-group-text,#conversejs .input-group-lg>.input-group-prepend>.btn,#conversejs .input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}#conversejs .input-group-sm>.custom-select,#conversejs .input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}#conversejs .input-group-sm>.custom-select,#conversejs .input-group-sm>.form-control,#conversejs .input-group-sm>.input-group-append>.btn,#conversejs .input-group-sm>.input-group-append>.input-group-text,#conversejs .input-group-sm>.input-group-prepend>.btn,#conversejs .input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}#conversejs .input-group-lg>.custom-select,#conversejs .input-group-sm>.custom-select{padding-right:1.75rem}#conversejs .input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),#conversejs .input-group>.input-group-append:last-child>.input-group-text:not(:last-child),#conversejs .input-group>.input-group-append:not(:last-child)>.btn,#conversejs .input-group>.input-group-append:not(:last-child)>.input-group-text,#conversejs .input-group>.input-group-prepend>.btn,#conversejs .input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .input-group>.input-group-append>.btn,#conversejs .input-group>.input-group-append>.input-group-text,#conversejs .input-group>.input-group-prepend:first-child>.btn:not(:first-child),#conversejs .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),#conversejs .input-group>.input-group-prepend:not(:first-child)>.btn,#conversejs .input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}#conversejs .custom-control-inline{display:inline-flex;margin-right:1rem}#conversejs .custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}#conversejs .custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}#conversejs .custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}#conversejs .custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}#conversejs .custom-control-input:disabled~.custom-control-label,#conversejs .custom-control-input[disabled]~.custom-control-label{color:#6c757d}#conversejs .custom-control-input:disabled~.custom-control-label::before,#conversejs .custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}#conversejs .custom-control-label{position:relative;margin-bottom:0;vertical-align:top}#conversejs .custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}#conversejs .custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}#conversejs .custom-checkbox .custom-control-label::before{border-radius:.25rem}#conversejs .custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}#conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}#conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}#conversejs .custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-radio .custom-control-label::before{border-radius:50%}#conversejs .custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}#conversejs .custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-switch{padding-left:2.25rem}#conversejs .custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}#conversejs .custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .custom-switch .custom-control-label::after{transition:none}}#conversejs .custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}#conversejs .custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}#conversejs .custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-select:focus::-ms-value{color:#495057;background-color:#fff}#conversejs .custom-select[multiple],#conversejs .custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}#conversejs .custom-select:disabled{color:#6c757d;background-color:#e9ecef}#conversejs .custom-select::-ms-expand{display:none}#conversejs .custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}#conversejs .custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}#conversejs .custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}#conversejs .custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}#conversejs .custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}#conversejs .custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-file-input:disabled~.custom-file-label,#conversejs .custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}#conversejs .custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}#conversejs .custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}#conversejs .custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}#conversejs .custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}#conversejs .custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}#conversejs .custom-range:focus{outline:0}#conversejs .custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-range::-moz-focus-outer{border:0}#conversejs .custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){#conversejs .custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}#conversejs .custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}#conversejs .custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}#conversejs .custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){#conversejs .custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}#conversejs .custom-range::-moz-range-thumb:active{background-color:#b3d7ff}#conversejs .custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}#conversejs .custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){#conversejs .custom-range::-ms-thumb{-ms-transition:none;transition:none}}#conversejs .custom-range::-ms-thumb:active{background-color:#b3d7ff}#conversejs .custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}#conversejs .custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}#conversejs .custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}#conversejs .custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}#conversejs .custom-range:disabled::-webkit-slider-runnable-track{cursor:default}#conversejs .custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}#conversejs .custom-range:disabled::-moz-range-track{cursor:default}#conversejs .custom-range:disabled::-ms-thumb{background-color:#adb5bd}#conversejs .custom-control-label::before,#conversejs .custom-file-label,#conversejs .custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .custom-control-label::before,#conversejs .custom-file-label,#conversejs .custom-select{transition:none}}#conversejs .nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}#conversejs .nav-link{display:block;padding:.5rem 1rem}#conversejs .nav-link:focus,#conversejs .nav-link:hover{text-decoration:none}#conversejs .nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}#conversejs .nav-tabs{border-bottom:1px solid #dee2e6}#conversejs .nav-tabs .nav-item{margin-bottom:-1px}#conversejs .nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}#conversejs .nav-tabs .nav-link:focus,#conversejs .nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}#conversejs .nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}#conversejs .nav-tabs .nav-item.show .nav-link,#conversejs .nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}#conversejs .nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}#conversejs .nav-pills .nav-link{border-radius:.25rem}#conversejs .nav-pills .nav-link.active,#conversejs .nav-pills .show>.nav-link{color:#fff;background-color:#007bff}#conversejs .nav-fill .nav-item{flex:1 1 auto;text-align:center}#conversejs .nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}#conversejs .tab-content>.tab-pane{display:none}#conversejs .tab-content>.active{display:block}#conversejs .badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .badge{transition:none}}a#conversejs .badge:focus,a#conversejs .badge:hover{text-decoration:none}#conversejs .badge:empty{display:none}#conversejs .btn .badge{position:relative;top:-1px}#conversejs .badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}#conversejs .badge-primary{color:#fff;background-color:#007bff}a#conversejs .badge-primary:focus,a#conversejs .badge-primary:hover{color:#fff;background-color:#0062cc}a#conversejs .badge-primary.focus,a#conversejs .badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}#conversejs .badge-secondary{color:#fff;background-color:#6c757d}a#conversejs .badge-secondary:focus,a#conversejs .badge-secondary:hover{color:#fff;background-color:#545b62}a#conversejs .badge-secondary.focus,a#conversejs .badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}#conversejs .badge-success{color:#fff;background-color:#28a745}a#conversejs .badge-success:focus,a#conversejs .badge-success:hover{color:#fff;background-color:#1e7e34}a#conversejs .badge-success.focus,a#conversejs .badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}#conversejs .badge-info{color:#fff;background-color:#17a2b8}a#conversejs .badge-info:focus,a#conversejs .badge-info:hover{color:#fff;background-color:#117a8b}a#conversejs .badge-info.focus,a#conversejs .badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}#conversejs .badge-warning{color:#212529;background-color:#ffc107}a#conversejs .badge-warning:focus,a#conversejs .badge-warning:hover{color:#212529;background-color:#d39e00}a#conversejs .badge-warning.focus,a#conversejs .badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}#conversejs .badge-danger{color:#fff;background-color:#dc3545}a#conversejs .badge-danger:focus,a#conversejs .badge-danger:hover{color:#fff;background-color:#bd2130}a#conversejs .badge-danger.focus,a#conversejs .badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}#conversejs .badge-light{color:#212529;background-color:#f8f9fa}a#conversejs .badge-light:focus,a#conversejs .badge-light:hover{color:#212529;background-color:#dae0e5}a#conversejs .badge-light.focus,a#conversejs .badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}#conversejs .badge-dark{color:#fff;background-color:#343a40}a#conversejs .badge-dark:focus,a#conversejs .badge-dark:hover{color:#fff;background-color:#1d2124}a#conversejs .badge-dark.focus,a#conversejs .badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}#conversejs .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}#conversejs .alert-heading{color:inherit}#conversejs .alert-link{font-weight:700}#conversejs .alert-dismissible{padding-right:4rem}#conversejs .alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}#conversejs .alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}#conversejs .alert-primary hr{border-top-color:#9fcdff}#conversejs .alert-primary .alert-link{color:#002752}#conversejs .alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}#conversejs .alert-secondary hr{border-top-color:#c8cbcf}#conversejs .alert-secondary .alert-link{color:#202326}#conversejs .alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}#conversejs .alert-success hr{border-top-color:#b1dfbb}#conversejs .alert-success .alert-link{color:#0b2e13}#conversejs .alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}#conversejs .alert-info hr{border-top-color:#abdde5}#conversejs .alert-info .alert-link{color:#062c33}#conversejs .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}#conversejs .alert-warning hr{border-top-color:#ffe8a1}#conversejs .alert-warning .alert-link{color:#533f03}#conversejs .alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}#conversejs .alert-danger hr{border-top-color:#f1b0b7}#conversejs .alert-danger .alert-link{color:#491217}#conversejs .alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}#conversejs .alert-light hr{border-top-color:#ececf6}#conversejs .alert-light .alert-link{color:#686868}#conversejs .alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}#conversejs .alert-dark hr{border-top-color:#b9bbbe}#conversejs .alert-dark .alert-link{color:#040505}#conversejs .media{display:flex;align-items:flex-start}#conversejs .media-body{flex:1}#conversejs .list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}#conversejs .list-group-item-action{width:100%;color:#495057;text-align:inherit}#conversejs .list-group-item-action:focus,#conversejs .list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}#conversejs .list-group-item-action:active{color:#212529;background-color:#e9ecef}#conversejs .list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}#conversejs .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}#conversejs .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}#conversejs .list-group-item.disabled,#conversejs .list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}#conversejs .list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .list-group-item+#conversejs .list-group-item{border-top-width:0}#conversejs .list-group-item+#conversejs .list-group-item.active{margin-top:-1px;border-top-width:1px}#conversejs .list-group-horizontal{flex-direction:row}#conversejs .list-group-horizontal .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){#conversejs .list-group-horizontal-sm{flex-direction:row}#conversejs .list-group-horizontal-sm .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-sm .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-sm .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-sm .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-sm .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){#conversejs .list-group-horizontal-md{flex-direction:row}#conversejs .list-group-horizontal-md .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-md .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-md .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-md .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-md .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){#conversejs .list-group-horizontal-lg{flex-direction:row}#conversejs .list-group-horizontal-lg .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-lg .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-lg .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-lg .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-lg .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){#conversejs .list-group-horizontal-xl{flex-direction:row}#conversejs .list-group-horizontal-xl .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-xl .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-xl .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-xl .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-xl .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}#conversejs .list-group-flush .list-group-item{border-right-width:0;border-left-width:0;border-radius:0}#conversejs .list-group-flush .list-group-item:first-child{border-top-width:0}#conversejs .list-group-flush:last-child .list-group-item:last-child{border-bottom-width:0}#conversejs .list-group-item-primary{color:#004085;background-color:#b8daff}#conversejs .list-group-item-primary.list-group-item-action:focus,#conversejs .list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}#conversejs .list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}#conversejs .list-group-item-secondary{color:#383d41;background-color:#d6d8db}#conversejs .list-group-item-secondary.list-group-item-action:focus,#conversejs .list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}#conversejs .list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}#conversejs .list-group-item-success{color:#155724;background-color:#c3e6cb}#conversejs .list-group-item-success.list-group-item-action:focus,#conversejs .list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}#conversejs .list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}#conversejs .list-group-item-info{color:#0c5460;background-color:#bee5eb}#conversejs .list-group-item-info.list-group-item-action:focus,#conversejs .list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}#conversejs .list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}#conversejs .list-group-item-warning{color:#856404;background-color:#ffeeba}#conversejs .list-group-item-warning.list-group-item-action:focus,#conversejs .list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}#conversejs .list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}#conversejs .list-group-item-danger{color:#721c24;background-color:#f5c6cb}#conversejs .list-group-item-danger.list-group-item-action:focus,#conversejs .list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}#conversejs .list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}#conversejs .list-group-item-light{color:#818182;background-color:#fdfdfe}#conversejs .list-group-item-light.list-group-item-action:focus,#conversejs .list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}#conversejs .list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}#conversejs .list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}#conversejs .list-group-item-dark.list-group-item-action:focus,#conversejs .list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}#conversejs .list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}#conversejs .close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}#conversejs .close:hover{color:#000;text-decoration:none}#conversejs .close:not(:disabled):not(.disabled):focus,#conversejs .close:not(:disabled):not(.disabled):hover{opacity:.75}#conversejs button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}#conversejs a.close.disabled{pointer-events:none}#conversejs .modal-open{overflow:hidden}#conversejs .modal-open .modal{overflow-x:hidden;overflow-y:auto}#conversejs .modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}#conversejs .modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade #conversejs .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade #conversejs .modal-dialog{transition:none}}.modal.show #conversejs .modal-dialog{transform:none}.modal.modal-static #conversejs .modal-dialog{transform:scale(1.02)}#conversejs .modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}#conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}#conversejs .modal-dialog-scrollable .modal-footer,#conversejs .modal-dialog-scrollable .modal-header{flex-shrink:0}#conversejs .modal-dialog-scrollable .modal-body{overflow-y:auto}#conversejs .modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}#conversejs .modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}#conversejs .modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}#conversejs .modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}#conversejs .modal-dialog-centered.modal-dialog-scrollable::before{content:none}#conversejs .modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}#conversejs .modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}#conversejs .modal-backdrop.fade{opacity:0}#conversejs .modal-backdrop.show{opacity:.5}#conversejs .modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}#conversejs .modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}#conversejs .modal-title{margin-bottom:0;line-height:1.5}#conversejs .modal-body{position:relative;flex:1 1 auto;padding:1rem}#conversejs .modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}#conversejs .modal-footer>*{margin:.25rem}#conversejs .modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){#conversejs .modal-dialog{max-width:500px;margin:1.75rem auto}#conversejs .modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}#conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}#conversejs .modal-dialog-centered{min-height:calc(100% - 3.5rem)}#conversejs .modal-dialog-centered::before{height:calc(100vh - 3.5rem)}#conversejs .modal-sm{max-width:300px}}@media (min-width:992px){#conversejs .modal-lg,#conversejs .modal-xl{max-width:800px}}@media (min-width:1200px){#conversejs .modal-xl{max-width:1140px}}#conversejs .tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}#conversejs .tooltip.show{opacity:.9}#conversejs .tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}#conversejs .tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}#conversejs .bs-tooltip-auto[x-placement^=top],#conversejs .bs-tooltip-top{padding:.4rem 0}#conversejs .bs-tooltip-auto[x-placement^=top] .arrow,#conversejs .bs-tooltip-top .arrow{bottom:0}#conversejs .bs-tooltip-auto[x-placement^=top] .arrow::before,#conversejs .bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}#conversejs .bs-tooltip-auto[x-placement^=right],#conversejs .bs-tooltip-right{padding:0 .4rem}#conversejs .bs-tooltip-auto[x-placement^=right] .arrow,#conversejs .bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}#conversejs .bs-tooltip-auto[x-placement^=right] .arrow::before,#conversejs .bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}#conversejs .bs-tooltip-auto[x-placement^=bottom],#conversejs .bs-tooltip-bottom{padding:.4rem 0}#conversejs .bs-tooltip-auto[x-placement^=bottom] .arrow,#conversejs .bs-tooltip-bottom .arrow{top:0}#conversejs .bs-tooltip-auto[x-placement^=bottom] .arrow::before,#conversejs .bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}#conversejs .bs-tooltip-auto[x-placement^=left],#conversejs .bs-tooltip-left{padding:0 .4rem}#conversejs .bs-tooltip-auto[x-placement^=left] .arrow,#conversejs .bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}#conversejs .bs-tooltip-auto[x-placement^=left] .arrow::before,#conversejs .bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}#conversejs .tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}#conversejs .popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}#conversejs .popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}#conversejs .popover .arrow::after,#conversejs .popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}#conversejs .bs-popover-auto[x-placement^=top],#conversejs .bs-popover-top{margin-bottom:.5rem}#conversejs .bs-popover-auto[x-placement^=top]>.arrow,#conversejs .bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}#conversejs .bs-popover-auto[x-placement^=top]>.arrow::before,#conversejs .bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=top]>.arrow::after,#conversejs .bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}#conversejs .bs-popover-auto[x-placement^=right],#conversejs .bs-popover-right{margin-left:.5rem}#conversejs .bs-popover-auto[x-placement^=right]>.arrow,#conversejs .bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}#conversejs .bs-popover-auto[x-placement^=right]>.arrow::before,#conversejs .bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=right]>.arrow::after,#conversejs .bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}#conversejs .bs-popover-auto[x-placement^=bottom],#conversejs .bs-popover-bottom{margin-top:.5rem}#conversejs .bs-popover-auto[x-placement^=bottom]>.arrow,#conversejs .bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}#conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::before,#conversejs .bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::after,#conversejs .bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}#conversejs .bs-popover-auto[x-placement^=bottom] .popover-header::before,#conversejs .bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}#conversejs .bs-popover-auto[x-placement^=left],#conversejs .bs-popover-left{margin-right:.5rem}#conversejs .bs-popover-auto[x-placement^=left]>.arrow,#conversejs .bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}#conversejs .bs-popover-auto[x-placement^=left]>.arrow::before,#conversejs .bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=left]>.arrow::after,#conversejs .bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}#conversejs .popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}#conversejs .popover-header:empty{display:none}#conversejs .popover-body{padding:.5rem .75rem;color:#212529}#conversejs .align-baseline{vertical-align:baseline!important}#conversejs .align-top{vertical-align:top!important}#conversejs .align-middle{vertical-align:middle!important}#conversejs .align-bottom{vertical-align:bottom!important}#conversejs .align-text-bottom{vertical-align:text-bottom!important}#conversejs .align-text-top{vertical-align:text-top!important}#conversejs .bg-primary{background-color:#007bff!important}#conversejs a.bg-primary:focus,#conversejs a.bg-primary:hover,#conversejs button.bg-primary:focus,#conversejs button.bg-primary:hover{background-color:#0062cc!important}#conversejs .bg-secondary{background-color:#6c757d!important}#conversejs a.bg-secondary:focus,#conversejs a.bg-secondary:hover,#conversejs button.bg-secondary:focus,#conversejs button.bg-secondary:hover{background-color:#545b62!important}#conversejs .bg-success{background-color:#28a745!important}#conversejs a.bg-success:focus,#conversejs a.bg-success:hover,#conversejs button.bg-success:focus,#conversejs button.bg-success:hover{background-color:#1e7e34!important}#conversejs .bg-info{background-color:#17a2b8!important}#conversejs a.bg-info:focus,#conversejs a.bg-info:hover,#conversejs button.bg-info:focus,#conversejs button.bg-info:hover{background-color:#117a8b!important}#conversejs .bg-warning{background-color:#ffc107!important}#conversejs a.bg-warning:focus,#conversejs a.bg-warning:hover,#conversejs button.bg-warning:focus,#conversejs button.bg-warning:hover{background-color:#d39e00!important}#conversejs .bg-danger{background-color:#dc3545!important}#conversejs a.bg-danger:focus,#conversejs a.bg-danger:hover,#conversejs button.bg-danger:focus,#conversejs button.bg-danger:hover{background-color:#bd2130!important}#conversejs .bg-light{background-color:#f8f9fa!important}#conversejs a.bg-light:focus,#conversejs a.bg-light:hover,#conversejs button.bg-light:focus,#conversejs button.bg-light:hover{background-color:#dae0e5!important}#conversejs .bg-dark{background-color:#343a40!important}#conversejs a.bg-dark:focus,#conversejs a.bg-dark:hover,#conversejs button.bg-dark:focus,#conversejs button.bg-dark:hover{background-color:#1d2124!important}#conversejs .bg-white{background-color:#fff!important}#conversejs .bg-transparent{background-color:transparent!important}#conversejs .border{border:1px solid #dee2e6!important}#conversejs .border-top{border-top:1px solid #dee2e6!important}#conversejs .border-right{border-right:1px solid #dee2e6!important}#conversejs .border-bottom{border-bottom:1px solid #dee2e6!important}#conversejs .border-left{border-left:1px solid #dee2e6!important}#conversejs .border-0{border:0!important}#conversejs .border-top-0{border-top:0!important}#conversejs .border-right-0{border-right:0!important}#conversejs .border-bottom-0{border-bottom:0!important}#conversejs .border-left-0{border-left:0!important}#conversejs .border-primary{border-color:#007bff!important}#conversejs .border-secondary{border-color:#6c757d!important}#conversejs .border-success{border-color:#28a745!important}#conversejs .border-info{border-color:#17a2b8!important}#conversejs .border-warning{border-color:#ffc107!important}#conversejs .border-danger{border-color:#dc3545!important}#conversejs .border-light{border-color:#f8f9fa!important}#conversejs .border-dark{border-color:#343a40!important}#conversejs .border-white{border-color:#fff!important}#conversejs .rounded-sm{border-radius:.2rem!important}#conversejs .rounded{border-radius:.25rem!important}#conversejs .rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}#conversejs .rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}#conversejs .rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}#conversejs .rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}#conversejs .rounded-lg{border-radius:.3rem!important}#conversejs .rounded-circle{border-radius:50%!important}#conversejs .rounded-pill{border-radius:50rem!important}#conversejs .rounded-0{border-radius:0!important}#conversejs .clearfix::after{display:block;clear:both;content:""}#conversejs .d-none{display:none!important}#conversejs .d-inline{display:inline!important}#conversejs .d-inline-block{display:inline-block!important}#conversejs .d-block{display:block!important}#conversejs .d-table{display:table!important}#conversejs .d-table-row{display:table-row!important}#conversejs .d-table-cell{display:table-cell!important}#conversejs .d-flex{display:flex!important}#conversejs .d-inline-flex{display:inline-flex!important}@media (min-width:576px){#conversejs .d-sm-none{display:none!important}#conversejs .d-sm-inline{display:inline!important}#conversejs .d-sm-inline-block{display:inline-block!important}#conversejs .d-sm-block{display:block!important}#conversejs .d-sm-table{display:table!important}#conversejs .d-sm-table-row{display:table-row!important}#conversejs .d-sm-table-cell{display:table-cell!important}#conversejs .d-sm-flex{display:flex!important}#conversejs .d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){#conversejs .d-md-none{display:none!important}#conversejs .d-md-inline{display:inline!important}#conversejs .d-md-inline-block{display:inline-block!important}#conversejs .d-md-block{display:block!important}#conversejs .d-md-table{display:table!important}#conversejs .d-md-table-row{display:table-row!important}#conversejs .d-md-table-cell{display:table-cell!important}#conversejs .d-md-flex{display:flex!important}#conversejs .d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){#conversejs .d-lg-none{display:none!important}#conversejs .d-lg-inline{display:inline!important}#conversejs .d-lg-inline-block{display:inline-block!important}#conversejs .d-lg-block{display:block!important}#conversejs .d-lg-table{display:table!important}#conversejs .d-lg-table-row{display:table-row!important}#conversejs .d-lg-table-cell{display:table-cell!important}#conversejs .d-lg-flex{display:flex!important}#conversejs .d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){#conversejs .d-xl-none{display:none!important}#conversejs .d-xl-inline{display:inline!important}#conversejs .d-xl-inline-block{display:inline-block!important}#conversejs .d-xl-block{display:block!important}#conversejs .d-xl-table{display:table!important}#conversejs .d-xl-table-row{display:table-row!important}#conversejs .d-xl-table-cell{display:table-cell!important}#conversejs .d-xl-flex{display:flex!important}#conversejs .d-xl-inline-flex{display:inline-flex!important}}@media print{#conversejs .d-print-none{display:none!important}#conversejs .d-print-inline{display:inline!important}#conversejs .d-print-inline-block{display:inline-block!important}#conversejs .d-print-block{display:block!important}#conversejs .d-print-table{display:table!important}#conversejs .d-print-table-row{display:table-row!important}#conversejs .d-print-table-cell{display:table-cell!important}#conversejs .d-print-flex{display:flex!important}#conversejs .d-print-inline-flex{display:inline-flex!important}}#conversejs .embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}#conversejs .embed-responsive::before{display:block;content:""}#conversejs .embed-responsive .embed-responsive-item,#conversejs .embed-responsive embed,#conversejs .embed-responsive iframe,#conversejs .embed-responsive object,#conversejs .embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}#conversejs .embed-responsive-21by9::before{padding-top:42.85714%}#conversejs .embed-responsive-16by9::before{padding-top:56.25%}#conversejs .embed-responsive-4by3::before{padding-top:75%}#conversejs .embed-responsive-1by1::before{padding-top:100%}#conversejs .flex-row{flex-direction:row!important}#conversejs .flex-column{flex-direction:column!important}#conversejs .flex-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-wrap{flex-wrap:wrap!important}#conversejs .flex-nowrap{flex-wrap:nowrap!important}#conversejs .flex-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-fill{flex:1 1 auto!important}#conversejs .flex-grow-0{flex-grow:0!important}#conversejs .flex-grow-1{flex-grow:1!important}#conversejs .flex-shrink-0{flex-shrink:0!important}#conversejs .flex-shrink-1{flex-shrink:1!important}#conversejs .justify-content-start{justify-content:flex-start!important}#conversejs .justify-content-end{justify-content:flex-end!important}#conversejs .justify-content-center{justify-content:center!important}#conversejs .justify-content-between{justify-content:space-between!important}#conversejs .justify-content-around{justify-content:space-around!important}#conversejs .align-items-start{align-items:flex-start!important}#conversejs .align-items-end{align-items:flex-end!important}#conversejs .align-items-center{align-items:center!important}#conversejs .align-items-baseline{align-items:baseline!important}#conversejs .align-items-stretch{align-items:stretch!important}#conversejs .align-content-start{align-content:flex-start!important}#conversejs .align-content-end{align-content:flex-end!important}#conversejs .align-content-center{align-content:center!important}#conversejs .align-content-between{align-content:space-between!important}#conversejs .align-content-around{align-content:space-around!important}#conversejs .align-content-stretch{align-content:stretch!important}#conversejs .align-self-auto{align-self:auto!important}#conversejs .align-self-start{align-self:flex-start!important}#conversejs .align-self-end{align-self:flex-end!important}#conversejs .align-self-center{align-self:center!important}#conversejs .align-self-baseline{align-self:baseline!important}#conversejs .align-self-stretch{align-self:stretch!important}@media (min-width:576px){#conversejs .flex-sm-row{flex-direction:row!important}#conversejs .flex-sm-column{flex-direction:column!important}#conversejs .flex-sm-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-sm-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-sm-wrap{flex-wrap:wrap!important}#conversejs .flex-sm-nowrap{flex-wrap:nowrap!important}#conversejs .flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-sm-fill{flex:1 1 auto!important}#conversejs .flex-sm-grow-0{flex-grow:0!important}#conversejs .flex-sm-grow-1{flex-grow:1!important}#conversejs .flex-sm-shrink-0{flex-shrink:0!important}#conversejs .flex-sm-shrink-1{flex-shrink:1!important}#conversejs .justify-content-sm-start{justify-content:flex-start!important}#conversejs .justify-content-sm-end{justify-content:flex-end!important}#conversejs .justify-content-sm-center{justify-content:center!important}#conversejs .justify-content-sm-between{justify-content:space-between!important}#conversejs .justify-content-sm-around{justify-content:space-around!important}#conversejs .align-items-sm-start{align-items:flex-start!important}#conversejs .align-items-sm-end{align-items:flex-end!important}#conversejs .align-items-sm-center{align-items:center!important}#conversejs .align-items-sm-baseline{align-items:baseline!important}#conversejs .align-items-sm-stretch{align-items:stretch!important}#conversejs .align-content-sm-start{align-content:flex-start!important}#conversejs .align-content-sm-end{align-content:flex-end!important}#conversejs .align-content-sm-center{align-content:center!important}#conversejs .align-content-sm-between{align-content:space-between!important}#conversejs .align-content-sm-around{align-content:space-around!important}#conversejs .align-content-sm-stretch{align-content:stretch!important}#conversejs .align-self-sm-auto{align-self:auto!important}#conversejs .align-self-sm-start{align-self:flex-start!important}#conversejs .align-self-sm-end{align-self:flex-end!important}#conversejs .align-self-sm-center{align-self:center!important}#conversejs .align-self-sm-baseline{align-self:baseline!important}#conversejs .align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){#conversejs .flex-md-row{flex-direction:row!important}#conversejs .flex-md-column{flex-direction:column!important}#conversejs .flex-md-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-md-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-md-wrap{flex-wrap:wrap!important}#conversejs .flex-md-nowrap{flex-wrap:nowrap!important}#conversejs .flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-md-fill{flex:1 1 auto!important}#conversejs .flex-md-grow-0{flex-grow:0!important}#conversejs .flex-md-grow-1{flex-grow:1!important}#conversejs .flex-md-shrink-0{flex-shrink:0!important}#conversejs .flex-md-shrink-1{flex-shrink:1!important}#conversejs .justify-content-md-start{justify-content:flex-start!important}#conversejs .justify-content-md-end{justify-content:flex-end!important}#conversejs .justify-content-md-center{justify-content:center!important}#conversejs .justify-content-md-between{justify-content:space-between!important}#conversejs .justify-content-md-around{justify-content:space-around!important}#conversejs .align-items-md-start{align-items:flex-start!important}#conversejs .align-items-md-end{align-items:flex-end!important}#conversejs .align-items-md-center{align-items:center!important}#conversejs .align-items-md-baseline{align-items:baseline!important}#conversejs .align-items-md-stretch{align-items:stretch!important}#conversejs .align-content-md-start{align-content:flex-start!important}#conversejs .align-content-md-end{align-content:flex-end!important}#conversejs .align-content-md-center{align-content:center!important}#conversejs .align-content-md-between{align-content:space-between!important}#conversejs .align-content-md-around{align-content:space-around!important}#conversejs .align-content-md-stretch{align-content:stretch!important}#conversejs .align-self-md-auto{align-self:auto!important}#conversejs .align-self-md-start{align-self:flex-start!important}#conversejs .align-self-md-end{align-self:flex-end!important}#conversejs .align-self-md-center{align-self:center!important}#conversejs .align-self-md-baseline{align-self:baseline!important}#conversejs .align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){#conversejs .flex-lg-row{flex-direction:row!important}#conversejs .flex-lg-column{flex-direction:column!important}#conversejs .flex-lg-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-lg-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-lg-wrap{flex-wrap:wrap!important}#conversejs .flex-lg-nowrap{flex-wrap:nowrap!important}#conversejs .flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-lg-fill{flex:1 1 auto!important}#conversejs .flex-lg-grow-0{flex-grow:0!important}#conversejs .flex-lg-grow-1{flex-grow:1!important}#conversejs .flex-lg-shrink-0{flex-shrink:0!important}#conversejs .flex-lg-shrink-1{flex-shrink:1!important}#conversejs .justify-content-lg-start{justify-content:flex-start!important}#conversejs .justify-content-lg-end{justify-content:flex-end!important}#conversejs .justify-content-lg-center{justify-content:center!important}#conversejs .justify-content-lg-between{justify-content:space-between!important}#conversejs .justify-content-lg-around{justify-content:space-around!important}#conversejs .align-items-lg-start{align-items:flex-start!important}#conversejs .align-items-lg-end{align-items:flex-end!important}#conversejs .align-items-lg-center{align-items:center!important}#conversejs .align-items-lg-baseline{align-items:baseline!important}#conversejs .align-items-lg-stretch{align-items:stretch!important}#conversejs .align-content-lg-start{align-content:flex-start!important}#conversejs .align-content-lg-end{align-content:flex-end!important}#conversejs .align-content-lg-center{align-content:center!important}#conversejs .align-content-lg-between{align-content:space-between!important}#conversejs .align-content-lg-around{align-content:space-around!important}#conversejs .align-content-lg-stretch{align-content:stretch!important}#conversejs .align-self-lg-auto{align-self:auto!important}#conversejs .align-self-lg-start{align-self:flex-start!important}#conversejs .align-self-lg-end{align-self:flex-end!important}#conversejs .align-self-lg-center{align-self:center!important}#conversejs .align-self-lg-baseline{align-self:baseline!important}#conversejs .align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){#conversejs .flex-xl-row{flex-direction:row!important}#conversejs .flex-xl-column{flex-direction:column!important}#conversejs .flex-xl-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-xl-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-xl-wrap{flex-wrap:wrap!important}#conversejs .flex-xl-nowrap{flex-wrap:nowrap!important}#conversejs .flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-xl-fill{flex:1 1 auto!important}#conversejs .flex-xl-grow-0{flex-grow:0!important}#conversejs .flex-xl-grow-1{flex-grow:1!important}#conversejs .flex-xl-shrink-0{flex-shrink:0!important}#conversejs .flex-xl-shrink-1{flex-shrink:1!important}#conversejs .justify-content-xl-start{justify-content:flex-start!important}#conversejs .justify-content-xl-end{justify-content:flex-end!important}#conversejs .justify-content-xl-center{justify-content:center!important}#conversejs .justify-content-xl-between{justify-content:space-between!important}#conversejs .justify-content-xl-around{justify-content:space-around!important}#conversejs .align-items-xl-start{align-items:flex-start!important}#conversejs .align-items-xl-end{align-items:flex-end!important}#conversejs .align-items-xl-center{align-items:center!important}#conversejs .align-items-xl-baseline{align-items:baseline!important}#conversejs .align-items-xl-stretch{align-items:stretch!important}#conversejs .align-content-xl-start{align-content:flex-start!important}#conversejs .align-content-xl-end{align-content:flex-end!important}#conversejs .align-content-xl-center{align-content:center!important}#conversejs .align-content-xl-between{align-content:space-between!important}#conversejs .align-content-xl-around{align-content:space-around!important}#conversejs .align-content-xl-stretch{align-content:stretch!important}#conversejs .align-self-xl-auto{align-self:auto!important}#conversejs .align-self-xl-start{align-self:flex-start!important}#conversejs .align-self-xl-end{align-self:flex-end!important}#conversejs .align-self-xl-center{align-self:center!important}#conversejs .align-self-xl-baseline{align-self:baseline!important}#conversejs .align-self-xl-stretch{align-self:stretch!important}}#conversejs .float-left{float:left!important}#conversejs .float-right{float:right!important}#conversejs .float-none{float:none!important}@media (min-width:576px){#conversejs .float-sm-left{float:left!important}#conversejs .float-sm-right{float:right!important}#conversejs .float-sm-none{float:none!important}}@media (min-width:768px){#conversejs .float-md-left{float:left!important}#conversejs .float-md-right{float:right!important}#conversejs .float-md-none{float:none!important}}@media (min-width:992px){#conversejs .float-lg-left{float:left!important}#conversejs .float-lg-right{float:right!important}#conversejs .float-lg-none{float:none!important}}@media (min-width:1200px){#conversejs .float-xl-left{float:left!important}#conversejs .float-xl-right{float:right!important}#conversejs .float-xl-none{float:none!important}}#conversejs .overflow-auto{overflow:auto!important}#conversejs .overflow-hidden{overflow:hidden!important}#conversejs .position-static{position:static!important}#conversejs .position-relative{position:relative!important}#conversejs .position-absolute{position:absolute!important}#conversejs .position-fixed{position:fixed!important}#conversejs .position-sticky{position:-webkit-sticky!important;position:sticky!important}#conversejs .fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}#conversejs .fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){#conversejs .sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}#conversejs .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}#conversejs .sr-only-focusable:active,#conversejs .sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}#conversejs .shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}#conversejs .shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}#conversejs .shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}#conversejs .shadow-none{box-shadow:none!important}#conversejs .w-25{width:25%!important}#conversejs .w-50{width:50%!important}#conversejs .w-75{width:75%!important}#conversejs .w-100{width:100%!important}#conversejs .w-auto{width:auto!important}#conversejs .h-25{height:25%!important}#conversejs .h-50{height:50%!important}#conversejs .h-75{height:75%!important}#conversejs .h-100{height:100%!important}#conversejs .h-auto{height:auto!important}#conversejs .mw-100{max-width:100%!important}#conversejs .mh-100{max-height:100%!important}#conversejs .min-vw-100{min-width:100vw!important}#conversejs .min-vh-100{min-height:100vh!important}#conversejs .vw-100{width:100vw!important}#conversejs .vh-100{height:100vh!important}#conversejs .stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}#conversejs .m-0{margin:0!important}#conversejs .mt-0,#conversejs .my-0{margin-top:0!important}#conversejs .mr-0,#conversejs .mx-0{margin-right:0!important}#conversejs .mb-0,#conversejs .my-0{margin-bottom:0!important}#conversejs .ml-0,#conversejs .mx-0{margin-left:0!important}#conversejs .m-1{margin:.25rem!important}#conversejs .mt-1,#conversejs .my-1{margin-top:.25rem!important}#conversejs .mr-1,#conversejs .mx-1{margin-right:.25rem!important}#conversejs .mb-1,#conversejs .my-1{margin-bottom:.25rem!important}#conversejs .ml-1,#conversejs .mx-1{margin-left:.25rem!important}#conversejs .m-2{margin:.5rem!important}#conversejs .mt-2,#conversejs .my-2{margin-top:.5rem!important}#conversejs .mr-2,#conversejs .mx-2{margin-right:.5rem!important}#conversejs .mb-2,#conversejs .my-2{margin-bottom:.5rem!important}#conversejs .ml-2,#conversejs .mx-2{margin-left:.5rem!important}#conversejs .m-3{margin:1rem!important}#conversejs .mt-3,#conversejs .my-3{margin-top:1rem!important}#conversejs .mr-3,#conversejs .mx-3{margin-right:1rem!important}#conversejs .mb-3,#conversejs .my-3{margin-bottom:1rem!important}#conversejs .ml-3,#conversejs .mx-3{margin-left:1rem!important}#conversejs .m-4{margin:1.5rem!important}#conversejs .mt-4,#conversejs .my-4{margin-top:1.5rem!important}#conversejs .mr-4,#conversejs .mx-4{margin-right:1.5rem!important}#conversejs .mb-4,#conversejs .my-4{margin-bottom:1.5rem!important}#conversejs .ml-4,#conversejs .mx-4{margin-left:1.5rem!important}#conversejs .m-5{margin:3rem!important}#conversejs .mt-5,#conversejs .my-5{margin-top:3rem!important}#conversejs .mr-5,#conversejs .mx-5{margin-right:3rem!important}#conversejs .mb-5,#conversejs .my-5{margin-bottom:3rem!important}#conversejs .ml-5,#conversejs .mx-5{margin-left:3rem!important}#conversejs .p-0{padding:0!important}#conversejs .pt-0,#conversejs .py-0{padding-top:0!important}#conversejs .pr-0,#conversejs .px-0{padding-right:0!important}#conversejs .pb-0,#conversejs .py-0{padding-bottom:0!important}#conversejs .pl-0,#conversejs .px-0{padding-left:0!important}#conversejs .p-1{padding:.25rem!important}#conversejs .pt-1,#conversejs .py-1{padding-top:.25rem!important}#conversejs .pr-1,#conversejs .px-1{padding-right:.25rem!important}#conversejs .pb-1,#conversejs .py-1{padding-bottom:.25rem!important}#conversejs .pl-1,#conversejs .px-1{padding-left:.25rem!important}#conversejs .p-2{padding:.5rem!important}#conversejs .pt-2,#conversejs .py-2{padding-top:.5rem!important}#conversejs .pr-2,#conversejs .px-2{padding-right:.5rem!important}#conversejs .pb-2,#conversejs .py-2{padding-bottom:.5rem!important}#conversejs .pl-2,#conversejs .px-2{padding-left:.5rem!important}#conversejs .p-3{padding:1rem!important}#conversejs .pt-3,#conversejs .py-3{padding-top:1rem!important}#conversejs .pr-3,#conversejs .px-3{padding-right:1rem!important}#conversejs .pb-3,#conversejs .py-3{padding-bottom:1rem!important}#conversejs .pl-3,#conversejs .px-3{padding-left:1rem!important}#conversejs .p-4{padding:1.5rem!important}#conversejs .pt-4,#conversejs .py-4{padding-top:1.5rem!important}#conversejs .pr-4,#conversejs .px-4{padding-right:1.5rem!important}#conversejs .pb-4,#conversejs .py-4{padding-bottom:1.5rem!important}#conversejs .pl-4,#conversejs .px-4{padding-left:1.5rem!important}#conversejs .p-5{padding:3rem!important}#conversejs .pt-5,#conversejs .py-5{padding-top:3rem!important}#conversejs .pr-5,#conversejs .px-5{padding-right:3rem!important}#conversejs .pb-5,#conversejs .py-5{padding-bottom:3rem!important}#conversejs .pl-5,#conversejs .px-5{padding-left:3rem!important}#conversejs .m-n1{margin:-.25rem!important}#conversejs .mt-n1,#conversejs .my-n1{margin-top:-.25rem!important}#conversejs .mr-n1,#conversejs .mx-n1{margin-right:-.25rem!important}#conversejs .mb-n1,#conversejs .my-n1{margin-bottom:-.25rem!important}#conversejs .ml-n1,#conversejs .mx-n1{margin-left:-.25rem!important}#conversejs .m-n2{margin:-.5rem!important}#conversejs .mt-n2,#conversejs .my-n2{margin-top:-.5rem!important}#conversejs .mr-n2,#conversejs .mx-n2{margin-right:-.5rem!important}#conversejs .mb-n2,#conversejs .my-n2{margin-bottom:-.5rem!important}#conversejs .ml-n2,#conversejs .mx-n2{margin-left:-.5rem!important}#conversejs .m-n3{margin:-1rem!important}#conversejs .mt-n3,#conversejs .my-n3{margin-top:-1rem!important}#conversejs .mr-n3,#conversejs .mx-n3{margin-right:-1rem!important}#conversejs .mb-n3,#conversejs .my-n3{margin-bottom:-1rem!important}#conversejs .ml-n3,#conversejs .mx-n3{margin-left:-1rem!important}#conversejs .m-n4{margin:-1.5rem!important}#conversejs .mt-n4,#conversejs .my-n4{margin-top:-1.5rem!important}#conversejs .mr-n4,#conversejs .mx-n4{margin-right:-1.5rem!important}#conversejs .mb-n4,#conversejs .my-n4{margin-bottom:-1.5rem!important}#conversejs .ml-n4,#conversejs .mx-n4{margin-left:-1.5rem!important}#conversejs .m-n5{margin:-3rem!important}#conversejs .mt-n5,#conversejs .my-n5{margin-top:-3rem!important}#conversejs .mr-n5,#conversejs .mx-n5{margin-right:-3rem!important}#conversejs .mb-n5,#conversejs .my-n5{margin-bottom:-3rem!important}#conversejs .ml-n5,#conversejs .mx-n5{margin-left:-3rem!important}#conversejs .m-auto{margin:auto!important}#conversejs .mt-auto,#conversejs .my-auto{margin-top:auto!important}#conversejs .mr-auto,#conversejs .mx-auto{margin-right:auto!important}#conversejs .mb-auto,#conversejs .my-auto{margin-bottom:auto!important}#conversejs .ml-auto,#conversejs .mx-auto{margin-left:auto!important}@media (min-width:576px){#conversejs .m-sm-0{margin:0!important}#conversejs .mt-sm-0,#conversejs .my-sm-0{margin-top:0!important}#conversejs .mr-sm-0,#conversejs .mx-sm-0{margin-right:0!important}#conversejs .mb-sm-0,#conversejs .my-sm-0{margin-bottom:0!important}#conversejs .ml-sm-0,#conversejs .mx-sm-0{margin-left:0!important}#conversejs .m-sm-1{margin:.25rem!important}#conversejs .mt-sm-1,#conversejs .my-sm-1{margin-top:.25rem!important}#conversejs .mr-sm-1,#conversejs .mx-sm-1{margin-right:.25rem!important}#conversejs .mb-sm-1,#conversejs .my-sm-1{margin-bottom:.25rem!important}#conversejs .ml-sm-1,#conversejs .mx-sm-1{margin-left:.25rem!important}#conversejs .m-sm-2{margin:.5rem!important}#conversejs .mt-sm-2,#conversejs .my-sm-2{margin-top:.5rem!important}#conversejs .mr-sm-2,#conversejs .mx-sm-2{margin-right:.5rem!important}#conversejs .mb-sm-2,#conversejs .my-sm-2{margin-bottom:.5rem!important}#conversejs .ml-sm-2,#conversejs .mx-sm-2{margin-left:.5rem!important}#conversejs .m-sm-3{margin:1rem!important}#conversejs .mt-sm-3,#conversejs .my-sm-3{margin-top:1rem!important}#conversejs .mr-sm-3,#conversejs .mx-sm-3{margin-right:1rem!important}#conversejs .mb-sm-3,#conversejs .my-sm-3{margin-bottom:1rem!important}#conversejs .ml-sm-3,#conversejs .mx-sm-3{margin-left:1rem!important}#conversejs .m-sm-4{margin:1.5rem!important}#conversejs .mt-sm-4,#conversejs .my-sm-4{margin-top:1.5rem!important}#conversejs .mr-sm-4,#conversejs .mx-sm-4{margin-right:1.5rem!important}#conversejs .mb-sm-4,#conversejs .my-sm-4{margin-bottom:1.5rem!important}#conversejs .ml-sm-4,#conversejs .mx-sm-4{margin-left:1.5rem!important}#conversejs .m-sm-5{margin:3rem!important}#conversejs .mt-sm-5,#conversejs .my-sm-5{margin-top:3rem!important}#conversejs .mr-sm-5,#conversejs .mx-sm-5{margin-right:3rem!important}#conversejs .mb-sm-5,#conversejs .my-sm-5{margin-bottom:3rem!important}#conversejs .ml-sm-5,#conversejs .mx-sm-5{margin-left:3rem!important}#conversejs .p-sm-0{padding:0!important}#conversejs .pt-sm-0,#conversejs .py-sm-0{padding-top:0!important}#conversejs .pr-sm-0,#conversejs .px-sm-0{padding-right:0!important}#conversejs .pb-sm-0,#conversejs .py-sm-0{padding-bottom:0!important}#conversejs .pl-sm-0,#conversejs .px-sm-0{padding-left:0!important}#conversejs .p-sm-1{padding:.25rem!important}#conversejs .pt-sm-1,#conversejs .py-sm-1{padding-top:.25rem!important}#conversejs .pr-sm-1,#conversejs .px-sm-1{padding-right:.25rem!important}#conversejs .pb-sm-1,#conversejs .py-sm-1{padding-bottom:.25rem!important}#conversejs .pl-sm-1,#conversejs .px-sm-1{padding-left:.25rem!important}#conversejs .p-sm-2{padding:.5rem!important}#conversejs .pt-sm-2,#conversejs .py-sm-2{padding-top:.5rem!important}#conversejs .pr-sm-2,#conversejs .px-sm-2{padding-right:.5rem!important}#conversejs .pb-sm-2,#conversejs .py-sm-2{padding-bottom:.5rem!important}#conversejs .pl-sm-2,#conversejs .px-sm-2{padding-left:.5rem!important}#conversejs .p-sm-3{padding:1rem!important}#conversejs .pt-sm-3,#conversejs .py-sm-3{padding-top:1rem!important}#conversejs .pr-sm-3,#conversejs .px-sm-3{padding-right:1rem!important}#conversejs .pb-sm-3,#conversejs .py-sm-3{padding-bottom:1rem!important}#conversejs .pl-sm-3,#conversejs .px-sm-3{padding-left:1rem!important}#conversejs .p-sm-4{padding:1.5rem!important}#conversejs .pt-sm-4,#conversejs .py-sm-4{padding-top:1.5rem!important}#conversejs .pr-sm-4,#conversejs .px-sm-4{padding-right:1.5rem!important}#conversejs .pb-sm-4,#conversejs .py-sm-4{padding-bottom:1.5rem!important}#conversejs .pl-sm-4,#conversejs .px-sm-4{padding-left:1.5rem!important}#conversejs .p-sm-5{padding:3rem!important}#conversejs .pt-sm-5,#conversejs .py-sm-5{padding-top:3rem!important}#conversejs .pr-sm-5,#conversejs .px-sm-5{padding-right:3rem!important}#conversejs .pb-sm-5,#conversejs .py-sm-5{padding-bottom:3rem!important}#conversejs .pl-sm-5,#conversejs .px-sm-5{padding-left:3rem!important}#conversejs .m-sm-n1{margin:-.25rem!important}#conversejs .mt-sm-n1,#conversejs .my-sm-n1{margin-top:-.25rem!important}#conversejs .mr-sm-n1,#conversejs .mx-sm-n1{margin-right:-.25rem!important}#conversejs .mb-sm-n1,#conversejs .my-sm-n1{margin-bottom:-.25rem!important}#conversejs .ml-sm-n1,#conversejs .mx-sm-n1{margin-left:-.25rem!important}#conversejs .m-sm-n2{margin:-.5rem!important}#conversejs .mt-sm-n2,#conversejs .my-sm-n2{margin-top:-.5rem!important}#conversejs .mr-sm-n2,#conversejs .mx-sm-n2{margin-right:-.5rem!important}#conversejs .mb-sm-n2,#conversejs .my-sm-n2{margin-bottom:-.5rem!important}#conversejs .ml-sm-n2,#conversejs .mx-sm-n2{margin-left:-.5rem!important}#conversejs .m-sm-n3{margin:-1rem!important}#conversejs .mt-sm-n3,#conversejs .my-sm-n3{margin-top:-1rem!important}#conversejs .mr-sm-n3,#conversejs .mx-sm-n3{margin-right:-1rem!important}#conversejs .mb-sm-n3,#conversejs .my-sm-n3{margin-bottom:-1rem!important}#conversejs .ml-sm-n3,#conversejs .mx-sm-n3{margin-left:-1rem!important}#conversejs .m-sm-n4{margin:-1.5rem!important}#conversejs .mt-sm-n4,#conversejs .my-sm-n4{margin-top:-1.5rem!important}#conversejs .mr-sm-n4,#conversejs .mx-sm-n4{margin-right:-1.5rem!important}#conversejs .mb-sm-n4,#conversejs .my-sm-n4{margin-bottom:-1.5rem!important}#conversejs .ml-sm-n4,#conversejs .mx-sm-n4{margin-left:-1.5rem!important}#conversejs .m-sm-n5{margin:-3rem!important}#conversejs .mt-sm-n5,#conversejs .my-sm-n5{margin-top:-3rem!important}#conversejs .mr-sm-n5,#conversejs .mx-sm-n5{margin-right:-3rem!important}#conversejs .mb-sm-n5,#conversejs .my-sm-n5{margin-bottom:-3rem!important}#conversejs .ml-sm-n5,#conversejs .mx-sm-n5{margin-left:-3rem!important}#conversejs .m-sm-auto{margin:auto!important}#conversejs .mt-sm-auto,#conversejs .my-sm-auto{margin-top:auto!important}#conversejs .mr-sm-auto,#conversejs .mx-sm-auto{margin-right:auto!important}#conversejs .mb-sm-auto,#conversejs .my-sm-auto{margin-bottom:auto!important}#conversejs .ml-sm-auto,#conversejs .mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){#conversejs .m-md-0{margin:0!important}#conversejs .mt-md-0,#conversejs .my-md-0{margin-top:0!important}#conversejs .mr-md-0,#conversejs .mx-md-0{margin-right:0!important}#conversejs .mb-md-0,#conversejs .my-md-0{margin-bottom:0!important}#conversejs .ml-md-0,#conversejs .mx-md-0{margin-left:0!important}#conversejs .m-md-1{margin:.25rem!important}#conversejs .mt-md-1,#conversejs .my-md-1{margin-top:.25rem!important}#conversejs .mr-md-1,#conversejs .mx-md-1{margin-right:.25rem!important}#conversejs .mb-md-1,#conversejs .my-md-1{margin-bottom:.25rem!important}#conversejs .ml-md-1,#conversejs .mx-md-1{margin-left:.25rem!important}#conversejs .m-md-2{margin:.5rem!important}#conversejs .mt-md-2,#conversejs .my-md-2{margin-top:.5rem!important}#conversejs .mr-md-2,#conversejs .mx-md-2{margin-right:.5rem!important}#conversejs .mb-md-2,#conversejs .my-md-2{margin-bottom:.5rem!important}#conversejs .ml-md-2,#conversejs .mx-md-2{margin-left:.5rem!important}#conversejs .m-md-3{margin:1rem!important}#conversejs .mt-md-3,#conversejs .my-md-3{margin-top:1rem!important}#conversejs .mr-md-3,#conversejs .mx-md-3{margin-right:1rem!important}#conversejs .mb-md-3,#conversejs .my-md-3{margin-bottom:1rem!important}#conversejs .ml-md-3,#conversejs .mx-md-3{margin-left:1rem!important}#conversejs .m-md-4{margin:1.5rem!important}#conversejs .mt-md-4,#conversejs .my-md-4{margin-top:1.5rem!important}#conversejs .mr-md-4,#conversejs .mx-md-4{margin-right:1.5rem!important}#conversejs .mb-md-4,#conversejs .my-md-4{margin-bottom:1.5rem!important}#conversejs .ml-md-4,#conversejs .mx-md-4{margin-left:1.5rem!important}#conversejs .m-md-5{margin:3rem!important}#conversejs .mt-md-5,#conversejs .my-md-5{margin-top:3rem!important}#conversejs .mr-md-5,#conversejs .mx-md-5{margin-right:3rem!important}#conversejs .mb-md-5,#conversejs .my-md-5{margin-bottom:3rem!important}#conversejs .ml-md-5,#conversejs .mx-md-5{margin-left:3rem!important}#conversejs .p-md-0{padding:0!important}#conversejs .pt-md-0,#conversejs .py-md-0{padding-top:0!important}#conversejs .pr-md-0,#conversejs .px-md-0{padding-right:0!important}#conversejs .pb-md-0,#conversejs .py-md-0{padding-bottom:0!important}#conversejs .pl-md-0,#conversejs .px-md-0{padding-left:0!important}#conversejs .p-md-1{padding:.25rem!important}#conversejs .pt-md-1,#conversejs .py-md-1{padding-top:.25rem!important}#conversejs .pr-md-1,#conversejs .px-md-1{padding-right:.25rem!important}#conversejs .pb-md-1,#conversejs .py-md-1{padding-bottom:.25rem!important}#conversejs .pl-md-1,#conversejs .px-md-1{padding-left:.25rem!important}#conversejs .p-md-2{padding:.5rem!important}#conversejs .pt-md-2,#conversejs .py-md-2{padding-top:.5rem!important}#conversejs .pr-md-2,#conversejs .px-md-2{padding-right:.5rem!important}#conversejs .pb-md-2,#conversejs .py-md-2{padding-bottom:.5rem!important}#conversejs .pl-md-2,#conversejs .px-md-2{padding-left:.5rem!important}#conversejs .p-md-3{padding:1rem!important}#conversejs .pt-md-3,#conversejs .py-md-3{padding-top:1rem!important}#conversejs .pr-md-3,#conversejs .px-md-3{padding-right:1rem!important}#conversejs .pb-md-3,#conversejs .py-md-3{padding-bottom:1rem!important}#conversejs .pl-md-3,#conversejs .px-md-3{padding-left:1rem!important}#conversejs .p-md-4{padding:1.5rem!important}#conversejs .pt-md-4,#conversejs .py-md-4{padding-top:1.5rem!important}#conversejs .pr-md-4,#conversejs .px-md-4{padding-right:1.5rem!important}#conversejs .pb-md-4,#conversejs .py-md-4{padding-bottom:1.5rem!important}#conversejs .pl-md-4,#conversejs .px-md-4{padding-left:1.5rem!important}#conversejs .p-md-5{padding:3rem!important}#conversejs .pt-md-5,#conversejs .py-md-5{padding-top:3rem!important}#conversejs .pr-md-5,#conversejs .px-md-5{padding-right:3rem!important}#conversejs .pb-md-5,#conversejs .py-md-5{padding-bottom:3rem!important}#conversejs .pl-md-5,#conversejs .px-md-5{padding-left:3rem!important}#conversejs .m-md-n1{margin:-.25rem!important}#conversejs .mt-md-n1,#conversejs .my-md-n1{margin-top:-.25rem!important}#conversejs .mr-md-n1,#conversejs .mx-md-n1{margin-right:-.25rem!important}#conversejs .mb-md-n1,#conversejs .my-md-n1{margin-bottom:-.25rem!important}#conversejs .ml-md-n1,#conversejs .mx-md-n1{margin-left:-.25rem!important}#conversejs .m-md-n2{margin:-.5rem!important}#conversejs .mt-md-n2,#conversejs .my-md-n2{margin-top:-.5rem!important}#conversejs .mr-md-n2,#conversejs .mx-md-n2{margin-right:-.5rem!important}#conversejs .mb-md-n2,#conversejs .my-md-n2{margin-bottom:-.5rem!important}#conversejs .ml-md-n2,#conversejs .mx-md-n2{margin-left:-.5rem!important}#conversejs .m-md-n3{margin:-1rem!important}#conversejs .mt-md-n3,#conversejs .my-md-n3{margin-top:-1rem!important}#conversejs .mr-md-n3,#conversejs .mx-md-n3{margin-right:-1rem!important}#conversejs .mb-md-n3,#conversejs .my-md-n3{margin-bottom:-1rem!important}#conversejs .ml-md-n3,#conversejs .mx-md-n3{margin-left:-1rem!important}#conversejs .m-md-n4{margin:-1.5rem!important}#conversejs .mt-md-n4,#conversejs .my-md-n4{margin-top:-1.5rem!important}#conversejs .mr-md-n4,#conversejs .mx-md-n4{margin-right:-1.5rem!important}#conversejs .mb-md-n4,#conversejs .my-md-n4{margin-bottom:-1.5rem!important}#conversejs .ml-md-n4,#conversejs .mx-md-n4{margin-left:-1.5rem!important}#conversejs .m-md-n5{margin:-3rem!important}#conversejs .mt-md-n5,#conversejs .my-md-n5{margin-top:-3rem!important}#conversejs .mr-md-n5,#conversejs .mx-md-n5{margin-right:-3rem!important}#conversejs .mb-md-n5,#conversejs .my-md-n5{margin-bottom:-3rem!important}#conversejs .ml-md-n5,#conversejs .mx-md-n5{margin-left:-3rem!important}#conversejs .m-md-auto{margin:auto!important}#conversejs .mt-md-auto,#conversejs .my-md-auto{margin-top:auto!important}#conversejs .mr-md-auto,#conversejs .mx-md-auto{margin-right:auto!important}#conversejs .mb-md-auto,#conversejs .my-md-auto{margin-bottom:auto!important}#conversejs .ml-md-auto,#conversejs .mx-md-auto{margin-left:auto!important}}@media (min-width:992px){#conversejs .m-lg-0{margin:0!important}#conversejs .mt-lg-0,#conversejs .my-lg-0{margin-top:0!important}#conversejs .mr-lg-0,#conversejs .mx-lg-0{margin-right:0!important}#conversejs .mb-lg-0,#conversejs .my-lg-0{margin-bottom:0!important}#conversejs .ml-lg-0,#conversejs .mx-lg-0{margin-left:0!important}#conversejs .m-lg-1{margin:.25rem!important}#conversejs .mt-lg-1,#conversejs .my-lg-1{margin-top:.25rem!important}#conversejs .mr-lg-1,#conversejs .mx-lg-1{margin-right:.25rem!important}#conversejs .mb-lg-1,#conversejs .my-lg-1{margin-bottom:.25rem!important}#conversejs .ml-lg-1,#conversejs .mx-lg-1{margin-left:.25rem!important}#conversejs .m-lg-2{margin:.5rem!important}#conversejs .mt-lg-2,#conversejs .my-lg-2{margin-top:.5rem!important}#conversejs .mr-lg-2,#conversejs .mx-lg-2{margin-right:.5rem!important}#conversejs .mb-lg-2,#conversejs .my-lg-2{margin-bottom:.5rem!important}#conversejs .ml-lg-2,#conversejs .mx-lg-2{margin-left:.5rem!important}#conversejs .m-lg-3{margin:1rem!important}#conversejs .mt-lg-3,#conversejs .my-lg-3{margin-top:1rem!important}#conversejs .mr-lg-3,#conversejs .mx-lg-3{margin-right:1rem!important}#conversejs .mb-lg-3,#conversejs .my-lg-3{margin-bottom:1rem!important}#conversejs .ml-lg-3,#conversejs .mx-lg-3{margin-left:1rem!important}#conversejs .m-lg-4{margin:1.5rem!important}#conversejs .mt-lg-4,#conversejs .my-lg-4{margin-top:1.5rem!important}#conversejs .mr-lg-4,#conversejs .mx-lg-4{margin-right:1.5rem!important}#conversejs .mb-lg-4,#conversejs .my-lg-4{margin-bottom:1.5rem!important}#conversejs .ml-lg-4,#conversejs .mx-lg-4{margin-left:1.5rem!important}#conversejs .m-lg-5{margin:3rem!important}#conversejs .mt-lg-5,#conversejs .my-lg-5{margin-top:3rem!important}#conversejs .mr-lg-5,#conversejs .mx-lg-5{margin-right:3rem!important}#conversejs .mb-lg-5,#conversejs .my-lg-5{margin-bottom:3rem!important}#conversejs .ml-lg-5,#conversejs .mx-lg-5{margin-left:3rem!important}#conversejs .p-lg-0{padding:0!important}#conversejs .pt-lg-0,#conversejs .py-lg-0{padding-top:0!important}#conversejs .pr-lg-0,#conversejs .px-lg-0{padding-right:0!important}#conversejs .pb-lg-0,#conversejs .py-lg-0{padding-bottom:0!important}#conversejs .pl-lg-0,#conversejs .px-lg-0{padding-left:0!important}#conversejs .p-lg-1{padding:.25rem!important}#conversejs .pt-lg-1,#conversejs .py-lg-1{padding-top:.25rem!important}#conversejs .pr-lg-1,#conversejs .px-lg-1{padding-right:.25rem!important}#conversejs .pb-lg-1,#conversejs .py-lg-1{padding-bottom:.25rem!important}#conversejs .pl-lg-1,#conversejs .px-lg-1{padding-left:.25rem!important}#conversejs .p-lg-2{padding:.5rem!important}#conversejs .pt-lg-2,#conversejs .py-lg-2{padding-top:.5rem!important}#conversejs .pr-lg-2,#conversejs .px-lg-2{padding-right:.5rem!important}#conversejs .pb-lg-2,#conversejs .py-lg-2{padding-bottom:.5rem!important}#conversejs .pl-lg-2,#conversejs .px-lg-2{padding-left:.5rem!important}#conversejs .p-lg-3{padding:1rem!important}#conversejs .pt-lg-3,#conversejs .py-lg-3{padding-top:1rem!important}#conversejs .pr-lg-3,#conversejs .px-lg-3{padding-right:1rem!important}#conversejs .pb-lg-3,#conversejs .py-lg-3{padding-bottom:1rem!important}#conversejs .pl-lg-3,#conversejs .px-lg-3{padding-left:1rem!important}#conversejs .p-lg-4{padding:1.5rem!important}#conversejs .pt-lg-4,#conversejs .py-lg-4{padding-top:1.5rem!important}#conversejs .pr-lg-4,#conversejs .px-lg-4{padding-right:1.5rem!important}#conversejs .pb-lg-4,#conversejs .py-lg-4{padding-bottom:1.5rem!important}#conversejs .pl-lg-4,#conversejs .px-lg-4{padding-left:1.5rem!important}#conversejs .p-lg-5{padding:3rem!important}#conversejs .pt-lg-5,#conversejs .py-lg-5{padding-top:3rem!important}#conversejs .pr-lg-5,#conversejs .px-lg-5{padding-right:3rem!important}#conversejs .pb-lg-5,#conversejs .py-lg-5{padding-bottom:3rem!important}#conversejs .pl-lg-5,#conversejs .px-lg-5{padding-left:3rem!important}#conversejs .m-lg-n1{margin:-.25rem!important}#conversejs .mt-lg-n1,#conversejs .my-lg-n1{margin-top:-.25rem!important}#conversejs .mr-lg-n1,#conversejs .mx-lg-n1{margin-right:-.25rem!important}#conversejs .mb-lg-n1,#conversejs .my-lg-n1{margin-bottom:-.25rem!important}#conversejs .ml-lg-n1,#conversejs .mx-lg-n1{margin-left:-.25rem!important}#conversejs .m-lg-n2{margin:-.5rem!important}#conversejs .mt-lg-n2,#conversejs .my-lg-n2{margin-top:-.5rem!important}#conversejs .mr-lg-n2,#conversejs .mx-lg-n2{margin-right:-.5rem!important}#conversejs .mb-lg-n2,#conversejs .my-lg-n2{margin-bottom:-.5rem!important}#conversejs .ml-lg-n2,#conversejs .mx-lg-n2{margin-left:-.5rem!important}#conversejs .m-lg-n3{margin:-1rem!important}#conversejs .mt-lg-n3,#conversejs .my-lg-n3{margin-top:-1rem!important}#conversejs .mr-lg-n3,#conversejs .mx-lg-n3{margin-right:-1rem!important}#conversejs .mb-lg-n3,#conversejs .my-lg-n3{margin-bottom:-1rem!important}#conversejs .ml-lg-n3,#conversejs .mx-lg-n3{margin-left:-1rem!important}#conversejs .m-lg-n4{margin:-1.5rem!important}#conversejs .mt-lg-n4,#conversejs .my-lg-n4{margin-top:-1.5rem!important}#conversejs .mr-lg-n4,#conversejs .mx-lg-n4{margin-right:-1.5rem!important}#conversejs .mb-lg-n4,#conversejs .my-lg-n4{margin-bottom:-1.5rem!important}#conversejs .ml-lg-n4,#conversejs .mx-lg-n4{margin-left:-1.5rem!important}#conversejs .m-lg-n5{margin:-3rem!important}#conversejs .mt-lg-n5,#conversejs .my-lg-n5{margin-top:-3rem!important}#conversejs .mr-lg-n5,#conversejs .mx-lg-n5{margin-right:-3rem!important}#conversejs .mb-lg-n5,#conversejs .my-lg-n5{margin-bottom:-3rem!important}#conversejs .ml-lg-n5,#conversejs .mx-lg-n5{margin-left:-3rem!important}#conversejs .m-lg-auto{margin:auto!important}#conversejs .mt-lg-auto,#conversejs .my-lg-auto{margin-top:auto!important}#conversejs .mr-lg-auto,#conversejs .mx-lg-auto{margin-right:auto!important}#conversejs .mb-lg-auto,#conversejs .my-lg-auto{margin-bottom:auto!important}#conversejs .ml-lg-auto,#conversejs .mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){#conversejs .m-xl-0{margin:0!important}#conversejs .mt-xl-0,#conversejs .my-xl-0{margin-top:0!important}#conversejs .mr-xl-0,#conversejs .mx-xl-0{margin-right:0!important}#conversejs .mb-xl-0,#conversejs .my-xl-0{margin-bottom:0!important}#conversejs .ml-xl-0,#conversejs .mx-xl-0{margin-left:0!important}#conversejs .m-xl-1{margin:.25rem!important}#conversejs .mt-xl-1,#conversejs .my-xl-1{margin-top:.25rem!important}#conversejs .mr-xl-1,#conversejs .mx-xl-1{margin-right:.25rem!important}#conversejs .mb-xl-1,#conversejs .my-xl-1{margin-bottom:.25rem!important}#conversejs .ml-xl-1,#conversejs .mx-xl-1{margin-left:.25rem!important}#conversejs .m-xl-2{margin:.5rem!important}#conversejs .mt-xl-2,#conversejs .my-xl-2{margin-top:.5rem!important}#conversejs .mr-xl-2,#conversejs .mx-xl-2{margin-right:.5rem!important}#conversejs .mb-xl-2,#conversejs .my-xl-2{margin-bottom:.5rem!important}#conversejs .ml-xl-2,#conversejs .mx-xl-2{margin-left:.5rem!important}#conversejs .m-xl-3{margin:1rem!important}#conversejs .mt-xl-3,#conversejs .my-xl-3{margin-top:1rem!important}#conversejs .mr-xl-3,#conversejs .mx-xl-3{margin-right:1rem!important}#conversejs .mb-xl-3,#conversejs .my-xl-3{margin-bottom:1rem!important}#conversejs .ml-xl-3,#conversejs .mx-xl-3{margin-left:1rem!important}#conversejs .m-xl-4{margin:1.5rem!important}#conversejs .mt-xl-4,#conversejs .my-xl-4{margin-top:1.5rem!important}#conversejs .mr-xl-4,#conversejs .mx-xl-4{margin-right:1.5rem!important}#conversejs .mb-xl-4,#conversejs .my-xl-4{margin-bottom:1.5rem!important}#conversejs .ml-xl-4,#conversejs .mx-xl-4{margin-left:1.5rem!important}#conversejs .m-xl-5{margin:3rem!important}#conversejs .mt-xl-5,#conversejs .my-xl-5{margin-top:3rem!important}#conversejs .mr-xl-5,#conversejs .mx-xl-5{margin-right:3rem!important}#conversejs .mb-xl-5,#conversejs .my-xl-5{margin-bottom:3rem!important}#conversejs .ml-xl-5,#conversejs .mx-xl-5{margin-left:3rem!important}#conversejs .p-xl-0{padding:0!important}#conversejs .pt-xl-0,#conversejs .py-xl-0{padding-top:0!important}#conversejs .pr-xl-0,#conversejs .px-xl-0{padding-right:0!important}#conversejs .pb-xl-0,#conversejs .py-xl-0{padding-bottom:0!important}#conversejs .pl-xl-0,#conversejs .px-xl-0{padding-left:0!important}#conversejs .p-xl-1{padding:.25rem!important}#conversejs .pt-xl-1,#conversejs .py-xl-1{padding-top:.25rem!important}#conversejs .pr-xl-1,#conversejs .px-xl-1{padding-right:.25rem!important}#conversejs .pb-xl-1,#conversejs .py-xl-1{padding-bottom:.25rem!important}#conversejs .pl-xl-1,#conversejs .px-xl-1{padding-left:.25rem!important}#conversejs .p-xl-2{padding:.5rem!important}#conversejs .pt-xl-2,#conversejs .py-xl-2{padding-top:.5rem!important}#conversejs .pr-xl-2,#conversejs .px-xl-2{padding-right:.5rem!important}#conversejs .pb-xl-2,#conversejs .py-xl-2{padding-bottom:.5rem!important}#conversejs .pl-xl-2,#conversejs .px-xl-2{padding-left:.5rem!important}#conversejs .p-xl-3{padding:1rem!important}#conversejs .pt-xl-3,#conversejs .py-xl-3{padding-top:1rem!important}#conversejs .pr-xl-3,#conversejs .px-xl-3{padding-right:1rem!important}#conversejs .pb-xl-3,#conversejs .py-xl-3{padding-bottom:1rem!important}#conversejs .pl-xl-3,#conversejs .px-xl-3{padding-left:1rem!important}#conversejs .p-xl-4{padding:1.5rem!important}#conversejs .pt-xl-4,#conversejs .py-xl-4{padding-top:1.5rem!important}#conversejs .pr-xl-4,#conversejs .px-xl-4{padding-right:1.5rem!important}#conversejs .pb-xl-4,#conversejs .py-xl-4{padding-bottom:1.5rem!important}#conversejs .pl-xl-4,#conversejs .px-xl-4{padding-left:1.5rem!important}#conversejs .p-xl-5{padding:3rem!important}#conversejs .pt-xl-5,#conversejs .py-xl-5{padding-top:3rem!important}#conversejs .pr-xl-5,#conversejs .px-xl-5{padding-right:3rem!important}#conversejs .pb-xl-5,#conversejs .py-xl-5{padding-bottom:3rem!important}#conversejs .pl-xl-5,#conversejs .px-xl-5{padding-left:3rem!important}#conversejs .m-xl-n1{margin:-.25rem!important}#conversejs .mt-xl-n1,#conversejs .my-xl-n1{margin-top:-.25rem!important}#conversejs .mr-xl-n1,#conversejs .mx-xl-n1{margin-right:-.25rem!important}#conversejs .mb-xl-n1,#conversejs .my-xl-n1{margin-bottom:-.25rem!important}#conversejs .ml-xl-n1,#conversejs .mx-xl-n1{margin-left:-.25rem!important}#conversejs .m-xl-n2{margin:-.5rem!important}#conversejs .mt-xl-n2,#conversejs .my-xl-n2{margin-top:-.5rem!important}#conversejs .mr-xl-n2,#conversejs .mx-xl-n2{margin-right:-.5rem!important}#conversejs .mb-xl-n2,#conversejs .my-xl-n2{margin-bottom:-.5rem!important}#conversejs .ml-xl-n2,#conversejs .mx-xl-n2{margin-left:-.5rem!important}#conversejs .m-xl-n3{margin:-1rem!important}#conversejs .mt-xl-n3,#conversejs .my-xl-n3{margin-top:-1rem!important}#conversejs .mr-xl-n3,#conversejs .mx-xl-n3{margin-right:-1rem!important}#conversejs .mb-xl-n3,#conversejs .my-xl-n3{margin-bottom:-1rem!important}#conversejs .ml-xl-n3,#conversejs .mx-xl-n3{margin-left:-1rem!important}#conversejs .m-xl-n4{margin:-1.5rem!important}#conversejs .mt-xl-n4,#conversejs .my-xl-n4{margin-top:-1.5rem!important}#conversejs .mr-xl-n4,#conversejs .mx-xl-n4{margin-right:-1.5rem!important}#conversejs .mb-xl-n4,#conversejs .my-xl-n4{margin-bottom:-1.5rem!important}#conversejs .ml-xl-n4,#conversejs .mx-xl-n4{margin-left:-1.5rem!important}#conversejs .m-xl-n5{margin:-3rem!important}#conversejs .mt-xl-n5,#conversejs .my-xl-n5{margin-top:-3rem!important}#conversejs .mr-xl-n5,#conversejs .mx-xl-n5{margin-right:-3rem!important}#conversejs .mb-xl-n5,#conversejs .my-xl-n5{margin-bottom:-3rem!important}#conversejs .ml-xl-n5,#conversejs .mx-xl-n5{margin-left:-3rem!important}#conversejs .m-xl-auto{margin:auto!important}#conversejs .mt-xl-auto,#conversejs .my-xl-auto{margin-top:auto!important}#conversejs .mr-xl-auto,#conversejs .mx-xl-auto{margin-right:auto!important}#conversejs .mb-xl-auto,#conversejs .my-xl-auto{margin-bottom:auto!important}#conversejs .ml-xl-auto,#conversejs .mx-xl-auto{margin-left:auto!important}}#conversejs .text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}#conversejs .text-justify{text-align:justify!important}#conversejs .text-wrap{white-space:normal!important}#conversejs .text-nowrap{white-space:nowrap!important}#conversejs .text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs .text-left{text-align:left!important}#conversejs .text-right{text-align:right!important}#conversejs .text-center{text-align:center!important}@media (min-width:576px){#conversejs .text-sm-left{text-align:left!important}#conversejs .text-sm-right{text-align:right!important}#conversejs .text-sm-center{text-align:center!important}}@media (min-width:768px){#conversejs .text-md-left{text-align:left!important}#conversejs .text-md-right{text-align:right!important}#conversejs .text-md-center{text-align:center!important}}@media (min-width:992px){#conversejs .text-lg-left{text-align:left!important}#conversejs .text-lg-right{text-align:right!important}#conversejs .text-lg-center{text-align:center!important}}@media (min-width:1200px){#conversejs .text-xl-left{text-align:left!important}#conversejs .text-xl-right{text-align:right!important}#conversejs .text-xl-center{text-align:center!important}}#conversejs .text-lowercase{text-transform:lowercase!important}#conversejs .text-uppercase{text-transform:uppercase!important}#conversejs .text-capitalize{text-transform:capitalize!important}#conversejs .font-weight-light{font-weight:300!important}#conversejs .font-weight-lighter{font-weight:lighter!important}#conversejs .font-weight-normal{font-weight:400!important}#conversejs .font-weight-bold{font-weight:700!important}#conversejs .font-weight-bolder{font-weight:bolder!important}#conversejs .font-italic{font-style:italic!important}#conversejs .text-white{color:#fff!important}#conversejs .text-primary{color:#007bff!important}#conversejs a.text-primary:focus,#conversejs a.text-primary:hover{color:#0056b3!important}#conversejs .text-secondary{color:#6c757d!important}#conversejs a.text-secondary:focus,#conversejs a.text-secondary:hover{color:#494f54!important}#conversejs .text-success{color:#28a745!important}#conversejs a.text-success:focus,#conversejs a.text-success:hover{color:#19692c!important}#conversejs .text-info{color:#17a2b8!important}#conversejs a.text-info:focus,#conversejs a.text-info:hover{color:#0f6674!important}#conversejs .text-warning{color:#ffc107!important}#conversejs a.text-warning:focus,#conversejs a.text-warning:hover{color:#ba8b00!important}#conversejs .text-danger{color:#dc3545!important}#conversejs a.text-danger:focus,#conversejs a.text-danger:hover{color:#a71d2a!important}#conversejs .text-light{color:#f8f9fa!important}#conversejs a.text-light:focus,#conversejs a.text-light:hover{color:#cbd3da!important}#conversejs .text-dark{color:#343a40!important}#conversejs a.text-dark:focus,#conversejs a.text-dark:hover{color:#121416!important}#conversejs .text-body{color:#212529!important}#conversejs .text-muted{color:#6c757d!important}#conversejs .text-black-50{color:rgba(0,0,0,.5)!important}#conversejs .text-white-50{color:rgba(255,255,255,.5)!important}#conversejs .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}#conversejs .text-decoration-none{text-decoration:none!important}#conversejs .text-break{word-break:break-word!important;overflow-wrap:break-word!important}#conversejs .text-reset{color:inherit!important}#conversejs .visible{visibility:visible!important}#conversejs .invisible{visibility:hidden!important}@font-face{font-family:Baumans;font-style:normal;font-weight:400;src:local("Baumans Regular"),local("Baumans-Regular"),url(webfonts/baumans.ttf) format("truetype")}@font-face{font-family:Muli;font-style:normal;font-weight:400;src:local("Muli Regular"),local("Muli-Regular"),url(webfonts/muli.ttf) format("truetype")}@font-face{font-family:ConverseFontAwesomeBrands;font-style:normal;font-weight:400;src:url(webfonts/fa-brands-400.eot);src:url(webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(webfonts/fa-brands-400.woff2) format("woff2"),url(webfonts/fa-brands-400.woff) format("woff"),url(webfonts/fa-brands-400.ttf) format("truetype"),url(webfonts/fa-brands-400.svg#fontawesome) format("svg")}@font-face{font-family:ConverseFontAwesomeRegular;font-style:normal;font-weight:400;src:url(webfonts/fa-regular-400.eot);src:url(webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(webfonts/fa-regular-400.woff2) format("woff2"),url(webfonts/fa-regular-400.woff) format("woff"),url(webfonts/fa-regular-400.ttf) format("truetype"),url(webfonts/fa-regular-400.svg#fontawesome) format("svg");font-weight:400;font-style:normal}@font-face{font-family:ConverseFontAwesomeSolid;font-style:normal;font-weight:900;src:url(webfonts/fa-solid-900.eot);src:url(webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(webfonts/fa-solid-900.svg#fontawesome) format("svg"),url(webfonts/fa-solid-900.woff2) format("woff2"),url(webfonts/fa-solid-900.woff) format("woff"),url(webfonts/fa-solid-900.ttf) format("truetype")}.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scale(-1,1)}.fa-flip-vertical{transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#conversejs converse-icon:before,.converse-website converse-icon:before{content:none!important}#conversejs .far:not(converse-icon),.converse-website .far:not(converse-icon){font-family:ConverseFontAwesomeRegular!important;font-weight:400}#conversejs .fa:not(converse-icon),#conversejs .fas:not(converse-icon),.converse-website .fa:not(converse-icon),.converse-website .fas:not(converse-icon){font-family:ConverseFontAwesomeSolid!important;font-weight:900}#conversejs .fab:not(converse-icon),.converse-website .fab:not(converse-icon){font-family:ConverseFontAwesomeBrands}#conversejs .fa:not(converse-icon),#conversejs .fab:not(converse-icon),#conversejs .far:not(converse-icon),#conversejs .fas:not(converse-icon),.converse-website .fa:not(converse-icon),.converse-website .fab:not(converse-icon),.converse-website .far:not(converse-icon),.converse-website .fas:not(converse-icon){display:inline-block;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs .fa-info-circle,.converse-website .fa-info-circle{height:1em}#conversejs,#conversejs-bg,.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--message-avatar-width:36px;--message-avatar-height:36px;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:'Muli',normal;--branding-font:'Baumans',cursive;--heading-display:block;--heading-color:white;--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}#conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--chat-head-text-color:#AAA;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}body.converse-fullscreen{margin:0;background-color:var(--global-background-color)}#conversejs-bg .converse-brand{display:flex;justify-content:space-between;margin-top:15vh;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:5s;animation-duration:5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media (min-width:768px){#conversejs-bg .converse-brand__padding{flex:0 0 33.33333%;max-width:33.33333%}}@media (min-width:992px){#conversejs-bg .converse-brand__padding{flex:0 0 25%;max-width:25%}}@media (min-width:1200px){#conversejs-bg .converse-brand__padding{flex:0 0 16.66667%;max-width:16.66667%}}#conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media (min-width:768px){#conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.66667%;max-width:66.66667%}}@media (min-width:992px){#conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 75%;max-width:75%}}@media (min-width:1200px){#conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.33333%;max-width:83.33333%}}#conversejs-bg .converse-brand__heading svg{margin-top:.3em}#conversejs-bg .converse-brand__text{color:#fff;font-family:var(--branding-font);font-weight:400;text-align:center;font-size:140%;margin-left:.2em}#conversejs-bg .converse-brand__text .byline{margin:0;font-family:var(--heading-font);font-size:.3em;opacity:.55;margin-bottom:2em;margin-left:-2.7em;word-spacing:5px}#conversejs .subdued,#conversejs-bg .subdued{opacity:.35}#conversejs{bottom:0;height:100%;position:fixed;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);color:var(--text-color);font-family:var(--normal-font);font-size:var(--font-size);direction:ltr;z-index:1031}#conversejs textarea:disabled{background-color:#eee!important}#conversejs .fit-content{width:-webkit-fit-content!important;width:-moz-fit-content!important;width:fit-content!important;max-width:-webkit-fit-content!important;max-width:-moz-fit-content!important;max-width:fit-content!important}#conversejs .nopadding{padding:0!important}#conversejs.converse-overlayed>.row{flex-direction:row-reverse}#conversejs.converse-fullscreen .converse-chatboxes,#conversejs.converse-mobile .converse-chatboxes{width:100vw;left:-15px}#conversejs.converse-overlayed{height:3em}#conversejs.converse-embedded{box-sizing:border-box;bottom:auto;height:100%;position:relative;right:auto;width:100%}#conversejs.converse-embedded *,#conversejs.converse-embedded :after,#conversejs.converse-embedded :before{box-sizing:border-box}#conversejs converse-brand-heading{text-align:center}#conversejs .brand-heading{display:inline-flex;flex-direction:row;align-items:flex-start;font-family:var(--branding-font);color:var(--link-color);margin-bottom:.75em}#conversejs .brand-heading .brand-name-wrapper{display:flex;white-space:nowrap;margin:auto}#conversejs .brand-heading .brand-name{color:var(--link-color);display:flex;flex-direction:column;align-items:center;margin-top:-.25em}#conversejs .brand-heading .brand-name .byline{font-family:var(--heading-font);font-size:.3em;margin-bottom:.75em;margin-left:-2.7em;opacity:.55;word-spacing:5px}#conversejs .brand-heading .brand-subtitle{color:var(--text-color)}#conversejs .brand-heading .brand-name__text{font-size:120%;vertical-align:text-bottom}#conversejs .brand-heading .converse-svg-logo{color:var(--link-color);height:1.5em;margin-right:.25em;margin-bottom:-.25em}#conversejs .brand-heading .converse-svg-logo .cls-1{isolation:isolate}#conversejs .brand-heading .converse-svg-logo .cls-2{opacity:.5;mix-blend-mode:multiply}#conversejs .brand-heading .converse-svg-logo .cls-3{fill:var(--link-color)}#conversejs .brand-heading .converse-svg-logo .cls-4{fill:var(--link-color)}#conversejs .brand-heading--inverse .converse-svg-logo{margin-bottom:0;margin-top:-.2em}#conversejs .brand-heading--inverse .byline{margin:0;font-family:var(--heading-font);font-size:.25em;opacity:.55;margin-left:-7em;word-spacing:5px}#conversejs .dropdown-item{padding:.5rem 1rem}#conversejs .dropdown-item .fa{width:1.25em;margin-right:.75rem}#conversejs .dropdown-item.selected,#conversejs .dropdown-item:active{color:#fff!important;background-color:var(--list-item-open-color)}#conversejs .dropdown-item.selected .fa,#conversejs .dropdown-item:active .fa{color:#fff!important}#conversejs .popover{position:fixed}#conversejs .converse-chatboxes{z-index:1031;position:fixed;bottom:0;right:0}#conversejs ::-moz-placeholder{color:var(--subdued-color)}#conversejs :-ms-input-placeholder{color:var(--subdued-color)}#conversejs ::-ms-input-placeholder{color:var(--subdued-color)}#conversejs ::placeholder{color:var(--subdued-color)}#conversejs ::-moz-selection{background-color:var(--highlight-color)}#conversejs ::selection{background-color:var(--highlight-color)}#conversejs ::-moz-selection{background-color:var(--highlight-color)}@media screen and (max-width:480px){#conversejs{margin:0;right:10px;left:10px;bottom:5px}}@media screen and (max-height:450px){#conversejs{margin:0;right:10px;left:10px;bottom:5px}}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs button,#conversejs input[type=button],#conversejs input[type=password],#conversejs input[type=submit],#conversejs input[type=text],#conversejs textarea{font-size:var(--font-size);min-height:0}#conversejs strong{font-weight:700}#conversejs em{font-style:italic}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0}#conversejs a{cursor:pointer}#conversejs a,#conversejs a:not([href]):not([tabindex]),#conversejs a:visited{text-decoration:none;color:var(--link-color);text-shadow:none;cursor:pointer}#conversejs a:hover,#conversejs a:not([href]):not([tabindex]):hover,#conversejs a:visited:hover{color:var(--link-hover-color);text-decoration:none;text-shadow:none}#conversejs a.fa,#conversejs a.far,#conversejs a.fas,#conversejs a:not([href]):not([tabindex]).fa,#conversejs a:not([href]):not([tabindex]).far,#conversejs a:not([href]):not([tabindex]).fas,#conversejs a:visited.fa,#conversejs a:visited.far,#conversejs a:visited.fas{color:var(--subdued-color)}#conversejs a.fa:hover,#conversejs a.far:hover,#conversejs a.fas:hover,#conversejs a:not([href]):not([tabindex]).fa:hover,#conversejs a:not([href]):not([tabindex]).far:hover,#conversejs a:not([href]):not([tabindex]).fas:hover,#conversejs a:visited.fa:hover,#conversejs a:visited.far:hover,#conversejs a:visited.fas:hover{color:var(--gray-color)}#conversejs svg{border-radius:var(--chatbox-border-radius)}#conversejs .fa,#conversejs .far,#conversejs .fas{color:var(--subdued-color)}#conversejs .fa:hover,#conversejs .far:hover,#conversejs .fas:hover{color:var(--gray-color)}#conversejs q{quotes:"“" "”" "‘" "’"}#conversejs q.reason{display:inline}#conversejs q:before{content:open-quote}#conversejs q:after{content:close-quote}#conversejs .helptext{font-size:var(--font-size-tiny);color:var(--text-color-lighten-15-percent)}#conversejs .selected{color:var(--link-color)!important}#conversejs .circle{border-radius:50%}#conversejs .badge{line-height:1;font-weight:400;font-size:90%}#conversejs .btn{font-weight:400;color:#fff}#conversejs .btn .fa,#conversejs .btn .far,#conversejs .btn .fas{color:#fff;margin-right:.5em}#conversejs .btn .fa.only-icon,#conversejs .btn .far.only-icon,#conversejs .btn .fas.only-icon{margin-right:0}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}@keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}#conversejs .fade-in{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs .visible{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs .hidden{opacity:0!important;display:none!important}#conversejs .fade-out{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}#conversejs .collapsed{height:0!important;overflow:hidden!important;padding:0!important}#conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}#conversejs .spinner{-webkit-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;width:1em;display:block;text-align:center;padding:.5em 0;font-size:24px}#conversejs .left{float:left}#conversejs .right{float:right}#conversejs .centered{text-align:center;display:block;margin:auto}#conversejs .hor_centered{width:100%;text-align:center;display:block;margin:0 auto;clear:both}#conversejs .error{color:var(--error-color)!important}#conversejs .info{color:var(--info-color)}#conversejs .reg-feedback{font-size:85%;margin-bottom:1em}#conversejs #converse-login .conn-feedback,#conversejs .reg-feedback{display:block;text-align:center;width:100%}#conversejs .avatar{border-radius:var(--avatar-border-radius);border:var(--avatar-border);background-color:var(--avatar-background-color)}#conversejs .avatar-autocomplete{margin-right:.5em;vertical-align:middle}#conversejs .activated{display:block!important}#conversejs .form-help{color:var(--subdued-color);font-size:90%}#conversejs .form-control--labeled{margin-top:.5em}#conversejs .nav-pills .nav-link.active,#conversejs .nav-pills .show>.nav-link{background-color:var(--primary-color)}#conversejs .list-group-item.active{background-color:var(--primary-color);border-color:var(--primary-color-dark)}#conversejs .badge{text-shadow:none;color:#fff}#conversejs .badge-light{color:var(--text-color)}#conversejs .badge-primary,#conversejs .btn-primary,#conversejs .button-primary{background-color:var(--primary-color);border-color:transparent}#conversejs .badge-primary:active,#conversejs .badge-primary:focus,#conversejs .badge-primary:hover,#conversejs .btn-primary:active,#conversejs .btn-primary:focus,#conversejs .btn-primary:hover,#conversejs .button-primary:active,#conversejs .button-primary:focus,#conversejs .button-primary:hover{background-color:var(--primary-color-dark)!important;border-color:transparent!important}#conversejs .btn--transparent{background:0 0;border:none}#conversejs .btn-circle{width:30px;height:30px;text-align:center;padding:.5em 0;font-size:var(--font-size-small);line-height:1.428571429;border-radius:50%}#conversejs .btn.fa{color:#fff!important}#conversejs .badge-groupchat{background-color:var(--chatroom-badge-color);border-color:transparent}#conversejs .badge-groupchat:hover{background-color:var(--chatroom-badge-hover-color);border-color:transparent}#conversejs .badge-groupchat.active{background-color:var(--chatroom-badge-hover-color)!important;border-color:transparent!important}#conversejs .badge-info,#conversejs .btn-info{background-color:var(--primary-color);border-color:var(--primary-color)}#conversejs .badge-info:hover,#conversejs .btn-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}#conversejs .badge-secondary,#conversejs .btn-secondary,#conversejs .button-cancel{color:#fff;background-color:var(--secondary-color);border-color:var(--secondary-color)}#conversejs .badge-secondary:hover,#conversejs .btn-secondary:hover,#conversejs .button-cancel:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}#conversejs .btn-warning{color:#fff;background-color:var(--warning-color);border-color:var(--warning-color)}#conversejs .btn-warning:hover{color:#fff;background-color:var(--warning-color-dark);border-color:var(--warning-color-dark)}#conversejs .btn-danger{color:#fff;background-color:var(--danger-color);border-color:var(--danger-color)!important}#conversejs .btn-danger:hover{background-color:var(--danger-color-dark);border-color:var(--danger-color-dark)}@media screen and (max-width:575px){body .converse-brand{font-size:3.75em}#conversejs:not(.converse-embedded) .chatbox .chat-body{border-radius:var(--chatbox-border-radius)}#conversejs:not(.converse-embedded) .flyout{border-radius:var(--chatbox-border-radius)}}@media screen and (min-width:576px){#conversejs .offset-sm-2{margin-left:16.666667%}}@media screen and (min-width:768px){#conversejs .offset-md-2{margin-left:16.666667%}#conversejs .offset-md-3{margin-left:25%}}@media screen and (min-width:992px){#conversejs .offset-lg-2{margin-left:16.666667%}#conversejs .offset-lg-3{margin-left:25%}}@media screen and (min-width:1200px){#conversejs .offset-xl-2{margin-left:16.666667%}}@media screen and (max-height:450px){#conversejs{left:0}}#conversejs .btn--small{font-size:80%;font-weight:400}#conversejs form .hidden-username{opacity:0!important;height:0!important;padding:0!important}#conversejs form .error-feedback{margin-bottom:.5em}#conversejs form .form-check-label{margin-top:.3rem}#conversejs form .form-control::-moz-placeholder{color:var(--subdued-color)}#conversejs form .form-control:-ms-input-placeholder{color:var(--subdued-color)}#conversejs form .form-control::-ms-input-placeholder{color:var(--subdued-color)}#conversejs form .form-control::placeholder{color:var(--subdued-color)}#conversejs form .clear-input{margin-top:.5em;margin-bottom:.5em;position:absolute;right:.2em;cursor:pointer;font-size:var(--font-size)}#conversejs form#converse-login,#conversejs form#converse-register{background:var(--controlbox-pane-background-color)}#conversejs form#converse-login legend,#conversejs form#converse-register legend{width:100%;text-align:center;margin:0 auto .5em auto}#conversejs form#converse-login fieldset.buttons,#conversejs form#converse-register fieldset.buttons{text-align:center}#conversejs form#converse-login .login-anon,#conversejs form#converse-register .login-anon{height:auto;white-space:normal}#conversejs form#converse-login .save-submit,#conversejs form#converse-register .save-submit{color:var(--save-button-color)}#conversejs form#converse-login .form-url,#conversejs form#converse-register .form-url{display:block;font-weight:400;margin:1em 0}#conversejs form.converse-form{padding:1.2rem}#conversejs form.converse-form legend{color:var(--text-color);font-size:125%;margin-bottom:1.5em}#conversejs form.converse-form input[type=number],#conversejs form.converse-form input[type=password],#conversejs form.converse-form input[type=text],#conversejs form.converse-form select{min-width:50%}#conversejs form.converse-form input[type=button],#conversejs form.converse-form input[type=number],#conversejs form.converse-form input[type=password],#conversejs form.converse-form input[type=submit],#conversejs form.converse-form input[type=text]{padding:.5em}#conversejs form.converse-form input[type=button],#conversejs form.converse-form input[type=submit]{padding-left:1em;padding-right:1em;border:none}#conversejs form.converse-form input.error{border:1px solid var(--error-color);color:var(--text-color)}#conversejs form.converse-form .text-muted{color:var(--subdued-color)!important;font-size:85%;padding-top:.5em}#conversejs form.converse-form .text-muted a{color:var(--link-color-lighten-10-percent)}#conversejs form.converse-form .text-muted.error{color:var(--error-color)}#conversejs form.converse-form--modal{padding-bottom:0}#conversejs form.converse-centered-form{min-height:66%;text-align:center}#conversejs form.converse-centered-form input{max-width:30em;margin:auto}#conversejs .send-button{border-radius:0;bottom:var(--send-button-bottom);color:var(--inverse-link-color)}#conversejs .chatbox .send-button{background-color:var(--chat-head-color)}#conversejs .chatroom .send-button{background-color:var(--muc-toolbar-btn-color)}#conversejs .chat-toolbar .toolbar-buttons{width:100%;display:inline-block}#conversejs .chat-toolbar .toolbar-buttons .message-limit{padding:.5em;font-weight:700}#conversejs .chat-toolbar .unverified,#conversejs .chat-toolbar .unverified a{color:#cf5300}#conversejs .chat-toolbar .private,#conversejs .chat-toolbar .private a{color:#4b7003}#conversejs .chat-toolbar li{cursor:pointer;display:inline-block;list-style:none;padding:0 .5em}#conversejs .chat-toolbar li:hover{cursor:pointer}#conversejs .chat-toolbar li .toolbar-menu{background-color:#fff;bottom:1.7rem;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);height:auto;margin-bottom:0;min-width:21rem;position:absolute;right:0;top:auto;z-index:1000}#conversejs .chat-toolbar li .toolbar-menu.otr-menu{left:-6em;min-width:15rem}#conversejs .chat-toolbar li .toolbar-menu.otr-menu.show{display:flex;flex-direction:column}#conversejs .chat-toolbar li .toolbar-menu a{color:var(--link-color)}#conversejs .chat-toolbar li.toggle-otr ul{z-index:99}#conversejs .chat-toolbar li.toggle-otr ul li{display:block;padding:7px}#conversejs .chat-toolbar li.toggle-otr ul li:hover{background-color:var(--highlight-color)}#conversejs .chat-toolbar li.toggle-otr ul li a{display:block}#conversejs converse-chat-toolbar{background-color:#fff;box-sizing:border-box;display:flex;justify-content:space-between;margin:0;width:100%}#conversejs converse-chat-toolbar .fa,#conversejs converse-chat-toolbar .fa:hover,#conversejs converse-chat-toolbar .far,#conversejs converse-chat-toolbar .far:hover,#conversejs converse-chat-toolbar .fas,#conversejs converse-chat-toolbar .fas:hover{color:var(--chat-head-color);font-size:var(--font-size-large)}#conversejs converse-chat-toolbar .fa svg,#conversejs converse-chat-toolbar .fa:hover svg,#conversejs converse-chat-toolbar .far svg,#conversejs converse-chat-toolbar .far:hover svg,#conversejs converse-chat-toolbar .fas svg,#conversejs converse-chat-toolbar .fas:hover svg{fill:var(--chat-head-color)}#conversejs converse-chat-toolbar .unencrypted,#conversejs converse-chat-toolbar .unencrypted a{color:var(--text-color)}#conversejs converse-chat-toolbar .unencrypted .toolbar-menu a,#conversejs converse-chat-toolbar .unencrypted a .toolbar-menu a{color:var(--link-color)}#conversejs converse-chat-toolbar button{margin-top:.4em;border:1px transparent solid;background-color:transparent}#conversejs converse-chat-toolbar button.send-button{padding-top:.2em;padding-bottom:.2em;margin:0;margin-top:-1px}#conversejs .chatbox converse-chat-toolbar{border-top:var(--chatbox-message-input-border-top);color:var(--chat-toolbar-btn-color);background-color:#fff}#conversejs .chatbox converse-chat-toolbar .fa,#conversejs .chatbox converse-chat-toolbar .fa:hover,#conversejs .chatbox converse-chat-toolbar .far,#conversejs .chatbox converse-chat-toolbar .far:hover,#conversejs .chatbox converse-chat-toolbar .fas,#conversejs .chatbox converse-chat-toolbar .fas:hover{color:var(--chat-toolbar-btn-color)}#conversejs .chatbox converse-chat-toolbar button:focus{outline-color:var(--chat-toolbar-btn-color)!important}#conversejs .chatbox converse-chat-toolbar button:disabled .fa{color:var(--chat-toolbar-btn-disabled-color)}#conversejs .chatbox converse-chat-toolbar button:disabled .fa:hover{color:var(--chat-toolbar-btn-disabled-color)}#conversejs .chatbox converse-chat-toolbar button:disabled .fa svg,#conversejs .chatbox converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--chat-toolbar-btn-disabled-color)}#conversejs .chatroom converse-chat-toolbar{border-top:var(--chatroom-message-input-border-top);color:var(--muc-toolbar-btn-color)}#conversejs .chatroom converse-chat-toolbar .fa,#conversejs .chatroom converse-chat-toolbar .fa:hover,#conversejs .chatroom converse-chat-toolbar .far,#conversejs .chatroom converse-chat-toolbar .far:hover,#conversejs .chatroom converse-chat-toolbar .fas,#conversejs .chatroom converse-chat-toolbar .fas:hover{color:var(--muc-toolbar-btn-color);font-size:var(--font-size-large)}#conversejs .chatroom converse-chat-toolbar .fa svg,#conversejs .chatroom converse-chat-toolbar .fa:hover svg,#conversejs .chatroom converse-chat-toolbar .far svg,#conversejs .chatroom converse-chat-toolbar .far:hover svg,#conversejs .chatroom converse-chat-toolbar .fas svg,#conversejs .chatroom converse-chat-toolbar .fas:hover svg{fill:var(--muc-toolbar-btn-color)}#conversejs .chatroom converse-chat-toolbar button:focus{outline-color:var(--muc-toolbar-btn-color)!important}#conversejs .chatroom converse-chat-toolbar button:disabled .fa{color:var(--muc-toolbar-btn-disabled-color)}#conversejs .chatroom converse-chat-toolbar button:disabled .fa:hover{color:var(--muc-toolbar-btn-disabled-color)}#conversejs .chatroom converse-chat-toolbar button:disabled .fa svg,#conversejs .chatroom converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--muc-toolbar-btn-disabled-color)}#conversejs.converse-overlayed .chat-toolbar li .toolbar-menu{min-width:235px}#conversejs.converse-overlayed .chatroom .chat-toolbar li .toolbar-menu{min-width:280px}#conversejs .chatbox-navback{display:none}#conversejs .flyout{position:absolute}@media screen and (max-height:450px){#conversejs .flyout{border-radius:0}}@media screen and (max-width:480px){#conversejs .flyout{border-radius:0}}@media screen and (max-height:450px){#conversejs .flyout{bottom:0}}@media screen and (max-width:480px){#conversejs .flyout{bottom:0}}#conversejs .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}#conversejs .chatbox-btn:active{position:relative;top:1px}#conversejs .chat-head{display:flex;flex-direction:row;color:#fff;font-size:100%;margin:0;padding:0;position:relative}#conversejs .chat-head.chat-head-chatbox{background-color:var(--chat-head-color)}#conversejs .chat-head .avatar{margin-right:.5em}#conversejs .chat-head .chat-head__desc{color:var(--chat-head-color-lighten-50-percent);font-size:var(--font-size-small);margin:0;overflow:hidden;padding:.5rem 1rem .5rem 1rem;text-overflow:ellipsis;width:100%;max-height:5em}#conversejs .chat-head .chatbox-title{padding:.75rem 1rem 0 1rem;display:flex;flex-direction:row;justify-content:space-between;width:100%}#conversejs .chat-head .chatbox-title--no-desc{padding:.75rem 1rem}#conversejs .chat-head .chatbox-title--row{display:flex;flex-direction:row;overflow:hidden}#conversejs .chat-head .chatbox-title__text{overflow:hidden;text-overflow:ellipsis}#conversejs .chat-head .chatbox-title__buttons{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;padding:0}#conversejs .chat-head a.chatbox-btn.fa,#conversejs .chat-head a.chatbox-btn.far,#conversejs .chat-head a.chatbox-btn.fas,#conversejs .chat-head a:hover.chatbox-btn.fa,#conversejs .chat-head a:hover.chatbox-btn.far,#conversejs .chat-head a:hover.chatbox-btn.fas,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.far,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fas,#conversejs .chat-head a:visited.chatbox-btn.fa,#conversejs .chat-head a:visited.chatbox-btn.far,#conversejs .chat-head a:visited.chatbox-btn.fas{color:#fff}#conversejs .chat-head a.chatbox-btn.fa.button-on:before,#conversejs .chat-head a.chatbox-btn.far.button-on:before,#conversejs .chat-head a.chatbox-btn.fas.button-on:before,#conversejs .chat-head a:hover.chatbox-btn.fa.button-on:before,#conversejs .chat-head a:hover.chatbox-btn.far.button-on:before,#conversejs .chat-head a:hover.chatbox-btn.fas.button-on:before,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.far.button-on:before,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fas.button-on:before,#conversejs .chat-head a:visited.chatbox-btn.fa.button-on:before,#conversejs .chat-head a:visited.chatbox-btn.far.button-on:before,#conversejs .chat-head a:visited.chatbox-btn.fas.button-on:before{padding:.2em;background-color:var(--chat-head-text-color);color:var(--chat-head-color)}#conversejs .chat-head .chatbox-btn{color:#fff}#conversejs .chat-head .chatbox-btn.fa,#conversejs .chat-head .chatbox-btn.far,#conversejs .chat-head .chatbox-btn.fas{color:#fff}#conversejs .chat-head .chatbox-btn:active{position:relative;top:1px}#conversejs .chat-head .chatbox-btn.button-on:before{border-radius:5%;background-color:var(--chat-head-text-color);color:var(--chat-head-color)}#conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height:450px){#conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width:480px){#conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}#conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height:450px){#conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){#conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}#conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}#conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}#conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-head-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0}@media screen and (max-height:450px){#conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width:480px){#conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}#conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}#conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}#conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}#conversejs .chatbox .chat-content converse-chat-content{display:flex;flex-direction:column;height:100%;justify-content:space-between}#conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}#conversejs .chatbox .chat-content .chat-content__help{border-top:1px solid var(--chat-head-color);max-height:100%}#conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}#conversejs .chatbox .chat-content .chat-content__help converse-chat-help{height:100%;overflow-y:auto;display:block;padding:.5em 0}#conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}#conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}#conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}#conversejs .chatbox .chat-content .chat-content__notifications:before{content:" "}#conversejs .chatbox .chat-content video{width:100%}#conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}#conversejs .chatbox .chat-content-sendbutton{height:calc(100% - (var(--chat-textarea-height) + var(--send-button-height) + 2 * var(--send-button-margin)))}#conversejs .chatbox .dropdown{background-color:var(--light-background-color)}#conversejs .chatbox .dropdown dd{margin:0;padding:0;position:relative}#conversejs .chatbox .sendXMPPMessage{-moz-background-clip:padding;-webkit-background-clip:padding-box;border-bottom-radius:var(--chatbox-border-radius);background-clip:padding-box;background-color:#fff;border:0;margin:0;padding:0}@media screen and (max-height:450px){#conversejs .chatbox .sendXMPPMessage{width:100%}}@media screen and (max-width:480px){#conversejs .chatbox .sendXMPPMessage{width:100%}}#conversejs .chatbox .sendXMPPMessage .suggestion-box__results:after{display:none}#conversejs .chatbox .sendXMPPMessage .spoiler-hint{width:100%}#conversejs .chatbox .sendXMPPMessage .chat-textarea:active,#conversejs .chatbox .sendXMPPMessage .chat-textarea:focus,#conversejs .chatbox .sendXMPPMessage input:active,#conversejs .chatbox .sendXMPPMessage input:focus{outline-color:var(--chat-head-color)}#conversejs .chatbox .sendXMPPMessage .chat-textarea.correcting,#conversejs .chatbox .sendXMPPMessage input.correcting{background-color:var(--chat-correcting-color)}#conversejs .chatbox .sendXMPPMessage .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);border-top-left-radius:0;border-top-right-radius:0;border-bottom-radius:var(--chatbox-border-radius);padding-left:.5em;padding-right:4.5em;padding-top:.5em;padding-bottom:.5em;width:100%;border:none;min-height:var(--chat-textarea-height);margin-bottom:-4px;resize:none}#conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler{height:42px}#conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}#conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}#conversejs .chatbox .dragresize-left,#conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}#conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}#conversejs.converse-embedded .controlbox-head,#conversejs.converse-overlayed .controlbox-head{padding:.5em}#conversejs.converse-embedded .chat-head,#conversejs.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}#conversejs.converse-embedded .chatbox,#conversejs.converse-overlayed .chatbox{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}#conversejs.converse-embedded .chatbox .box-flyout,#conversejs.converse-overlayed .chatbox .box-flyout{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}#conversejs.converse-overlayed .box-flyout,#conversejs.converse-overlayed .chat-head{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius)}@media screen and (max-height:450px){#conversejs.converse-overlayed .box-flyout,#conversejs.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}@media screen and (max-width:480px){#conversejs.converse-overlayed .box-flyout,#conversejs.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}#conversejs.converse-overlayed .flyout{bottom:var(--overlayed-chatbox-hover-height)}#conversejs.converse-overlayed .box-flyout{height:var(--overlayed-chat-height);min-height:calc(var(--overlayed-chat-height)/ 2)}#conversejs.converse-overlayed .chat-head{min-height:var(--overlayed-chat-head-height)}#conversejs.converse-overlayed .minimized-chats-flyout .chat-head{cursor:default}#conversejs.converse-overlayed .chat-textarea{max-height:var(--overlayed-max-chat-textarea-height)}#conversejs.converse-overlayed .chatbox .chat-body{height:calc(100% - var(--overlayed-chat-head-height))}#conversejs.converse-overlayed .chatbox .chatbox-title{padding:.5rem .75rem 0 .75rem}#conversejs.converse-overlayed .chatbox .chatbox-title--no-desc{padding:.5rem .75rem}#conversejs.converse-overlayed .chatbox converse-dropdown .btn--standalone{padding:0 .2em;margin:0 0 0 .5em}@media (max-width:767.98px){#conversejs.converse-overlayed>.row{flex-direction:column}#conversejs.converse-overlayed>.row.no-gutters{margin:-1em}}#conversejs.converse-embedded .flyout,#conversejs.converse-fullscreen .flyout{border-radius:0;border:none;bottom:0}#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{margin:0;position:relative;width:100%;padding-right:15px;padding-left:15px}#conversejs.converse-embedded .chatbox .box-flyout,#conversejs.converse-fullscreen .chatbox .box-flyout{box-shadow:none;overflow:hidden}@media (min-width:768px){#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{flex:0 0 66.66667%;max-width:66.66667%}}@media (min-width:992px){#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{flex:0 0 75%;max-width:75%}}@media (min-width:1200px){#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{flex:0 0 83.33333%;max-width:83.33333%}}#conversejs.converse-embedded.converse-singleton .flyout,#conversejs.converse-fullscreen.converse-singleton .flyout{border:none!important}#conversejs.converse-embedded.converse-singleton .chat-head,#conversejs.converse-fullscreen.converse-singleton .chat-head{padding:.5em}#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{margin:0;position:relative;width:100%;padding-right:15px;padding-left:15px}@media (min-width:768px){#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media (min-width:992px){#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media (min-width:1200px){#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}#conversejs.converse-embedded .chat-head{font-size:var(--font-size-huge)}#conversejs.converse-embedded .converse-chatboxes{z-index:1031;position:inherit;flex-wrap:nowrap;bottom:auto;height:100%;width:100%;margin-left:-15px}#conversejs.converse-embedded .chatbox .box-flyout{bottom:0;height:100%;min-width:auto;width:100%}#conversejs.converse-embedded .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}#conversejs.converse-fullscreen .chatbox-btn{font-size:var(--fullpage-chatbox-button-size);margin:0 .3em}#conversejs.converse-fullscreen .chat-head{font-size:var(--font-size-huge)}#conversejs.converse-fullscreen .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}#conversejs.converse-fullscreen .chatbox .box-flyout{box-shadow:none;height:var(--fullpage-chat-height);min-height:calc(var(--fullpage-chat-height)/ 2);width:var(--fullpage-chat-width);overflow:hidden}#conversejs.converse-fullscreen .chatbox .chat-body{height:inherit;overflow:hidden;background-color:var(--chat-head-color)}#conversejs.converse-fullscreen .chatbox .chat-title{font-size:var(--font-size-huge);line-height:var(--line-height-huge)}#conversejs.converse-fullscreen .chatbox .sendXMPPMessage ul{width:100%}@media (max-width:767.98px){#conversejs:not(.converse-embedded)>.row{flex-direction:row-reverse}#conversejs:not(.converse-embedded) #converse-login-panel .converse-form{padding:3em 2em 3em}#conversejs:not(.converse-embedded) .chatbox{width:calc(100% - 50px)}#conversejs:not(.converse-embedded) .chatbox .row .box-flyout{left:50px;bottom:0;height:var(--fullpage-chat-height);box-shadow:none}#conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback,#conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback,#conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback{margin:auto 0;margin-right:1em;display:flex}#conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,#conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,#conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before{color:#fff}}#conversejs .oauth-providers{text-align:center}#conversejs .oauth-providers .oauth-provider{margin:1em 0}#conversejs .oauth-providers .oauth-provider .oauth-login{margin-left:0;color:var(--link-color);font-size:var(--font-size-large)}#conversejs .oauth-providers .oauth-provider .oauth-login:hover{color:var(--link-hover-color)}#conversejs .oauth-providers .oauth-provider .oauth-login i{color:var(--link-color);font-size:var(--font-size-huge);margin-right:.5em}#conversejs .set-xmpp-status .chat-status--online,#conversejs .xmpp-status .chat-status--online{color:var(--chat-status-online)}#conversejs .set-xmpp-status .chat-status--busy,#conversejs .xmpp-status .chat-status--busy{color:var(--chat-status-busy)}#conversejs .set-xmpp-status .chat-status--away,#conversejs .xmpp-status .chat-status--away{color:var(--chat-status-away)}#conversejs .set-xmpp-status .fa-times-circle,#conversejs .set-xmpp-status .far.fa-circle,#conversejs .xmpp-status .fa-times-circle,#conversejs .xmpp-status .far.fa-circle{color:var(--subdued-color)}#conversejs .set-xmpp-status .chat-status{padding-right:.5em}#conversejs .room-info{font-size:var(--font-size-small);font-style:normal;font-weight:400}#conversejs .room-info li.room-info{display:block;margin-left:5px}#conversejs .room-info p.room-info{line-height:var(--line-height);margin:0;display:block;white-space:normal}#conversejs div.room-info{padding:.3em 0;clear:left;width:100%}#conversejs #controlbox{order:-1;color:var(--controlbox-text-color);margin-right:calc(3 * var(--chat-gutter))}#conversejs #controlbox converse-brand-heading{width:100%;display:block}#conversejs #controlbox .brand-name-wrapper{font-size:200%}#conversejs #controlbox .brand-name-wrapper--fullscreen{font-size:100%}#conversejs #controlbox .open-rooms-toggle,#conversejs #controlbox .open-rooms-toggle .fa{color:var(--groupchats-header-color)!important}#conversejs #controlbox .open-rooms-toggle .fa:hover,#conversejs #controlbox .open-rooms-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}#conversejs #controlbox .box-flyout{background-color:var(--controlbox-pane-background-color)}#conversejs #controlbox.logged-out .box-flyout .controlbox-pane{overflow-y:auto}#conversejs #controlbox form.search-xmpp-contact{margin:0;padding-left:5px;padding:0 0 5px 5px}#conversejs #controlbox form.search-xmpp-contact input{width:8em}#conversejs #controlbox .msgs-indicator{margin-right:.5em}#conversejs #controlbox a.subscribe-to-user{padding-left:2em;font-weight:700}#conversejs #controlbox #converse-register{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-timing-function:ease;animation-timing-function:ease;background-color:var(--controlbox-pane-background-color)}#conversejs #controlbox #converse-register .title{font-weight:700}#conversejs #controlbox #converse-register .info{color:green;font-size:90%;margin:1.5em 0}#conversejs #controlbox #converse-register .form-errors{color:var(--error-color);margin:1em 0}#conversejs #controlbox #converse-register .provider-title{font-size:var(--font-size-huge);margin:0}#conversejs #controlbox #converse-register .provider-score{width:178px;margin-bottom:8px}#conversejs #controlbox #converse-register .form-help .url{font-weight:700;color:var(--link-color)}#conversejs #controlbox #converse-register .input-group{display:table;margin:auto;width:100%}#conversejs #controlbox #converse-register .input-group span{overflow-x:hidden;text-overflow:ellipsis;max-width:110px}#conversejs #controlbox #converse-register .input-group input[name=username],#conversejs #controlbox #converse-register .input-group span{display:table-cell;text-align:left}#conversejs #controlbox #converse-register .instructions{color:gray;font-size:85%}#conversejs #controlbox #converse-register .instructions:hover{color:var(--controlbox-text-color)}#conversejs #controlbox .conn-feedback{color:var(--controlbox-head-color)}#conversejs #controlbox .conn-feedback.error{color:var(--error-color)}#conversejs #controlbox .conn-feedback p{padding-bottom:1em}#conversejs #controlbox .conn-feedback p.feedback-subject.error{font-weight:700}#conversejs #controlbox #converse-login-panel,#conversejs #controlbox #converse-register-panel{padding-top:0;padding-bottom:0}#conversejs #controlbox #converse-login-panel{flex-direction:row}#conversejs #controlbox .toggle-register-login{font-weight:700}#conversejs #controlbox .controlbox-pane .userinfo{padding-bottom:1em}#conversejs #controlbox .controlbox-pane .userinfo .username{margin-left:.5em;overflow:hidden;text-overflow:ellipsis}#conversejs #controlbox .controlbox-pane .userinfo .profile{margin-bottom:.75em}#conversejs #controlbox #chatrooms{padding:0}#conversejs #controlbox #chatrooms .add-chatroom{margin:0;padding:0}#conversejs #controlbox #chatrooms .add-chatroom input[type=button],#conversejs #controlbox #chatrooms .add-chatroom input[type=submit],#conversejs #controlbox #chatrooms .add-chatroom input[type=text]{width:100%}#conversejs #controlbox .controlbox-section .controlbox-heading{font-family:var(--heading-font);color:var(--controlbox-heading-color);font-weight:var(--controlbox-heading-font-weight);padding:0;font-size:1.1em;line-height:1.1em;text-transform:uppercase}#conversejs #controlbox .controlbox-section .controlbox-heading--groupchats{color:var(--groupchats-header-color)}#conversejs #controlbox .controlbox-section .controlbox-heading--contacts{color:var(--chat-head-color-dark)}#conversejs #controlbox .controlbox-section .controlbox-heading--headline{color:var(--headline-head-color)}#conversejs #controlbox .controlbox-section .controlbox-heading__btn{cursor:pointer;font-size:1em;padding:0;margin:var(--controlbox-heading-top-margin) 0 var(--inline-action-margin) 0;min-width:25px;text-align:center}#conversejs #controlbox .controlbox-section .controlbox-heading__btn.fa-vcard{margin-top:1em}#conversejs #controlbox .dropdown a{width:143px;display:inline-block}#conversejs #controlbox .dropdown li{list-style:none;padding-left:0}#conversejs #controlbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;width:100%;z-index:21;background-color:var(--light-background-color)}#conversejs #controlbox .dropdown dd ul li:hover{background-color:var(--highlight-color)}#conversejs #controlbox .dropdown dd.search-xmpp{height:0}#conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container{position:absolute;z-index:22}#conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container form{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4);background-color:#fff}#conversejs #controlbox .dropdown dd.search-xmpp li:hover{background-color:var(--light-background-color)}#conversejs #controlbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}#conversejs #controlbox .controlbox-panes{background-color:var(--controlbox-pane-background-color);border-right:.2143rem solid var(--panel-divider-color);height:100%;overflow-y:auto}#conversejs #controlbox .controlbox-subtitle{font-size:90%;padding:.5em;text-align:right}#conversejs #controlbox .controlbox-pane{background-color:var(--controlbox-pane-background-color);border:0;font-size:var(--font-size);left:0;text-align:left;overflow-x:hidden;padding:0 0 1em 0}#conversejs #controlbox .controlbox-pane .controlbox-padded{padding-left:1em;padding-right:1em;align-items:center;line-height:normal}#conversejs #controlbox .controlbox-pane .controlbox-padded .change-status{min-width:25px;text-align:center}#conversejs #controlbox .controlbox-pane .add-converse-contact{margin:0 0 .75em 0}#conversejs #controlbox .controlbox-pane .chatbox-btn{margin:0}#conversejs #controlbox .controlbox-pane .switch-form{text-align:center;padding:2em 0}#conversejs #controlbox .controlbox-pane .switch-form p{margin-top:.5em}#conversejs #controlbox .controlbox-pane dd{margin-left:0;margin-bottom:0}#conversejs #controlbox .controlbox-pane dd.odd{background-color:#dceac5}#conversejs #controlbox .add-xmpp-contact{padding:1em .5em}#conversejs #controlbox .add-xmpp-contact input{margin:0 0 1rem;width:100%}#conversejs #controlbox .add-xmpp-contact button{width:100%}#conversejs.converse-overlayed .toggle-controlbox{order:-1;text-align:center;background-color:var(--link-color);border-top-left-radius:var(--button-border-radius);border-top-right-radius:var(--button-border-radius);color:#0a0a0a;float:right;height:100%;margin:0 var(--chat-gutter);padding:1em}#conversejs.converse-overlayed .toggle-controlbox span{color:var(--inverse-link-color)}#conversejs.converse-overlayed #controlbox{min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}#conversejs.converse-overlayed #controlbox .box-flyout{min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}#conversejs.converse-overlayed #controlbox .login-trusted{white-space:nowrap;font-size:90%}#conversejs.converse-overlayed #controlbox #converse-login-trusted{margin-top:.5em}#conversejs.converse-overlayed #controlbox:not(.logged-out) .controlbox-head{height:15px}#conversejs.converse-overlayed #controlbox .controlbox-head{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;justify-content:space-between;min-height:0}#conversejs.converse-overlayed #controlbox .controlbox-head .brand-heading{color:var(--controlbox-text-color);font-size:2em}#conversejs.converse-overlayed #controlbox .controlbox-head .chatbox-btn{color:var(--controlbox-head-color);margin:0}#conversejs.converse-overlayed #controlbox #converse-login,#conversejs.converse-overlayed #controlbox #converse-register{flex:0 0 100%;max-width:100%;padding-bottom:0}#conversejs.converse-overlayed #controlbox #converse-register .button-cancel{font-size:90%}#conversejs.converse-overlayed #controlbox .controlbox-panes{border-radius:var(--chatbox-border-radius)}#conversejs.converse-embedded .toggle-controlbox,#conversejs.converse-fullscreen .toggle-controlbox{display:none}#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{position:relative;width:100%;padding-right:15px;padding-left:15px;margin:0}@media (min-width:768px){#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{flex:0 0 33.33333%;max-width:33.33333%}}@media (min-width:992px){#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{flex:0 0 25%;max-width:25%}}@media (min-width:1200px){#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{flex:0 0 16.66667%;max-width:16.66667%}}#conversejs.converse-embedded #controlbox.logged-out,#conversejs.converse-fullscreen #controlbox.logged-out,#conversejs.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%}#conversejs.converse-embedded #controlbox .controlbox-pane,#conversejs.converse-fullscreen #controlbox .controlbox-pane,#conversejs.converse-mobile #controlbox .controlbox-pane{border-radius:0}#conversejs.converse-embedded #controlbox .flyout,#conversejs.converse-fullscreen #controlbox .flyout,#conversejs.converse-mobile #controlbox .flyout{border-radius:0}#conversejs.converse-embedded #controlbox #converse-login-panel,#conversejs.converse-fullscreen #controlbox #converse-login-panel,#conversejs.converse-mobile #controlbox #converse-login-panel{border-radius:0}#conversejs.converse-embedded #controlbox #converse-login-panel .converse-form,#conversejs.converse-fullscreen #controlbox #converse-login-panel .converse-form,#conversejs.converse-mobile #controlbox #converse-login-panel .converse-form{padding:3em 2em 3em}#conversejs.converse-embedded #controlbox .toggle-register-login,#conversejs.converse-fullscreen #controlbox .toggle-register-login,#conversejs.converse-mobile #controlbox .toggle-register-login{line-height:var(--line-height-huge)}#conversejs.converse-embedded #controlbox converse-brand-heading,#conversejs.converse-fullscreen #controlbox converse-brand-heading,#conversejs.converse-mobile #controlbox converse-brand-heading{flex:0 0 100%;max-width:100%;margin-top:5em;margin-bottom:1em}#conversejs.converse-embedded #controlbox converse-brand-heading .brand-heading,#conversejs.converse-fullscreen #controlbox converse-brand-heading .brand-heading,#conversejs.converse-mobile #controlbox converse-brand-heading .brand-heading{font-size:500%;padding:.7em 0 0 0;opacity:.8;color:var(--brand-heading-color)}#conversejs.converse-embedded #controlbox converse-brand-heading .brand-subtitle,#conversejs.converse-fullscreen #controlbox converse-brand-heading .brand-subtitle,#conversejs.converse-mobile #controlbox converse-brand-heading .brand-subtitle{font-size:90%;padding:.5em}@media screen and (max-width:480px){#conversejs.converse-embedded #controlbox converse-brand-heading .brand-heading,#conversejs.converse-fullscreen #controlbox converse-brand-heading .brand-heading,#conversejs.converse-mobile #controlbox converse-brand-heading .brand-heading{font-size:300%}}#conversejs.converse-embedded #controlbox.logged-out,#conversejs.converse-fullscreen #controlbox.logged-out,#conversejs.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%;opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-timing-function:ease;animation-timing-function:ease;width:100%}#conversejs.converse-embedded #controlbox.logged-out .box-flyout,#conversejs.converse-fullscreen #controlbox.logged-out .box-flyout,#conversejs.converse-mobile #controlbox.logged-out .box-flyout{width:100%}#conversejs.converse-embedded #controlbox .box-flyout,#conversejs.converse-fullscreen #controlbox .box-flyout,#conversejs.converse-mobile #controlbox .box-flyout{border:0;width:100%;z-index:1;background-color:var(--controlbox-head-color)}#conversejs.converse-embedded #controlbox .box-flyout .controlbox-head,#conversejs.converse-fullscreen #controlbox .box-flyout .controlbox-head,#conversejs.converse-mobile #controlbox .box-flyout .controlbox-head{display:none}#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{position:relative;width:100%;padding-right:15px;padding-left:15px;flex:0 0 66.66667%;max-width:66.66667%;margin-left:16.66667%}@media (min-width:576px){#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{flex:0 0 66.66667%;max-width:66.66667%;margin-left:16.66667%}}@media (min-width:768px){#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{flex:0 0 66.66667%;max-width:66.66667%;margin-left:16.66667%}}@media (min-width:992px){#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{flex:0 0 50%;max-width:50%;margin-left:25%}}#conversejs.converse-embedded #controlbox #converse-login .instructions,#conversejs.converse-embedded #controlbox #converse-login .title,#conversejs.converse-embedded #controlbox #converse-register .instructions,#conversejs.converse-embedded #controlbox #converse-register .title,#conversejs.converse-fullscreen #controlbox #converse-login .instructions,#conversejs.converse-fullscreen #controlbox #converse-login .title,#conversejs.converse-fullscreen #controlbox #converse-register .instructions,#conversejs.converse-fullscreen #controlbox #converse-register .title,#conversejs.converse-mobile #controlbox #converse-login .instructions,#conversejs.converse-mobile #controlbox #converse-login .title,#conversejs.converse-mobile #controlbox #converse-register .instructions,#conversejs.converse-mobile #controlbox #converse-register .title{margin:1em 0}#conversejs.converse-embedded #controlbox #converse-login input[type=button],#conversejs.converse-embedded #controlbox #converse-login input[type=submit],#conversejs.converse-embedded #controlbox #converse-register input[type=button],#conversejs.converse-embedded #controlbox #converse-register input[type=submit],#conversejs.converse-fullscreen #controlbox #converse-login input[type=button],#conversejs.converse-fullscreen #controlbox #converse-login input[type=submit],#conversejs.converse-fullscreen #controlbox #converse-register input[type=button],#conversejs.converse-fullscreen #controlbox #converse-register input[type=submit],#conversejs.converse-mobile #controlbox #converse-login input[type=button],#conversejs.converse-mobile #controlbox #converse-login input[type=submit],#conversejs.converse-mobile #controlbox #converse-register input[type=button],#conversejs.converse-mobile #controlbox #converse-register input[type=submit]{width:auto}@media (max-width:767.98px){#conversejs{left:0;right:0;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}#conversejs .converse-chatboxes{margin:0!important;flex-direction:row!important;justify-content:space-between}#conversejs .converse-chatboxes .converse-chatroom{font-size:14px}#conversejs .converse-chatboxes .chatbox .box-flyout{margin-left:15px;left:0;bottom:0;border-radius:0;width:100vw!important;height:var(--fullpage-chat-height)}#conversejs .converse-chatboxes #controlbox{width:100vw!important}#conversejs .converse-chatboxes #controlbox .box-flyout{width:100vw!important;height:var(--fullpage-chat-height);margin-right:-15px}#conversejs .converse-chatboxes #controlbox .sidebar{display:block}#conversejs .converse-chatboxes.sidebar-open .chatbox:not(#controlbox){display:none}#conversejs .converse-chatboxes.sidebar-open #controlbox .controlbox-pane{display:block}}#conversejs.converse-fullscreen .controlbox-panes{padding-top:1em}#conversejs.converse-overlayed .brand-heading{padding-top:.8rem;padding-left:.8rem;width:100%}#conversejs.converse-overlayed .converse-svg-logo{height:1em}#conversejs.converse-overlayed #controlbox #converse-login-panel{height:100%}#conversejs.converse-overlayed #controlbox .controlbox-panes{margin-top:.5em}#conversejs #converse-modals .modal{background-color:rgba(0,0,0,.4)}#conversejs #converse-modals .modal .modal-body{overflow-y:auto;max-height:75vh;margin-bottom:2em}#conversejs #converse-modals .modal .modal-body p{padding:.25rem 0}#conversejs #converse-modals .modal .modal-body .confirm .form-group p:first-child{font-size:110%;font-weight:700}#conversejs #converse-modals .modal .modal-body.fit-content{box-sizing:content-box}#conversejs #converse-modals .modal .modal-body.fit-content img{max-width:90vw}#conversejs #converse-modals .modal .modal-body--image .chat-image{max-height:99%;max-width:100%}#conversejs #converse-modals .modal .modal-footer{justify-content:flex-start}#conversejs #converse-modals .modal .roomid-policy-error{color:var(--error-color);font-size:var(--font-size-small);float:right}#conversejs #converse-modals .scrollable-container{max-height:45vh;overflow-y:auto}#conversejs #converse-modals .affiliation-form,#conversejs #converse-modals .role-form{padding:2em 0 1em 0}#conversejs #converse-modals .set-xmpp-status{margin:1em}#conversejs #converse-modals .set-xmpp-status .custom-control-label{padding-top:.25em}#conversejs #converse-modals #omemo-tabpanel{margin-top:1em}#conversejs #converse-modals .btn{font-weight:400}#conversejs #converse-modals #user-profile-modal .profile-form label{font-weight:700}#conversejs #converse-modals #user-profile-modal .fingerprint-removal label{display:flex;padding:.75rem 1.25rem}#conversejs #converse-modals #user-profile-modal .list-group-item{display:flex;justify-content:left;font-size:95%}#conversejs #converse-modals #user-profile-modal .list-group-item input[type=checkbox]{margin-right:1em}#conversejs #converse-modals .fingerprints{width:100%;margin-bottom:1em}#conversejs #converse-modals .fingerprint-trust{display:flex;justify-content:space-between;font-size:95%}#conversejs #converse-modals .fingerprint-trust .fingerprint{margin-left:1em}#conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:0;height:var(--roster-height);padding:0;overflow:hidden;height:calc(100% - 70px)}#conversejs #converse-roster #online-count{display:none}#conversejs #converse-roster .search-xmpp ul li.chat-info{padding-left:10px}#conversejs #converse-roster .roster-filter-form{width:100%}#conversejs #converse-roster .roster-filter-form .button-group{padding:.2em}#conversejs #converse-roster .roster-filter-form span{padding:.3em;cursor:pointer;min-width:25px;text-align:center}#conversejs #converse-roster .roster-filter-form .roster-filter{width:100%;margin:.2em;font-size:calc(var(--font-size) - 2px)}#conversejs #converse-roster .roster-filter-form .state-type{font-size:calc(var(--font-size) - 2px);width:100%}#conversejs #converse-roster .roster-contacts{padding:0;margin:0 0 .2em 0;height:100%;overflow-x:hidden;overflow-y:auto}#conversejs #converse-roster .roster-contacts .roster-group{border:none;color:var(--text-color);font-weight:400;text-shadow:0 1px 0 var(--text-shadow-color);margin:.75em 0 .75em 0}#conversejs #converse-roster .roster-contacts .roster-group .group-toggle{font-family:var(--heading-font);display:block;width:100%;padding-top:0;padding-bottom:.3rem}#conversejs #converse-roster .roster-contacts .roster-group .group-toggle,#conversejs #converse-roster .roster-contacts .roster-group .group-toggle .fa{color:var(--chat-head-color-dark)!important}#conversejs #converse-roster .roster-contacts .roster-group .group-toggle .fa:hover,#conversejs #converse-roster .roster-contacts .roster-group .group-toggle:hover{color:var(--chat-head-color-darker)!important}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact{margin:.25em 0}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status{vertical-align:middle;font-size:.6em;margin-right:0;margin-left:-.7em;margin-bottom:-1.5em;border-radius:50%;border:2px solid var(--occupants-background-color)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--offline{margin-right:.8em}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--online{color:var(--chat-status-online)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--busy{color:var(--chat-status-busy)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--away{color:var(--chat-status-away)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--offline{display:none}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .fa-times-circle,#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .far.fa-circle{color:var(--subdued-color)}#conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a{line-height:var(--line-height)}#conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact .req-contact-name{padding:0 .2em 0 0}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat{margin:0;padding:0}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs{font-weight:700}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs .contact-name{width:70%}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .msgs-indicator{color:#fff;background-color:var(--chat-head-color);opacity:1;border-radius:10%;padding:.2em .4em;font-size:var(--font-size-small)}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding:0;margin:0;max-width:85%;float:none;height:100%}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name.unread-msgs{max-width:60%}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name.contact-name--offline{margin-left:.7em}#conversejs #converse-roster .roster-contacts .roster-group li.odd{background-color:#dceac5}#conversejs #converse-roster .roster-contacts .roster-group li a,#conversejs #converse-roster .roster-contacts .roster-group li span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#conversejs #converse-roster .roster-contacts .roster-group li .span{display:inline-block}#conversejs #converse-roster .roster-contacts .roster-group li .decline-xmpp-request{margin-left:5px}#conversejs #converse-roster .roster-contacts .roster-group li:hover{background-color:var(controlbox-pane-bg-hover-color)}#conversejs #converse-roster span.pending-contact-name{line-height:var(--line-height);width:100%}#conversejs .list-container{text-align:left;padding:.3em 0}#conversejs .list-container .list-toggle{font-family:var(--heading-font);font-weight:var(--list-toggle-font-weight);display:block;color:var(--list-toggle-color);padding:0 0 .5rem 0}#conversejs .list-container .list-toggle:hover{color:var(--list-toggle-hover-color)}#conversejs .items-list{text-align:left}#conversejs .items-list .list-item{border:none;clear:both;color:var(--text-color);overflow:hidden;padding:.5em 0;text-shadow:0 1px 0 var(--text-shadow-color);word-wrap:break-word;height:2.5em}#conversejs .items-list .list-item.unread-msgs{font-weight:700}#conversejs .items-list .list-item .list-item-link{color:var(--list-item-link-color);margin:auto;font-size:var(--font-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;vertical-align:baseline}#conversejs .items-list .list-item .list-item-link:hover{color:var(--list-item-link-hover-color)}#conversejs .items-list .list-item .list-item-badge{opacity:1;border-radius:25%;color:#fff;font-size:var(--font-size-small);line-height:var(--font-size-small)}#conversejs .items-list .list-item .list-item-action{opacity:0;font-size:var(--font-size-tiny);padding:.3em 0 0 0;margin:0 0 0 var(--inline-action-margin);width:2em;height:2em;color:var(--subdued-color)}#conversejs .items-list .list-item .list-item-action:before{font-size:var(--font-size)}#conversejs .items-list .list-item .list-item-action.button-on{color:var(--list-item-link-color)}#conversejs .items-list .list-item .list-item-action.button-on:hover{color:var(--list-item-link-hover-color)}#conversejs .items-list .list-item .list-item-action:hover{color:var(--list-toggle-hover-color);opacity:1}#conversejs .items-list .list-item .list-item-action--visible{opacity:1!important}#conversejs .items-list .list-item.open{background-color:var(--list-item-open-color)}#conversejs .items-list .list-item.open:hover{background-color:var(--list-item-open-hover-color)!important}#conversejs .items-list .list-item.open a{color:#fff}#conversejs .items-list .list-item.open .list-item-link:hover{color:#fff}#conversejs .items-list .list-item.open .list-item-action{color:var(--list-item-action-color)}#conversejs .items-list .list-item.open .list-item-action:hover{color:#fff}#conversejs .items-list .list-item:hover{background-color:var(--controlbox-pane-bg-hover-color)}#conversejs .items-list .list-item:hover .fa,#conversejs .items-list .list-item:hover .far,#conversejs .items-list .list-item:hover .fas{opacity:1}#conversejs .badge--muc,#conversejs.converse-embedded .badge--muc{background-color:var(--groupchats-header-color)}#conversejs .add-chatroom input[type=button],#conversejs .add-chatroom input[type=submit],#conversejs.converse-embedded .add-chatroom input[type=button],#conversejs.converse-embedded .add-chatroom input[type=submit]{margin:.3em 0}#conversejs #room-details-modal .features-list,#conversejs.converse-embedded #room-details-modal .features-list{margin-left:1em}#conversejs .chatroom-features,#conversejs.converse-embedded .chatroom-features{width:100%}#conversejs .chatroom-features .features-list,#conversejs.converse-embedded .chatroom-features .features-list{padding-top:0}#conversejs .chatroom-features .features-list .feature,#conversejs.converse-embedded .chatroom-features .features-list .feature{width:100%;margin-right:.5em;padding-right:0;font-size:1em;cursor:help}#conversejs .chatroom-features .features-list .feature .fa,#conversejs.converse-embedded .chatroom-features .features-list .feature .fa{margin-right:.5em;color:var(--text-color)}#conversejs .chat-head-chatroom,#conversejs.converse-embedded .chat-head-chatroom{color:var(--chatroom-head-color);background-color:var(--chatroom-head-bg-color);border-bottom:var(--chatroom-head-border-bottom)}#conversejs .chat-head-chatroom .chat-head__desc,#conversejs.converse-embedded .chat-head-chatroom .chat-head__desc{color:var(--chatroom-head-color);display:var(--chatroom-head-description-display)}#conversejs .chat-head-chatroom .chat-head__desc a,#conversejs.converse-embedded .chat-head-chatroom .chat-head__desc a{color:var(--chatroom-head-description-link-color)}#conversejs .chat-head-chatroom .chat-head__desc:hover button,#conversejs.converse-embedded .chat-head-chatroom .chat-head__desc:hover button{display:inline-block}#conversejs .chat-head-chatroom .chatbox-title .btn--transparent i,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title .btn--transparent i{color:var(--chatroom-head-color)}#conversejs .chat-head-chatroom .chatbox-title .chatbox-title__text--bookmarked,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title .chatbox-title__text--bookmarked{margin-left:.5em;color:var(--chatroom-head-color)}#conversejs .chat-head-chatroom .chatbox-title__buttons,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title__buttons{background-color:var(--chatroom-head-bg-color)}#conversejs .chat-head-chatroom a.chatbox-btn.fa,#conversejs .chat-head-chatroom a:hover.chatbox-btn.fa,#conversejs .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa,#conversejs .chat-head-chatroom a:visited.chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a:hover.chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a:visited.chatbox-btn.fa{color:var(--chat-head-text-color)}#conversejs .chat-head-chatroom a.chatbox-btn.fa.button-on:before,#conversejs .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before,#conversejs .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,#conversejs .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before{color:var(--chatroom-head-button-color)}#conversejs .chat-head-chatroom .chatbox-btn.button-on:before,#conversejs.converse-embedded .chat-head-chatroom .chatbox-btn.button-on:before{color:var(--chatroom-head-button-color)}#conversejs .chat-head-chatroom .chatbox-title__text,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title__text{display:var(--heading-display);font-weight:var(--chatroom-head-title-font-weight);margin:auto 0;padding-right:var(--chatroom-head-title-padding-right);white-space:nowrap}#conversejs .chat-head-chatroom .chatbox-title__text .chatroom-jid,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title__text .chatroom-jid{font-size:var(--font-size-small)}#conversejs .empty-history-feedback,#conversejs.converse-embedded .empty-history-feedback{position:relative}#conversejs .empty-history-feedback span,#conversejs.converse-embedded .empty-history-feedback span{width:100%;text-align:center;position:absolute;margin-top:50%}#conversejs .chatroom,#conversejs.converse-embedded .chatroom{width:var(--chatroom-width)}@media screen and (max-height:450px){#conversejs .chatroom,#conversejs.converse-embedded .chatroom{width:var(--mobile-chat-width)}}@media screen and (max-width:480px){#conversejs .chatroom,#conversejs.converse-embedded .chatroom{width:var(--mobile-chat-width)}}#conversejs .chatroom .box-flyout,#conversejs.converse-embedded .chatroom .box-flyout{overflow-y:hidden;background-color:var(--chatroom-head-bg-color);width:100%}@media screen and (max-height:450px){#conversejs .chatroom .box-flyout,#conversejs.converse-embedded .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){#conversejs .chatroom .box-flyout,#conversejs.converse-embedded .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}#conversejs .chatroom .box-flyout .chatroom-body,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body{flex-direction:row;flex-flow:nowrap;background-color:#fff;border-top:0;width:100%;overflow:hidden}#conversejs .chatroom .box-flyout .chatroom-body .row,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .row{flex-direction:row}#conversejs .chatroom .box-flyout .chatroom-body .chat-topic,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-topic{font-weight:700;color:var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-info,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info{color:var(--chat-info-color);line-height:normal}#conversejs .chatroom .box-flyout .chatroom-body .chat-info.badge,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info.badge{color:var(--chat-head-text-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-info.chat-msg--retracted,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info.chat-msg--retracted{color:var(--subdued-color)}#conversejs .chatroom .box-flyout .chatroom-body .disconnect-container,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-container{margin:1em;width:100%}#conversejs .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg{padding-bottom:1em}#conversejs .chatroom .box-flyout .chatroom-body .chat-area,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area{display:flex;flex-direction:column;flex:0 1 100%;justify-content:flex-end;min-width:25%;word-wrap:break-word}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator{background-color:var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content{height:100%}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help{border-top:1px solid var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help .close-chat-help svg,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help .close-chat-help svg{fill:var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .occupants,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants{display:flex;flex-direction:column;justify-content:space-between;overflow-x:hidden;overflow-y:hidden;vertical-align:top;background-color:var(--occupants-background-color);border-left:var(--occupants-border-left);padding:.5em;max-width:75%;min-width:20%;flex:0 0 25%}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header{display:flex;flex-direction:column}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants{align-self:flex-end;cursor:pointer;font-size:var(--font-size-small)}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header--title,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header--title{margin-top:.5em;margin-bottom:.5em;display:flex;flex-direction:row}#conversejs .chatroom .box-flyout .chatroom-body .occupants .fa-user-plus,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .fa-user-plus{margin-right:.25em}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{font-family:var(--heading-font);color:var(--groupchats-header-color-dark);padding-left:0;margin-right:1em}#conversejs .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul{padding:0}#conversejs .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul li,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul li{padding:.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul{padding:0;margin-bottom:.5em;overflow-x:hidden;overflow-y:auto;list-style:none}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list{overflow-y:auto;flex-basis:0;flex-grow:1}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li{cursor:default;display:block;font-size:var(--font-size-small);overflow:hidden;padding:.25em .25em .25em 0;text-overflow:ellipsis}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa{margin-right:.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.feature,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.feature{font-size:var(--font-size-tiny)}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant{cursor:pointer}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge{display:flex;justify-content:space-between;flex-wrap:wrap}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges{display:flex;justify-content:flex-end;flex-wrap:wrap;flex-direction:row}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges span,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges span{margin-right:.25rem}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters{flex-wrap:nowrap;min-height:1.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge{margin-bottom:.125rem}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status{display:inline-block;margin:0 .5em .125em 0;width:.5em;height:.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online{background-color:#1a9707}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd{background-color:red}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away{background-color:#ff8c00}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa{background-color:orange}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline{background-color:#a9a9a9}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container{background-color:#fff;border:0;color:var(--text-color);font-size:var(--font-size);height:100%;width:100%;overflow-y:auto}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message{font-size:90%;color:var(--error-color)}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit],#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit]{margin:0 .5em}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary{background-color:var(--chatroom-head-button-color)}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form{display:flex;flex-direction:column;justify-content:center;padding:2em}#conversejs .chatroom .muc-bottom-panel,#conversejs.converse-embedded .chatroom .muc-bottom-panel{height:3em;padding:.5em;text-align:center;font-size:var(--font-size-small);background-color:var(--chatroom-head-bg-color);color:#fff}#conversejs .chatroom .muc-bottom-panel.muc-bottom-panel--nickname,#conversejs.converse-embedded .chatroom .muc-bottom-panel.muc-bottom-panel--nickname{padding:0;height:16em}#conversejs .chatroom .muc-bottom-panel.muc-bottom-panel--nickname .chatroom-form-container .chatroom-form,#conversejs.converse-embedded .chatroom .muc-bottom-panel.muc-bottom-panel--nickname .chatroom-form-container .chatroom-form{padding-top:2em;padding-bottom:0}#conversejs .chatroom .sendXMPPMessage .suggestion-box__results--above,#conversejs.converse-embedded .chatroom .sendXMPPMessage .suggestion-box__results--above{bottom:4.5em}#conversejs .chatroom .sendXMPPMessage .chat-textarea:active,#conversejs .chatroom .sendXMPPMessage .chat-textarea:focus,#conversejs .chatroom .sendXMPPMessage input:active,#conversejs .chatroom .sendXMPPMessage input:focus,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea:active,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea:focus,#conversejs.converse-embedded .chatroom .sendXMPPMessage input:active,#conversejs.converse-embedded .chatroom .sendXMPPMessage input:focus{outline-color:var(--chatroom-head-bg-color)}#conversejs .chatroom .sendXMPPMessage .chat-textarea.correcting,#conversejs .chatroom .sendXMPPMessage input.correcting,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea.correcting,#conversejs.converse-embedded .chatroom .sendXMPPMessage input.correcting{background-color:var(--chatroom-correcting-color)}#conversejs .chatroom .sendXMPPMessage .chat-textarea,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea{border-bottom-right-radius:0}#conversejs .chatroom .room-invite .invited-contact,#conversejs.converse-embedded .chatroom .room-invite .invited-contact{margin:-1px 0 0 -1px;width:100%;border:1px solid #999}#conversejs.converse-overlayed .chatbox.chatroom{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}#conversejs.converse-overlayed .chatbox.chatroom .box-flyout{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}#conversejs.converse-overlayed .chatbox.chatroom .chatbox-title__text{flex:0 0 58.33333%;max-width:58.33333%}#conversejs.converse-overlayed .chatbox.chatroom .chatbox-title__buttons{flex:0 0 41.66667%;max-width:41.66667%}#conversejs.converse-overlayed .chatbox.chatroom .chat-head__desc{font-size:80%;margin-bottom:1em}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupants-heading{padding:0}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupant-list{border-bottom:none}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-nick-badge .occupant-badges{display:none}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-status{margin-top:6px}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .chat-area{min-width:var(--overlayed-chat-width)}#conversejs.converse-embedded .chatroom .box-flyout,#conversejs.converse-fullscreen .chatroom .box-flyout,#conversejs.converse-mobile .chatroom .box-flyout{width:100%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator{max-width:100%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants{padding:var(--occupants-padding)}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{font-size:var(--font-size-large)}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li{font-size:var(--font-size-small)}#conversejs.converse-embedded .chatroom .room-invite span .invited-contact,#conversejs.converse-fullscreen .chatroom .room-invite span .invited-contact,#conversejs.converse-mobile .chatroom .room-invite span .invited-contact{margin:0 0 .5em -1px}#conversejs.converse-embedded .chatroom{margin:0;width:100%}#conversejs.converse-embedded .chatroom .box-flyout .occupants-heading{font-size:120%}#conversejs.converse-embedded .chatroom .box-flyout .chat-content .chat-message{margin:.5em;font-size:120%}#conversejs.converse-embedded .chatroom .box-flyout .sendXMPPMessage .chat-textarea{padding:.5em;font-size:110%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body{height:100%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container{height:100%;position:relative}#conversejs.converse-embedded .chatroom .box-flyout .occupants .occupant-list{padding-left:.3em}@media (max-width:767.98px){#conversejs.converse-fullscreen .chatbox .box-flyout .chat-head-chatroom .chatbox-navback,#conversejs.converse-mobile .chatbox .box-flyout .chat-head-chatroom .chatbox-navback,#conversejs.converse-overlayed .chatbox .box-flyout .chat-head-chatroom .chatbox-navback{margin-right:0!important}#conversejs.converse-fullscreen .chatbox .box-flyout .chat-head-chatroom .chatbox-navback .fa-arrow-left:before,#conversejs.converse-mobile .chatbox .box-flyout .chat-head-chatroom .chatbox-navback .fa-arrow-left:before,#conversejs.converse-overlayed .chatbox .box-flyout .chat-head-chatroom .chatbox-navback .fa-arrow-left:before{color:var(--chatroom-head-color)}}#conversejs .chat-head-headline{background-color:var(--headline-head-color)}#conversejs .chatbox.headlines .chat-head.chat-head-chatbox{background-color:var(--headline-head-color)}#conversejs .chatbox.headlines .chat-body{background-color:var(--headline-head-color)}#conversejs .chatbox.headlines .chat-body .chat-message{color:var(--headline-message-color)}#conversejs .chatbox.headlines .chat-content{height:100%}#conversejs .message.chat-msg.headline .chat-msg__body{margin-left:0}#conversejs.converse-fullscreen .chatbox.headlines .box-flyout{background-color:var(--headline-head-color)}#conversejs.converse-fullscreen .chatbox.headlines .chat-head.chat-head-chatbox{background-color:var(--headline-head-color)}#conversejs.converse-fullscreen .chatbox.headlines .flyout{border-color:var(--headline-head-color)}#conversejs .styling-directive{color:var(--subdued-color)}#conversejs .older-msg time{font-weight:700}#conversejs .message blockquote{margin-left:.5em;margin-bottom:.25em;padding-right:1em;color:var(--subdued-color);border-left:.3em solid var(--subdued-color);padding-left:.5em}#conversejs .message code{font-family:monospace}#conversejs .message .mention{font-weight:700}#conversejs .message .mention--self{font-weight:400}#conversejs .message.date-separator,#conversejs .message.separator{height:2em;margin:0;position:relative;text-align:center;z-index:0}#conversejs .message.date-separator .separator,#conversejs .message.separator .separator{border-top:0;border-bottom:var(--chat-separator-border-bottom);margin:0 1em;position:relative;top:1em;z-index:5}#conversejs .message.date-separator .separator-text,#conversejs .message.separator .separator-text{background:#fff;bottom:1px;color:var(--separator-text-color);display:inline-block;line-height:2em;padding:0 1em;position:relative;z-index:5}#conversejs .message.chat-msg--retracted .chat-msg__message{color:var(--subdued-color)}#conversejs .message.chat-info{color:var(--chat-head-color);font-size:var(--message-font-size);line-height:var(--line-height-small);font-size:90%;padding:.17rem 1rem}#conversejs .message.chat-info.badge{color:var(--chat-head-text-color)}#conversejs .message.chat-info.chat-state-notification{font-style:italic}#conversejs .message.chat-info.chat-event{clear:left;font-style:italic}#conversejs .message.chat-info.chat-error{color:var(--error-color);font-weight:700}#conversejs .message.chat-info .q{font-style:italic}#conversejs .message .chat-image{height:auto;width:auto;max-height:15em;max-width:100%}#conversejs .message.chat-msg--action{font-style:italic}#conversejs .message.chat-msg--action .chat-msg__author{padding-right:.2em}#conversejs .message.chat-msg{display:inline-flex;width:100%;flex-direction:row;padding:.125rem 1rem}#conversejs .message.chat-msg.onload{animation:colorchange-chatmessage 1s;-webkit-animation:colorchange-chatmessage 1s}#conversejs .message.chat-msg:hover{background-color:var(--list-item-hover-color)}#conversejs .message.chat-msg.correcting.groupchat{background-color:var(--chatroom-correcting-color)}#conversejs .message.chat-msg.correcting:not(.groupchat){background-color:var(--chat-correcting-color)}#conversejs .message.chat-msg .spoiler{margin-top:.5em}#conversejs .message.chat-msg .spoiler-hint{margin-bottom:.5em}#conversejs .message.chat-msg .spoiler-toggle{color:#fff}#conversejs .message.chat-msg .spoiler-toggle i{color:#fff;padding-right:.5em}#conversejs .message.chat-msg .spoiler-toggle:before{padding-right:.25em;whitespace:nowrap}#conversejs .message.chat-msg .chat-msg__content{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-left:.5rem;width:calc(100% - var(--message-avatar-width))}#conversejs .message.chat-msg .chat-msg__content:hover .btn--standalone{opacity:1}#conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat .chat-msg__text{color:var(--subdued-color)}#conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--delayed .chat-msg__text,#conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--received .chat-msg__text{color:var(--message-text-color)}#conversejs .message.chat-msg .chat-msg__content--action{width:100%;margin-left:0}#conversejs .message.chat-msg .chat-msg__body{display:flex;flex-direction:row;justify-content:space-between}#conversejs .message.chat-msg converse-chat-message-body{display:inline}#conversejs .message.chat-msg .chat-msg__message{line-height:1.5em;display:inline-flex;flex-direction:column;width:100%;overflow-wrap:break-word}#conversejs .message.chat-msg .chat-msg__edit-modal{cursor:pointer;padding-right:.5em}#conversejs .message.chat-msg .chat-msg__subject{font-weight:700;clear:right}#conversejs .message.chat-msg .chat-msg__text{color:var(--message-text-color);padding:0;white-space:pre-wrap;word-wrap:break-word;word-break:break-word}#conversejs .message.chat-msg .chat-msg__text a{word-wrap:break-word;word-break:break-all;display:inline}#conversejs .message.chat-msg .chat-msg__text a.chat-image__link{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:block}#conversejs .message.chat-msg .chat-msg__text img.emoji{height:1.5em;width:1.5em;margin:0 .05em 0 .1em;vertical-align:-.1em}#conversejs .message.chat-msg .chat-msg__text .emojione{margin-bottom:-6px}#conversejs .message.chat-msg .chat-msg__text--larger{font-size:1.6em;padding-top:.25em;padding-bottom:.25em}#conversejs .message.chat-msg .chat-msg__error{color:var(--error-color)}#conversejs .message.chat-msg .chat-msg__media{margin-top:.25rem;word-break:break-all}#conversejs .message.chat-msg .chat-msg__media a{word-wrap:break-word}#conversejs .message.chat-msg .chat-msg__media audio{width:100%}#conversejs .message.chat-msg converse-message-actions{margin-left:.5em}#conversejs .message.chat-msg .chat-msg__actions .dropdown-menu{min-width:5rem}#conversejs .message.chat-msg .chat-msg__actions i{color:var(--text-color-lighten-15-percent);font-size:70%}#conversejs .message.chat-msg .chat-msg__actions button{border:none;background:0 0;color:var(--text-color-lighten-15-percent);padding:0 .25em}#conversejs .message.chat-msg .chat-msg__actions .btn--standalone{opacity:0;margin-top:-.2em}#conversejs .message.chat-msg .chat-msg__actions .chat-msg__action{width:100%;padding:.5em 1em;text-align:left;white-space:nowrap}#conversejs .message.chat-msg .chat-msg__actions .chat-msg__action converse-icon{margin-right:.25em}#conversejs .message.chat-msg .chat-msg__actions .chat-msg__action:hover{color:var(--text-color);background-color:var(--list-item-hover-color)}#conversejs .message.chat-msg .chat-msg__avatar{margin-top:.5em;vertical-align:middle;height:var(--message-avatar-height);width:var(--message-avatar-width);min-height:var(--message-avatar-height);min-width:var(--message-avatar-width)}#conversejs .message.chat-msg .chat-msg__author{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--heading-font);font-size:115%;font-weight:700;padding-bottom:1px}#conversejs .message.chat-msg .chat-msg__heading{width:100%;margin-top:.5em;padding-right:.25rem;padding-bottom:.25rem}#conversejs .message.chat-msg .chat-msg__heading .badge{margin-left:.5em;font-family:var(--normal_font)}#conversejs .message.chat-msg .chat-msg__heading .chat-msg__time{padding-left:.25em;padding-right:.25em;color:var(--text-color-lighten-15-percent)}#conversejs .message.chat-msg.chat-msg--action .chat-msg__message{flex-direction:row}#conversejs .message.chat-msg.chat-msg--action .chat-msg__text{width:auto}#conversejs .message.chat-msg.chat-msg--action .chat-msg__heading{margin-top:0;padding-bottom:0;width:auto}#conversejs .message.chat-msg.chat-msg--action .chat-msg__heading .fa{margin-left:.5em}#conversejs .message.chat-msg.chat-msg--action .chat-msg__author{font-size:var(--message-font-size)}#conversejs .message.chat-msg.chat-msg--action .chat-msg__time{margin-left:0}#conversejs .message.chat-msg.chat-msg--followup .chat-msg__avatar,#conversejs .message.chat-msg.chat-msg--followup .chat-msg__heading{display:none}#conversejs .message.chat-msg.chat-msg--followup.chat-msg--with-avatar .chat-msg__content{margin-left:2.75rem;width:100%}#conversejs .message.chat-msg .chat-msg__receipt{margin-left:.5em;margin-right:.5em;color:var(--message-receipt-color)}#conversejs .chatroom-body .message.onload{animation:colorchange-chatmessage-muc 1s;-webkit-animation:colorchange-chatmessage-muc 1s}#conversejs .chatroom-body .message .separator{border-top:0;border-bottom:var(--chatroom-separator-border-bottom)}#conversejs.converse-overlayed .message.chat-msg.chat-msg--followup .chat-msg__content{margin-left:0}@media screen and (max-width:767px){#conversejs:not(.converse-embedded) .message.chat-msg .chat-msg__author{white-space:normal}}#conversejs.converse-overlayed #minimized-chats{order:100;width:var(--minimized-chats-width);margin-bottom:0;border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);color:var(--inverse-link-color);margin-right:var(--chat-gutter);padding:0}#conversejs.converse-overlayed #minimized-chats .badge{bottom:8px;border:1px solid var(--overlayed-badge-color)}#conversejs.converse-overlayed #minimized-chats #toggle-minimized-chats{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);background-color:var(--link-color);padding:1em 0 0 0;text-align:center;color:#fff;white-space:nowrap;overflow-y:hidden;text-overflow:ellipsis;display:block;height:45px;width:9em}#conversejs.converse-overlayed #minimized-chats a.restore-chat{cursor:pointer;padding:1px 0 1px 5px;color:var(--chat-head-text-color);line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs.converse-overlayed #minimized-chats a.restore-chat:hover{text-decoration:none}#conversejs.converse-overlayed #minimized-chats a.restore-chat:visited{color:var(--chat-head-text-color)}#conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout{flex-direction:column-reverse;bottom:45px;width:var(--minimized-chats-width)}#conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head{min-height:0;padding:.3em;border-radius:var(--chatbox-border-radius);height:35px;margin-bottom:.2em;width:100%;max-width:9em;flex-wrap:nowrap}#conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout.minimized{height:auto}#conversejs.converse-overlayed #minimized-chats .unread-message-count{font-weight:700;background-color:#fff;border:1px solid;text-shadow:1px 1px 0 var(--text-shadow-color);color:var(--warning-color);border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}#conversejs.converse-overlayed #minimized-chats .chat-head-message-count-hidden,#conversejs.converse-overlayed #minimized-chats .unread-message-count-hidden{display:none}#conversejs #controlbox .bookmarks-toggle,#conversejs #controlbox .bookmarks-toggle .fa{color:var(--groupchats-header-color)!important}#conversejs #controlbox .bookmarks-toggle .fa:hover,#conversejs #controlbox .bookmarks-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}#conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room{width:80%}#conversejs [hidden]{display:none}#conversejs .visually-hidden{position:absolute;clip:rect(0,0,0,0)}#conversejs .form-group .suggestion-box{width:100%}#conversejs .suggestion-box{position:relative}#conversejs .suggestion-box mark{background:var(--completion-light-color)}#conversejs .suggestion-box>input{display:block}#conversejs .suggestion-box .suggestion-box__results,#conversejs .suggestion-box>ul{position:absolute;left:0;right:0;z-index:2;min-width:100%;box-sizing:border-box;list-style:none;padding:0;border-radius:.3em;margin:.2em 0 0;background:rgba(255,255,255,.9);background:linear-gradient(to bottom right,#fff,rgba(255,255,255,.9));border:1px solid rgba(0,0,0,.3);box-shadow:.05em .2em .6em rgba(0,0,0,.1);text-shadow:none}#conversejs .suggestion-box .suggestion-box__results:before,#conversejs .suggestion-box>ul:before{content:"";position:absolute;top:-.43em;left:1em;width:0;height:0;padding:.4em;background:#fff;border:inherit;border-right:0;border-bottom:0;transform:rotate(45deg);z-index:-1}#conversejs .suggestion-box .suggestion-box__results>li,#conversejs .suggestion-box>ul>li{text-overflow:ellipsis;overflow-x:hidden;position:relative;cursor:pointer;padding:1em}#conversejs .suggestion-box .suggestion-box__results--below{top:2em}#conversejs .suggestion-box .suggestion-box__results--above{bottom:4.5em}#conversejs .suggestion-box .suggestion-box__results--above:before{display:none}#conversejs .suggestion-box .suggestion-box__results--above:after{z-index:-1;content:"";position:absolute;bottom:-.43em;left:1em;width:0;height:0;padding:.4em;background:#fff;border:inherit;border-left:0;border-top:0;transform:rotate(45deg)}#conversejs .suggestion-box>ul:empty,#conversejs .suggestion-box>ul[hidden]{display:none}@supports (transform:scale(0)){#conversejs .suggestion-box>ul{transition:.3s cubic-bezier(.4,.2,.5,1.4);transform-origin:1.43em -.43em}#conversejs .suggestion-box>ul:empty,#conversejs .suggestion-box>ul[hidden]{opacity:0;transform:scale(0);display:block;transition-timing-function:ease}}#conversejs .suggestion-box>ul>li[aria-selected=true]{background:var(--completion-dark-color);color:var(--inverse-link-color)}#conversejs .suggestion-box li:hover mark{background:var(--completion-light-color);color:var(--inverse-link-color)}#conversejs .suggestion-box li[aria-selected=true] mark{background:var(--completion-normal-color);color:inherit}#conversejs.converse-fullscreen .suggestion-box__results--above{bottom:4.5em}#conversejs.converse-overlayed .suggestion-box__results--above{bottom:3.5em}#conversejs .chatbox img.emoji{height:1.2em;width:1.2em;margin:0 .05em 0 .1em;vertical-align:-.1em}#conversejs .chatbox .sendXMPPMessage .toggle-smiley a.toggle-smiley{padding:0}#conversejs .chatbox converse-emoji-dropdown{display:inline-block}#conversejs .chatbox converse-emoji-dropdown .dropdown-menu{padding:0}#conversejs .chatbox converse-emoji-picker{width:100%;padding-top:0;padding-bottom:0;background-color:var(--chat-head-color);overflow-y:hidden;background:#fff}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists{height:8em;overflow-y:auto;display:flex;flex-direction:column}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-category__heading{clear:both;color:var(--subdued-color);cursor:auto;display:block;font-size:var(--font-size);margin:0;padding:.75em 0 0 .5em}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-lists__container{overflow-x:hidden}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-picker li{float:left}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker{display:flex;padding:.5em 0;background-color:var(--chat-head-color);width:auto;font-size:var(--font-size)}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker label{margin:0;padding:0 .5em;white-space:nowrap;font-size:var(--font-size-small);color:var(--heading-color)}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul li{padding:0 .25em}#conversejs .chatbox converse-emoji-picker .emoji-picker{background-color:#fff;padding:.5em 0 0 .5em}#conversejs .chatbox converse-emoji-picker .emoji-picker:last-child{padding-bottom:.5em}#conversejs .chatbox converse-emoji-picker .emoji-picker li{display:inline-block;height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden;margin-left:0;list-style:none;position:relative}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji{padding:0 .2em;height:auto;width:auto;margin:0;display:block;text-align:center}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji.selected a{background-color:var(--highlight-color-darker)}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji img{margin:0 auto;height:var(--font-size-huge);width:var(--font-size-huge);display:inline-block;vertical-align:baseline}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a{padding:3px;display:inline-block;font-size:var(--font-size-huge);line-height:calc(var(--font-size-huge) * 1.5);height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a:hover{background-color:var(--highlight-color-darker)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header{display:flex;flex-direction:column;padding:.1em 0;background-color:var(--chat-head-color)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header .emoji-search{width:auto;margin:.25em;height:2em;font-size:var(--font-size-small)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category{padding:.25em 0;font-size:var(--font-size-huge)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{background-color:#fff;border:1px var(--chat-head-color) solid;border-bottom:none}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.selected a,#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category:hover a{background-color:var(--highlight-color-darker)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category a{padding:.25em;display:inline-block}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category img{height:var(--font-size-huge);width:var(--font-size-huge)}#conversejs .chatroom converse-emoji-picker{background-color:var(--chatroom-head-bg-color);background:#fff}#conversejs .chatroom converse-emoji-picker .emoji-skintone-picker{background-color:var(--chatroom-head-bg-color)}#conversejs .chatroom converse-emoji-picker .emoji-picker__header{background-color:var(--chatroom-head-bg-color)}#conversejs .chatroom converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{border:1px var(--chatroom-head-bg-color) solid;border-bottom:none}#conversejs.converse-overlayed converse-emoji-dropdown .dropdown-menu{min-width:18em}#conversejs.converse-overlayed .chatbox .emoji-picker__header .emoji-category img{height:var(--font-size)!important;width:var(--font-size)!important}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji a{font-size:var(--font-size);line-height:calc(var(--font-size) * 1.5);padding:0;height:calc(var(--font-size) * 1.5);width:calc(var(--font-size) * 1.5)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji img{height:var(--font-size);width:var(--font-size)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-skintone-picker{font-size:var(--font-size-small)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__header .emoji-category{font-size:var(--font-size-small)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__lists{height:7em}#conversejs.converse-embedded converse-emoji-dropdown .dropdown-menu{min-width:20em}#conversejs.converse-fullscreen converse-emoji-dropdown .dropdown-menu{min-width:22em}#conversejs.converse-fullscreen .chatbox converse-emoji-picker .emoji-picker__lists{height:12em}#conversejs .chatbox converse-emoji-picker{max-width:40em}#conversejs.theme-redpill{--green:#25DB77;--orange:#E19823;--light-blue:#4E9CFE;--pink:#BD23E1;--beet:#360101;--beet-green:rgb(25, 68, 71);--beet-light-green:#8EB726;--beet-orig:#50162D;--blue:#4E9CFE;--darkest-grey:#232323;--red:#d33b2b;--dark-link-color:#3a3a3a;--occupants-background-color:#333;--form-background:#3b3b3b;--global-background-color:var(--darkest-grey);--redder-orange:var(--beet);--primary-color:var(--beet-orig);--primary-color-dark:var(--beet);--highlight-color-darker:var(--beet-light-green);--highlight-color:var(--beet);--headline-head-color:var(--beet-green);--text-color:#c5c5c5;--text-color-lighten-15-percent:#e9e9e9;--message-text-color:#FFFFFF;--text-controlbox-color:#d9d9d9;--message-receipt-color:var(--darkest-grey);--link-color:var(--beet-light-green);--chat-textarea-color:var(--font-hover-head-color);--chat-textarea-background-color:#2c2c2c;--chat-content-background-color:#2c2c2c;--controlbox-heading-top-margin:0.75em;--inline-action-margin:0.75em;--chat-head-color:var(--beet-green);--chat-head-color-dark:#b9b9ac;--chat-head-color-darker:#e8e8e3;--chat-correcting-color:var(--beet);--chatbox-border-radius:0px;--controlbox-head-color-lighten-45-percent:#0e0e0e;--controlbox-pane-background-color:var(--darkest-grey);--font-head-color:#777;--font-hover-head-color:#c5c5c5;--chatroom-width:100%;--chatroom-correcting-color:var(--beet);--font-size-tiny:8px;--font-size-small:10px;--font-size-occupants:100%;--font-size:12px;--font-size-large:14px;--font-size-huge:18px;--chat-separator-border-bottom:2px solid var(--blue);--chatroom-separator-border-bottom:2px solid var(--blue);--message-background-color:#303030;--message-input-border-top:4px solid var(--blue);--message-mention-color:#404040;--message-mention-self-color:#AB3131;--message-separator-background-color:#2E1520;--embedded-emoji-picker-height:200px;--avatar-border-radius:50%;--fullpage-emoji-picker-height:200px;--overlayed-emoji-picker-height:100px;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--chat-content-background-color);--list-item-open-hover-color:var(--beet);--list-dot-circle-color:#f6dec1;scrollbar-color:var(--red) var(--occupants-background-color);scrollbar-width:thin}#conversejs.theme-redpill ::-webkit-scrollbar{width:5px;height:5px;background-color:vat(--darkest-grey)}#conversejs.theme-redpill ::-webkit-scrollbar-track-piece{background-color:var(--daskest-grey)}#conversejs.theme-redpill ::-webkit-scrollbar-thumb:vertical{height:15px;background-color:#fff}#conversejs.theme-redpill .scroller{width:300px;height:100px;overflow-y:scroll;scrollbar-color:#663399 green}#conversejs.theme-redpill #controlbox .bookmarks-toggle,#conversejs.theme-redpill #controlbox .bookmarks-toggle .fa{color:var(--orange)!important}#conversejs.theme-redpill #controlbox .bookmarks-toggle .fa:hover,#conversejs.theme-redpill #controlbox .bookmarks-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}#conversejs.theme-redpill .chatbox .chatroom .sendXMPPMessage{background-color:var(--message-background-color)}#conversejs.theme-redpill .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:red;color:#00f;padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);resize:none;border-radius:1em;border-width:.2em;margin-top:10px;padding-left:1em;width:70%;margin-left:10%}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea:active,#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea:focus{outline-color:unset!important;outline:unset!important}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea.spoiler{height:42px}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea.correcting{background-color:var(--chat-textarea-background-color)}#conversejs.theme-redpill .chatroom .sendXMPPMessage{background-color:var(--message-background-color)}#conversejs.theme-redpill .chatroom .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);resize:none;border-radius:1em;border-width:.2em;padding-left:1em;width:70%;margin-left:10%}#conversejs.theme-redpill .chatroom .chat-textarea.correcting{background-color:var(--chat-textarea-background-color);border-radius:1em;border-style:dotted;border-color:var(--red);padding-left:3em;width:70%;margin-left:10%}#conversejs.theme-redpill .chatroom .chat-textarea .chat-textarea:active,#conversejs.theme-redpill .chatroom .chat-textarea .chat-textarea:focus{outline-color:red!important}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .chat-info{color:var(--red)}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .occupants{border-left:unset}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .chatroom-form-container{backgorund-color:var(--dark-link-color)}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .chatroom-form{background-color:var(--dark-link-color)}#conversejs.theme-redpill #controlbox .open-rooms-toggle,#conversejs.theme-redpill #controlbox .open-rooms-toggle .fa{color:var(--chatroom-head-bg-color-dark)!important}#conversejs.theme-redpill #controlbox .open-rooms-toggle .fa:hover,#conversejs.theme-redpill #controlbox .open-rooms-toggle:hover{color:var(--orange)!important}#conversejs.theme-redpill #controlbox .controlbox-section .controlbox-heading--groupchats{color:var(--orange)}#conversejs.theme-redpill #controlbox .controlbox-pane dd{background-color:var(--beet)}#conversejs.theme-redpill #controlbox .controlbox-panes{border-right:unset}#conversejs.theme-redpill .avatar{border-radius:var(--avatar-border-radius);border:none;background-color:unset}#conversejs.theme-redpill .dropdown-menu{color:#fff;background-color:var(--darkest-grey)}#conversejs.theme-redpill .dropdown-menu.selected,#conversejs.theme-redpill .dropdown-menu:active{color:red!important;background-color:var(--occupants-background-color)}#conversejs.theme-redpill .dropdown-item{color:#fff}#conversejs.theme-redpill .dropdown-item.selected,#conversejs.theme-redpill .dropdown-item:active{color:red!important;background-color:#00f}#conversejs.theme-redpill ::-webkit-scrollbar-thumb{background:red;border-radius:10px}#conversejs.theme-redpill ::-webkit-scrollbar-track{background:var(--beet)}#conversejs.theme-redpill .chatbox img.emoji{height:1.2em;width:1.2em;margin:0 .05em 0 .1em;vertical-align:-.1em}#conversejs.theme-redpill .chatbox .sendXMPPMessage .toggle-smiley a.toggle-smiley{padding:0}#conversejs.theme-redpill .chatbox converse-emoji-dropdown{display:inline-block}#conversejs.theme-redpill .chatbox converse-emoji-dropdown .dropdown-menu{padding:0}#conversejs.theme-redpill .chatbox converse-emoji-picker{width:100%;padding-top:0;padding-bottom:0;background-color:var(--occupants-background-color);overflow-y:hidden;background:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists{height:8em;overflow-y:auto;display:flex;flex-direction:column}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists .emoji-category__heading{clear:both;color:var(--subdued-color);cursor:auto;display:block;font-size:var(--font-size);margin:0;padding:.75em 0 0 .5em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists .emoji-lists__container{overflow-x:hidden}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists .emoji-picker li{float:left}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker{display:flex;padding:.5em 0;background-color:var(--occupants-background-color);width:auto;font-size:var(--font-size)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker label{margin:0;padding:0 .5em;white-space:nowrap;font-size:var(--font-size-small);color:var(--heading-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker ul li{padding:0 .25em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker{background-color:var(--occupants-background-color);padding:.5em 0 0 .5em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker:last-child{padding-bottom:.5em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li{display:inline-block;height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden;margin-left:0;list-style:none;position:relative}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji{padding:0 .2em;height:auto;width:auto;margin:0;display:block;text-align:center}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji.selected a{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji img{margin:0 auto;height:var(--font-size-huge);width:var(--font-size-huge);display:inline-block;vertical-align:baseline}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a{padding:3px;display:inline-block;font-size:var(--font-size-huge);line-height:calc(var(--font-size-huge) * 1.5);height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a:hover{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header{display:flex;flex-direction:column;padding:.1em 0;background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header .emoji-search{width:auto;margin:.25em;height:2em;font-size:var(--font-size-small)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category{padding:.25em 0;font-size:var(--font-size-huge)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{background-color:var(--occupants-background-color);border:1px var(--chat-head-color) solid;border-bottom:none}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.selected a,#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category:hover a{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category a{padding:.25em;display:inline-block}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category img{height:var(--font-size-huge);width:var(--font-size-huge)}#conversejs.theme-redpill .chatroom converse-emoji-picker{background-color:var(--occupants-background-color);background:#fff}#conversejs.theme-redpill .chatroom converse-emoji-picker .emoji-skintone-picker{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatroom converse-emoji-picker .emoji-picker__header{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatroom converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{border:1px var(--chatroom-head-bg-color) solid;border-bottom:none}#conversejs.theme-redpill .items-list .list-item:hover{color:var(--text-color);background-color:var(--beet)}#conversejs.theme-redpill .items-list .list-item:hover .fa,#conversejs.theme-redpill .items-list .list-item:hover .far,#conversejs.theme-redpill .items-list .list-item:hover .fas{opacity:1}#conversejs.theme-redpill .items-list .list-item.open{border-left:4px solid var(--red);background-color:var(--list-item-open-color)}#conversejs.theme-redpill .items-list .list-item.open:hover{color:var(--text-color);background-color:var(--list-item-open-hover-color)!important}#conversejs.theme-redpill .items-list .list-item-badge{color:#fff;float:right;text-align:center;width:22px;background-color:var(--red);border-radius:50%;padding:.5em;font-size:var(--font-size-small)}#conversejs.theme-redpill .message .mention{font-weight:700;border-style:solid;border-width:0;border-radius:25px;background-color:var(--message-mention-color);color:#fff;padding:.2em}#conversejs.theme-redpill .message .mention--self{font-weight:700;border-radius:15px;background:var(--message-mention-self-color);color:var(--redder-orange)}#conversejs.theme-redpill .message.correcting.groupchat{background-color:unset;border-style:dotted;border-radius:1em;border-color:var(--red);border-width:.2em}#conversejs.theme-redpill .message.correcting:not(.groupchat){background-color:unset;border-style:solid;border-radius:1em;border-color:var(--red)}#conversejs.theme-redpill .message .chat-msg__heading .chat-msg__author{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--orange);font-family:var(--heading-font);font-size:115%;font-weight:700;padding-bottom:1px}#conversejs.theme-redpill .chat-msg__text{display:inline;color:var(--message-text-color);padding:10px;white-space:pre-wrap;word-wrap:break-word;word-break:break-word;line-height:1.7em}#conversejs.theme-redpill .chat-msg__message{display:inline-flex;flex-direction:column;width:unset;overflow-wrap:break-word}#conversejs.theme-redpill .chat-msg__avatar{height:var(--message-avatar-height);width:var(--message-avatar-width);display:block;margin-left:auto;margin-right:auto;background-size:cover}#conversejs.theme-redpill .message .mention{font-weight:700}#conversejs.theme-redpill .message .mention--self{font-weight:400}#conversejs.theme-redpill .message.date-separator{height:2em;margin:0;position:relative;text-align:center;z-index:0}#conversejs.theme-redpill .message.date-separator .separator{border-top:0;border-bottom:var(--global-background-color);border-style:solid}#conversejs.theme-redpill .message.date-separator .separator-text{background:var(--global-background-color);bottom:1px;color:var(--chatbox-separator-text);display:inline-block;line-height:2em;padding:0 1em;position:relative;z-index:5;border-style:solid;border-radius:2em;border-width:0}#conversejs.theme-redpill .chat-image{border-radius:2em;max-height:25em;transition:.5s;border:0;margin-left:5em;margin-top:2em}#conversejs.theme-redpill .chat-image:hover{-webkit-filter:grayscale(1);filter:grayscale(1)}#conversejs.theme-redpill .img-thumbnail{background-color:unset}#conversejs.theme-redpill .message.chat-msg .chat-msg__media{margin-top:.25rem;word-break:break-all}#conversejs.theme-redpill .message.chat-msg .chat-msg__media a{word-wrap:break-word}#conversejs.theme-redpill .message.chat-msg .chat-msg__media audio{width:50%;background-color:unset;color:var(--beet)}#conversejs.theme-redpill #converse-modals .modal-header{background-color:var(--beet);border-bottom:none}#conversejs.theme-redpill #converse-modals .modal-header .close{color:#fff;background-color:var(--red)}#conversejs.theme-redpill #converse-modals .modal-body{background-color:var(--chat-content-background-color)}#conversejs.theme-redpill #converse-modals .form-control{color:#fff;background-color:var(--darkest-grey);border:1px solid var(--darkest-grey)}#conversejs.theme-redpill #converse-modals .modal-content{background-color:var(--darkest-grey)}#conversejs.theme-redpill #converse-modals .modal-footer{border-top:none}#conversejs.theme-redpill #converse-modals .list-group-item{background-color:var(--darkest-grey)}#conversejs.theme-redpill #converse-roster .roster-contacts .current-xmpp-contact .chat-status{vertical-align:middle;font-size:1em;margin-right:0;margin-left:-.8em;margin-bottom:-1.5em;border-radius:50%;border:2px solid var(--occupants-background-color)}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle,#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle .fa{color:var(--beet-light-green)!important}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle .fa:hover,#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle:hover{color:var(--beet-green)!important}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group li .open-chat .msgs-indicator{float:right;color:#fff;text-align:center;width:22px;background-color:var(--red);border-radius:50%;padding:.5em;font-size:var(--font-size-small)}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group li .open-chat:hover{background-color:var(--beet)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar{background-color:var(--chat-content-background-color);box-sizing:border-box;color:var(--text-color);display:flex;justify-content:space-between;margin:0;width:100%}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa:hover,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far:hover,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas:hover{color:var(--font-head-color);font-size:var(--font-size-huge)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa:hover svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far:hover svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas:hover svg{fill:var(--text-color)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted a{color:var(--text-color)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted .toolbar-menu a,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted a .toolbar-menu a{color:var(--link-color)}#conversejs.theme-redpill .chat-toolbar .toolbar-buttons{width:100%;display:inline-block}#conversejs.theme-redpill .chat-toolbar .toolbar-buttons .message-limit{padding:.5em;font-weight:700}#conversejs.theme-redpill .chat-toolbar button{margin-top:.4em;border:1px transparent solid;background-color:transparent}#conversejs.theme-redpill .chat-toolbar button:disabled .fa{color:grey}#conversejs.theme-redpill .chat-toolbar button:disabled .fa:hover{color:grey}#conversejs.theme-redpill .chat-toolbar button:disabled .fa svg,#conversejs.theme-redpill .chat-toolbar button:disabled .fa svg:hover{fill:grey}#conversejs.theme-redpill .chat-toolbar button.send-button{padding-top:.2em;padding-bottom:.2em;margin:0;margin-top:-1px}#conversejs.theme-redpill .chat-toolbar .unverified,#conversejs.theme-redpill .chat-toolbar .unverified a{color:#cf5300}#conversejs.theme-redpill .chat-toolbar .private,#conversejs.theme-redpill .chat-toolbar .private a{color:#4b7003}#conversejs.theme-redpill .chat-toolbar li{cursor:pointer;display:inline-block;list-style:none;padding:0 .5em}#conversejs.theme-redpill .chat-toolbar li:hover{cursor:pointer}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu{background-color:var(--chat-content-background-color);bottom:1.7rem;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);height:auto;margin-bottom:0;min-width:21rem;position:absolute;right:0;top:auto;z-index:1000}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu.otr-menu{left:-6em;min-width:15rem}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu.otr-menu.show{display:flex;flex-direction:column}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu a{color:var(--link-color)}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul{z-index:99}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul li{display:block;padding:7px}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul li:hover{background-color:var(--highlight-color)}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul li a{display:block}#conversejs.theme-redpill .chatbox converse-chat-toolbar{border-top:var(--red);color:var(--text-color);background-color:var(--chat-content-background-color)}#conversejs.theme-redpill .chatbox converse-chat-toolbar .fa,#conversejs.theme-redpill .chatbox converse-chat-toolbar .fa:hover,#conversejs.theme-redpill .chatbox converse-chat-toolbar .far,#conversejs.theme-redpill .chatbox converse-chat-toolbar .far:hover,#conversejs.theme-redpill .chatbox converse-chat-toolbar .fas,#conversejs.theme-redpill .chatbox converse-chat-toolbar .fas:hover{color:var(--dark-link-color)}#conversejs.theme-redpill .chatbox converse-chat-toolbar button:focus{outline-color:unset!important;color:var(--red)}#conversejs.theme-redpill .chatroom converse-chat-toolbar{border-top:var(--chatroom-message-input-border-top);color:var(--text-color)}#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa:hover,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far:hover,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas:hover{color:var(--dark-link-color);font-size:var(--font-size-huge)}#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa:hover svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far:hover svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas:hover svg{fill:var(--text-color)}#conversejs.theme-redpill .chatroom converse-chat-toolbar button:focus{outline-color:unset!important}#conversejs.theme-redpill .suggestion-box{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .suggestion-box .suggestion-box__results,#conversejs.theme-redpill .suggestion-box>ul{position:absolute;left:0;right:0;z-index:2;min-width:100%;box-sizing:border-box;list-style:none;padding:0;border-radius:.3em;margin:.2em 0 0;background:rgba(37,36,36,.9);border:1px solid rgba(0,0,0,.3);box-shadow:.05em .2em .6em rgba(0,0,0,.1);text-shadow:none}#conversejs.theme-redpill .suggestion-box .suggestion-box__results:before,#conversejs.theme-redpill .suggestion-box>ul:before{content:"";position:absolute;top:-.43em;left:1em;width:0;height:0;padding:.4em;background:var(--red);border:inherit;border-right:0;border-bottom:0;transform:rotate(45deg);z-index:-1}#conversejs.theme-redpill .suggestion-box .suggestion-box__results>li,#conversejs.theme-redpill .suggestion-box>ul>li{text-overflow:ellipsis;overflow-x:hidden;position:relative;cursor:pointer;padding:1em} + +/*# sourceMappingURL=converse.css.map*/ \ No newline at end of file diff --git a/dist/converse.css.map b/dist/converse.css.map new file mode 100644 index 0000000..01b0be3 --- /dev/null +++ b/dist/converse.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///converse.scss"],"names":[],"mappings":"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","file":"../dist/converse.css","sourcesContent":["/*!\n * Converse.js (Web-based XMPP instant messaging client)\n * https://conversejs.org\n *\n * Copyright (c) 2013-2018, JC Brand \n * Licensed under the Mozilla Public License\n */#conversejs :root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace}#conversejs *,#conversejs ::after,#conversejs ::before{box-sizing:border-box}#conversejs html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}#conversejs article,#conversejs aside,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs header,#conversejs hgroup,#conversejs main,#conversejs nav,#conversejs section{display:block}#conversejs body{margin:0;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}#conversejs [tabindex=\"-1\"]:focus:not(:focus-visible){outline:0!important}#conversejs hr{box-sizing:content-box;height:0;overflow:visible}#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6{margin-top:0;margin-bottom:.5rem}#conversejs p{margin-top:0;margin-bottom:1rem}#conversejs abbr[data-original-title],#conversejs abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}#conversejs address{margin-bottom:1rem;font-style:normal;line-height:inherit}#conversejs dl,#conversejs ol,#conversejs ul{margin-top:0;margin-bottom:1rem}#conversejs ol ol,#conversejs ol ul,#conversejs ul ol,#conversejs ul ul{margin-bottom:0}#conversejs dt{font-weight:700}#conversejs dd{margin-bottom:.5rem;margin-left:0}#conversejs blockquote{margin:0 0 1rem}#conversejs b,#conversejs strong{font-weight:bolder}#conversejs small{font-size:80%}#conversejs sub,#conversejs sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}#conversejs sub{bottom:-.25em}#conversejs sup{top:-.5em}#conversejs a{color:#007bff;text-decoration:none;background-color:transparent}#conversejs a:hover{color:#0056b3;text-decoration:underline}#conversejs a:not([href]){color:inherit;text-decoration:none}#conversejs a:not([href]):hover{color:inherit;text-decoration:none}#conversejs code,#conversejs kbd,#conversejs pre,#conversejs samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;font-size:1em}#conversejs pre{margin-top:0;margin-bottom:1rem;overflow:auto}#conversejs figure{margin:0 0 1rem}#conversejs img{vertical-align:middle;border-style:none}#conversejs svg{overflow:hidden;vertical-align:middle}#conversejs table{border-collapse:collapse}#conversejs caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}#conversejs th{text-align:inherit}#conversejs label{display:inline-block;margin-bottom:.5rem}#conversejs button{border-radius:0}#conversejs button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}#conversejs button,#conversejs input,#conversejs optgroup,#conversejs select,#conversejs textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}#conversejs button,#conversejs input{overflow:visible}#conversejs button,#conversejs select{text-transform:none}#conversejs select{word-wrap:normal}#conversejs [type=button],#conversejs [type=reset],#conversejs [type=submit],#conversejs button{-webkit-appearance:button}#conversejs [type=button]:not(:disabled),#conversejs [type=reset]:not(:disabled),#conversejs [type=submit]:not(:disabled),#conversejs button:not(:disabled){cursor:pointer}#conversejs [type=button]::-moz-focus-inner,#conversejs [type=reset]::-moz-focus-inner,#conversejs [type=submit]::-moz-focus-inner,#conversejs button::-moz-focus-inner{padding:0;border-style:none}#conversejs input[type=checkbox],#conversejs input[type=radio]{box-sizing:border-box;padding:0}#conversejs input[type=date],#conversejs input[type=datetime-local],#conversejs input[type=month],#conversejs input[type=time]{-webkit-appearance:listbox}#conversejs textarea{overflow:auto;resize:vertical}#conversejs fieldset{min-width:0;padding:0;margin:0;border:0}#conversejs legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}#conversejs progress{vertical-align:baseline}#conversejs [type=number]::-webkit-inner-spin-button,#conversejs [type=number]::-webkit-outer-spin-button{height:auto}#conversejs [type=search]{outline-offset:-2px;-webkit-appearance:none}#conversejs [type=search]::-webkit-search-decoration{-webkit-appearance:none}#conversejs ::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}#conversejs output{display:inline-block}#conversejs summary{display:list-item;cursor:pointer}#conversejs template{display:none}#conversejs [hidden]{display:none!important}#conversejs .h1,#conversejs .h2,#conversejs .h3,#conversejs .h4,#conversejs .h5,#conversejs .h6,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}#conversejs .h1,#conversejs h1{font-size:2.5rem}#conversejs .h2,#conversejs h2{font-size:2rem}#conversejs .h3,#conversejs h3{font-size:1.75rem}#conversejs .h4,#conversejs h4{font-size:1.5rem}#conversejs .h5,#conversejs h5{font-size:1.25rem}#conversejs .h6,#conversejs h6{font-size:1rem}#conversejs .lead{font-size:1.25rem;font-weight:300}#conversejs .display-1{font-size:6rem;font-weight:300;line-height:1.2}#conversejs .display-2{font-size:5.5rem;font-weight:300;line-height:1.2}#conversejs .display-3{font-size:4.5rem;font-weight:300;line-height:1.2}#conversejs .display-4{font-size:3.5rem;font-weight:300;line-height:1.2}#conversejs hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}#conversejs .small,#conversejs small{font-size:80%;font-weight:400}#conversejs .mark,#conversejs mark{padding:.2em;background-color:#fcf8e3}#conversejs .list-unstyled{padding-left:0;list-style:none}#conversejs .list-inline{padding-left:0;list-style:none}#conversejs .list-inline-item{display:inline-block}#conversejs .list-inline-item:not(:last-child){margin-right:.5rem}#conversejs .initialism{font-size:90%;text-transform:uppercase}#conversejs .blockquote{margin-bottom:1rem;font-size:1.25rem}#conversejs .blockquote-footer{display:block;font-size:80%;color:#6c757d}#conversejs .blockquote-footer::before{content:\"\\2014\\00A0\"}#conversejs .img-fluid{max-width:100%;height:auto}#conversejs .img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}#conversejs .figure{display:inline-block}#conversejs .figure-img{margin-bottom:.5rem;line-height:1}#conversejs .figure-caption{font-size:90%;color:#6c757d}#conversejs .container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){#conversejs .container{max-width:540px}}@media (min-width:768px){#conversejs .container{max-width:720px}}@media (min-width:992px){#conversejs .container{max-width:960px}}@media (min-width:1200px){#conversejs .container{max-width:1140px}}#conversejs .container-fluid,#conversejs .container-lg,#conversejs .container-md,#conversejs .container-sm,#conversejs .container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){#conversejs .container,#conversejs .container-sm{max-width:540px}}@media (min-width:768px){#conversejs .container,#conversejs .container-md,#conversejs .container-sm{max-width:720px}}@media (min-width:992px){#conversejs .container,#conversejs .container-lg,#conversejs .container-md,#conversejs .container-sm{max-width:960px}}@media (min-width:1200px){#conversejs .container,#conversejs .container-lg,#conversejs .container-md,#conversejs .container-sm,#conversejs .container-xl{max-width:1140px}}#conversejs .row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}#conversejs .no-gutters{margin-right:0;margin-left:0}#conversejs .no-gutters>.col,#conversejs .no-gutters>[class*=col-]{padding-right:0;padding-left:0}#conversejs .col,#conversejs .col-1,#conversejs .col-10,#conversejs .col-11,#conversejs .col-12,#conversejs .col-2,#conversejs .col-3,#conversejs .col-4,#conversejs .col-5,#conversejs .col-6,#conversejs .col-7,#conversejs .col-8,#conversejs .col-9,#conversejs .col-auto,#conversejs .col-lg,#conversejs .col-lg-1,#conversejs .col-lg-10,#conversejs .col-lg-11,#conversejs .col-lg-12,#conversejs .col-lg-2,#conversejs .col-lg-3,#conversejs .col-lg-4,#conversejs .col-lg-5,#conversejs .col-lg-6,#conversejs .col-lg-7,#conversejs .col-lg-8,#conversejs .col-lg-9,#conversejs .col-lg-auto,#conversejs .col-md,#conversejs .col-md-1,#conversejs .col-md-10,#conversejs .col-md-11,#conversejs .col-md-12,#conversejs .col-md-2,#conversejs .col-md-3,#conversejs .col-md-4,#conversejs .col-md-5,#conversejs .col-md-6,#conversejs .col-md-7,#conversejs .col-md-8,#conversejs .col-md-9,#conversejs .col-md-auto,#conversejs .col-sm,#conversejs .col-sm-1,#conversejs .col-sm-10,#conversejs .col-sm-11,#conversejs .col-sm-12,#conversejs .col-sm-2,#conversejs .col-sm-3,#conversejs .col-sm-4,#conversejs .col-sm-5,#conversejs .col-sm-6,#conversejs .col-sm-7,#conversejs .col-sm-8,#conversejs .col-sm-9,#conversejs .col-sm-auto,#conversejs .col-xl,#conversejs .col-xl-1,#conversejs .col-xl-10,#conversejs .col-xl-11,#conversejs .col-xl-12,#conversejs .col-xl-2,#conversejs .col-xl-3,#conversejs .col-xl-4,#conversejs .col-xl-5,#conversejs .col-xl-6,#conversejs .col-xl-7,#conversejs .col-xl-8,#conversejs .col-xl-9,#conversejs .col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}#conversejs .col{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-3{flex:0 0 25%;max-width:25%}#conversejs .col-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-6{flex:0 0 50%;max-width:50%}#conversejs .col-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-9{flex:0 0 75%;max-width:75%}#conversejs .col-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-12{flex:0 0 100%;max-width:100%}#conversejs .order-first{order:-1}#conversejs .order-last{order:13}#conversejs .order-0{order:0}#conversejs .order-1{order:1}#conversejs .order-2{order:2}#conversejs .order-3{order:3}#conversejs .order-4{order:4}#conversejs .order-5{order:5}#conversejs .order-6{order:6}#conversejs .order-7{order:7}#conversejs .order-8{order:8}#conversejs .order-9{order:9}#conversejs .order-10{order:10}#conversejs .order-11{order:11}#conversejs .order-12{order:12}#conversejs .offset-1{margin-left:8.33333%}#conversejs .offset-2{margin-left:16.66667%}#conversejs .offset-3{margin-left:25%}#conversejs .offset-4{margin-left:33.33333%}#conversejs .offset-5{margin-left:41.66667%}#conversejs .offset-6{margin-left:50%}#conversejs .offset-7{margin-left:58.33333%}#conversejs .offset-8{margin-left:66.66667%}#conversejs .offset-9{margin-left:75%}#conversejs .offset-10{margin-left:83.33333%}#conversejs .offset-11{margin-left:91.66667%}@media (min-width:576px){#conversejs .col-sm{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-sm-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-sm-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-sm-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-sm-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-sm-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-sm-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-sm-3{flex:0 0 25%;max-width:25%}#conversejs .col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-sm-6{flex:0 0 50%;max-width:50%}#conversejs .col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-sm-9{flex:0 0 75%;max-width:75%}#conversejs .col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-sm-12{flex:0 0 100%;max-width:100%}#conversejs .order-sm-first{order:-1}#conversejs .order-sm-last{order:13}#conversejs .order-sm-0{order:0}#conversejs .order-sm-1{order:1}#conversejs .order-sm-2{order:2}#conversejs .order-sm-3{order:3}#conversejs .order-sm-4{order:4}#conversejs .order-sm-5{order:5}#conversejs .order-sm-6{order:6}#conversejs .order-sm-7{order:7}#conversejs .order-sm-8{order:8}#conversejs .order-sm-9{order:9}#conversejs .order-sm-10{order:10}#conversejs .order-sm-11{order:11}#conversejs .order-sm-12{order:12}#conversejs .offset-sm-0{margin-left:0}#conversejs .offset-sm-1{margin-left:8.33333%}#conversejs .offset-sm-2{margin-left:16.66667%}#conversejs .offset-sm-3{margin-left:25%}#conversejs .offset-sm-4{margin-left:33.33333%}#conversejs .offset-sm-5{margin-left:41.66667%}#conversejs .offset-sm-6{margin-left:50%}#conversejs .offset-sm-7{margin-left:58.33333%}#conversejs .offset-sm-8{margin-left:66.66667%}#conversejs .offset-sm-9{margin-left:75%}#conversejs .offset-sm-10{margin-left:83.33333%}#conversejs .offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){#conversejs .col-md{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-md-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-md-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-md-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-md-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-md-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-md-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-md-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-md-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-md-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-md-3{flex:0 0 25%;max-width:25%}#conversejs .col-md-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-md-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-md-6{flex:0 0 50%;max-width:50%}#conversejs .col-md-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-md-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-md-9{flex:0 0 75%;max-width:75%}#conversejs .col-md-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-md-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-md-12{flex:0 0 100%;max-width:100%}#conversejs .order-md-first{order:-1}#conversejs .order-md-last{order:13}#conversejs .order-md-0{order:0}#conversejs .order-md-1{order:1}#conversejs .order-md-2{order:2}#conversejs .order-md-3{order:3}#conversejs .order-md-4{order:4}#conversejs .order-md-5{order:5}#conversejs .order-md-6{order:6}#conversejs .order-md-7{order:7}#conversejs .order-md-8{order:8}#conversejs .order-md-9{order:9}#conversejs .order-md-10{order:10}#conversejs .order-md-11{order:11}#conversejs .order-md-12{order:12}#conversejs .offset-md-0{margin-left:0}#conversejs .offset-md-1{margin-left:8.33333%}#conversejs .offset-md-2{margin-left:16.66667%}#conversejs .offset-md-3{margin-left:25%}#conversejs .offset-md-4{margin-left:33.33333%}#conversejs .offset-md-5{margin-left:41.66667%}#conversejs .offset-md-6{margin-left:50%}#conversejs .offset-md-7{margin-left:58.33333%}#conversejs .offset-md-8{margin-left:66.66667%}#conversejs .offset-md-9{margin-left:75%}#conversejs .offset-md-10{margin-left:83.33333%}#conversejs .offset-md-11{margin-left:91.66667%}}@media (min-width:992px){#conversejs .col-lg{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-lg-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-lg-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-lg-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-lg-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-lg-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-lg-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-lg-3{flex:0 0 25%;max-width:25%}#conversejs .col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-lg-6{flex:0 0 50%;max-width:50%}#conversejs .col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-lg-9{flex:0 0 75%;max-width:75%}#conversejs .col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-lg-12{flex:0 0 100%;max-width:100%}#conversejs .order-lg-first{order:-1}#conversejs .order-lg-last{order:13}#conversejs .order-lg-0{order:0}#conversejs .order-lg-1{order:1}#conversejs .order-lg-2{order:2}#conversejs .order-lg-3{order:3}#conversejs .order-lg-4{order:4}#conversejs .order-lg-5{order:5}#conversejs .order-lg-6{order:6}#conversejs .order-lg-7{order:7}#conversejs .order-lg-8{order:8}#conversejs .order-lg-9{order:9}#conversejs .order-lg-10{order:10}#conversejs .order-lg-11{order:11}#conversejs .order-lg-12{order:12}#conversejs .offset-lg-0{margin-left:0}#conversejs .offset-lg-1{margin-left:8.33333%}#conversejs .offset-lg-2{margin-left:16.66667%}#conversejs .offset-lg-3{margin-left:25%}#conversejs .offset-lg-4{margin-left:33.33333%}#conversejs .offset-lg-5{margin-left:41.66667%}#conversejs .offset-lg-6{margin-left:50%}#conversejs .offset-lg-7{margin-left:58.33333%}#conversejs .offset-lg-8{margin-left:66.66667%}#conversejs .offset-lg-9{margin-left:75%}#conversejs .offset-lg-10{margin-left:83.33333%}#conversejs .offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){#conversejs .col-xl{flex-basis:0;flex-grow:1;max-width:100%}#conversejs .row-cols-xl-1>*{flex:0 0 100%;max-width:100%}#conversejs .row-cols-xl-2>*{flex:0 0 50%;max-width:50%}#conversejs .row-cols-xl-3>*{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .row-cols-xl-4>*{flex:0 0 25%;max-width:25%}#conversejs .row-cols-xl-5>*{flex:0 0 20%;max-width:20%}#conversejs .row-cols-xl-6>*{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}#conversejs .col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}#conversejs .col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}#conversejs .col-xl-3{flex:0 0 25%;max-width:25%}#conversejs .col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}#conversejs .col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}#conversejs .col-xl-6{flex:0 0 50%;max-width:50%}#conversejs .col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}#conversejs .col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}#conversejs .col-xl-9{flex:0 0 75%;max-width:75%}#conversejs .col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}#conversejs .col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}#conversejs .col-xl-12{flex:0 0 100%;max-width:100%}#conversejs .order-xl-first{order:-1}#conversejs .order-xl-last{order:13}#conversejs .order-xl-0{order:0}#conversejs .order-xl-1{order:1}#conversejs .order-xl-2{order:2}#conversejs .order-xl-3{order:3}#conversejs .order-xl-4{order:4}#conversejs .order-xl-5{order:5}#conversejs .order-xl-6{order:6}#conversejs .order-xl-7{order:7}#conversejs .order-xl-8{order:8}#conversejs .order-xl-9{order:9}#conversejs .order-xl-10{order:10}#conversejs .order-xl-11{order:11}#conversejs .order-xl-12{order:12}#conversejs .offset-xl-0{margin-left:0}#conversejs .offset-xl-1{margin-left:8.33333%}#conversejs .offset-xl-2{margin-left:16.66667%}#conversejs .offset-xl-3{margin-left:25%}#conversejs .offset-xl-4{margin-left:33.33333%}#conversejs .offset-xl-5{margin-left:41.66667%}#conversejs .offset-xl-6{margin-left:50%}#conversejs .offset-xl-7{margin-left:58.33333%}#conversejs .offset-xl-8{margin-left:66.66667%}#conversejs .offset-xl-9{margin-left:75%}#conversejs .offset-xl-10{margin-left:83.33333%}#conversejs .offset-xl-11{margin-left:91.66667%}}#conversejs .form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .form-control{transition:none}}#conversejs .form-control::-ms-expand{background-color:transparent;border:0}#conversejs .form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}#conversejs .form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .form-control::-moz-placeholder{color:#6c757d;opacity:1}#conversejs .form-control:-ms-input-placeholder{color:#6c757d;opacity:1}#conversejs .form-control::-ms-input-placeholder{color:#6c757d;opacity:1}#conversejs .form-control::placeholder{color:#6c757d;opacity:1}#conversejs .form-control:disabled,#conversejs .form-control[readonly]{background-color:#e9ecef;opacity:1}#conversejs select.form-control:focus::-ms-value{color:#495057;background-color:#fff}#conversejs .form-control-file,#conversejs .form-control-range{display:block;width:100%}#conversejs .col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}#conversejs .col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}#conversejs .col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}#conversejs .form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}#conversejs .form-control-plaintext.form-control-lg,#conversejs .form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}#conversejs .form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}#conversejs .form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}#conversejs select.form-control[multiple],#conversejs select.form-control[size]{height:auto}#conversejs textarea.form-control{height:auto}#conversejs .form-group{margin-bottom:1rem}#conversejs .form-text{display:block;margin-top:.25rem}#conversejs .form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}#conversejs .form-row>.col,#conversejs .form-row>[class*=col-]{padding-right:5px;padding-left:5px}#conversejs .form-check{position:relative;display:block;padding-left:1.25rem}#conversejs .form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}#conversejs .form-check-input:disabled~.form-check-label,#conversejs .form-check-input[disabled]~.form-check-label{color:#6c757d}#conversejs .form-check-label{margin-bottom:0}#conversejs .form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}#conversejs .form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}#conversejs .valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}#conversejs .valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}#conversejs.is-valid~.valid-feedback,#conversejs.is-valid~.valid-tooltip,.was-validated #conversejs:valid~.valid-feedback,.was-validated #conversejs:valid~.valid-tooltip{display:block}#conversejs .form-control.is-valid,.was-validated #conversejs .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .form-control.is-valid:focus,.was-validated #conversejs .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs textarea.form-control.is-valid,.was-validated #conversejs textarea.form-control:valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}#conversejs .custom-select.is-valid,.was-validated #conversejs .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right .75rem center/8px 10px,url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .custom-select.is-valid:focus,.was-validated #conversejs .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs .form-check-input.is-valid~.form-check-label,.was-validated #conversejs .form-check-input:valid~.form-check-label{color:#28a745}#conversejs .form-check-input.is-valid~.valid-feedback,#conversejs .form-check-input.is-valid~.valid-tooltip,.was-validated #conversejs .form-check-input:valid~.valid-feedback,.was-validated #conversejs .form-check-input:valid~.valid-tooltip{display:block}#conversejs .custom-control-input.is-valid~.custom-control-label,.was-validated #conversejs .custom-control-input:valid~.custom-control-label{color:#28a745}#conversejs .custom-control-input.is-valid~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}#conversejs .custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}#conversejs .custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated #conversejs .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}#conversejs .custom-file-input.is-valid~.custom-file-label,.was-validated #conversejs .custom-file-input:valid~.custom-file-label{border-color:#28a745}#conversejs .custom-file-input.is-valid:focus~.custom-file-label,.was-validated #conversejs .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}#conversejs .invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}#conversejs .invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}#conversejs.is-invalid~.invalid-feedback,#conversejs.is-invalid~.invalid-tooltip,.was-validated #conversejs:invalid~.invalid-feedback,.was-validated #conversejs:invalid~.invalid-tooltip{display:block}#conversejs .form-control.is-invalid,.was-validated #conversejs .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .form-control.is-invalid:focus,.was-validated #conversejs .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs textarea.form-control.is-invalid,.was-validated #conversejs textarea.form-control:invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}#conversejs .custom-select.is-invalid,.was-validated #conversejs .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right .75rem center/8px 10px,url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}#conversejs .custom-select.is-invalid:focus,.was-validated #conversejs .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs .form-check-input.is-invalid~.form-check-label,.was-validated #conversejs .form-check-input:invalid~.form-check-label{color:#dc3545}#conversejs .form-check-input.is-invalid~.invalid-feedback,#conversejs .form-check-input.is-invalid~.invalid-tooltip,.was-validated #conversejs .form-check-input:invalid~.invalid-feedback,.was-validated #conversejs .form-check-input:invalid~.invalid-tooltip{display:block}#conversejs .custom-control-input.is-invalid~.custom-control-label,.was-validated #conversejs .custom-control-input:invalid~.custom-control-label{color:#dc3545}#conversejs .custom-control-input.is-invalid~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}#conversejs .custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}#conversejs .custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated #conversejs .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}#conversejs .custom-file-input.is-invalid~.custom-file-label,.was-validated #conversejs .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}#conversejs .custom-file-input.is-invalid:focus~.custom-file-label,.was-validated #conversejs .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}#conversejs .form-inline{display:flex;flex-flow:row wrap;align-items:center}#conversejs .form-inline .form-check{width:100%}@media (min-width:576px){#conversejs .form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}#conversejs .form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}#conversejs .form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}#conversejs .form-inline .form-control-plaintext{display:inline-block}#conversejs .form-inline .custom-select,#conversejs .form-inline .input-group{width:auto}#conversejs .form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}#conversejs .form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}#conversejs .form-inline .custom-control{align-items:center;justify-content:center}#conversejs .form-inline .custom-control-label{margin-bottom:0}}#conversejs .btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .btn{transition:none}}#conversejs .btn:hover{color:#212529;text-decoration:none}#conversejs .btn.focus,#conversejs .btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .btn.disabled,#conversejs .btn:disabled{opacity:.65}#conversejs a.btn.disabled,#conversejs fieldset:disabled a.btn{pointer-events:none}#conversejs .btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}#conversejs .btn-primary.focus,#conversejs .btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}#conversejs .btn-primary.disabled,#conversejs .btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-primary:not(:disabled):not(.disabled).active,#conversejs .btn-primary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}#conversejs .btn-primary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-primary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}#conversejs .btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}#conversejs .btn-secondary.focus,#conversejs .btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}#conversejs .btn-secondary.disabled,#conversejs .btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-secondary:not(:disabled):not(.disabled).active,#conversejs .btn-secondary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}#conversejs .btn-secondary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-secondary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}#conversejs .btn-success{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}#conversejs .btn-success.focus,#conversejs .btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}#conversejs .btn-success.disabled,#conversejs .btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-success:not(:disabled):not(.disabled).active,#conversejs .btn-success:not(:disabled):not(.disabled):active,.show>#conversejs .btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}#conversejs .btn-success:not(:disabled):not(.disabled).active:focus,#conversejs .btn-success:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}#conversejs .btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}#conversejs .btn-info.focus,#conversejs .btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}#conversejs .btn-info.disabled,#conversejs .btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-info:not(:disabled):not(.disabled).active,#conversejs .btn-info:not(:disabled):not(.disabled):active,.show>#conversejs .btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}#conversejs .btn-info:not(:disabled):not(.disabled).active:focus,#conversejs .btn-info:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}#conversejs .btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}#conversejs .btn-warning.focus,#conversejs .btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}#conversejs .btn-warning.disabled,#conversejs .btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-warning:not(:disabled):not(.disabled).active,#conversejs .btn-warning:not(:disabled):not(.disabled):active,.show>#conversejs .btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}#conversejs .btn-warning:not(:disabled):not(.disabled).active:focus,#conversejs .btn-warning:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}#conversejs .btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}#conversejs .btn-danger.focus,#conversejs .btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}#conversejs .btn-danger.disabled,#conversejs .btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-danger:not(:disabled):not(.disabled).active,#conversejs .btn-danger:not(:disabled):not(.disabled):active,.show>#conversejs .btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}#conversejs .btn-danger:not(:disabled):not(.disabled).active:focus,#conversejs .btn-danger:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}#conversejs .btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}#conversejs .btn-light.focus,#conversejs .btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}#conversejs .btn-light.disabled,#conversejs .btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-light:not(:disabled):not(.disabled).active,#conversejs .btn-light:not(:disabled):not(.disabled):active,.show>#conversejs .btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}#conversejs .btn-light:not(:disabled):not(.disabled).active:focus,#conversejs .btn-light:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}#conversejs .btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}#conversejs .btn-dark.focus,#conversejs .btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}#conversejs .btn-dark.disabled,#conversejs .btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-dark:not(:disabled):not(.disabled).active,#conversejs .btn-dark:not(:disabled):not(.disabled):active,.show>#conversejs .btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}#conversejs .btn-dark:not(:disabled):not(.disabled).active:focus,#conversejs .btn-dark:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}#conversejs .btn-outline-primary{color:#007bff;border-color:#007bff}#conversejs .btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-outline-primary.focus,#conversejs .btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}#conversejs .btn-outline-primary.disabled,#conversejs .btn-outline-primary:disabled{color:#007bff;background-color:transparent}#conversejs .btn-outline-primary:not(:disabled):not(.disabled).active,#conversejs .btn-outline-primary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .btn-outline-primary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}#conversejs .btn-outline-secondary{color:#6c757d;border-color:#6c757d}#conversejs .btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-outline-secondary.focus,#conversejs .btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}#conversejs .btn-outline-secondary.disabled,#conversejs .btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}#conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active,#conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}#conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}#conversejs .btn-outline-success{color:#28a745;border-color:#28a745}#conversejs .btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-outline-success.focus,#conversejs .btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}#conversejs .btn-outline-success.disabled,#conversejs .btn-outline-success:disabled{color:#28a745;background-color:transparent}#conversejs .btn-outline-success:not(:disabled):not(.disabled).active,#conversejs .btn-outline-success:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}#conversejs .btn-outline-success:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}#conversejs .btn-outline-info{color:#17a2b8;border-color:#17a2b8}#conversejs .btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-outline-info.focus,#conversejs .btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}#conversejs .btn-outline-info.disabled,#conversejs .btn-outline-info:disabled{color:#17a2b8;background-color:transparent}#conversejs .btn-outline-info:not(:disabled):not(.disabled).active,#conversejs .btn-outline-info:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}#conversejs .btn-outline-info:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}#conversejs .btn-outline-warning{color:#ffc107;border-color:#ffc107}#conversejs .btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-outline-warning.focus,#conversejs .btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}#conversejs .btn-outline-warning.disabled,#conversejs .btn-outline-warning:disabled{color:#ffc107;background-color:transparent}#conversejs .btn-outline-warning:not(:disabled):not(.disabled).active,#conversejs .btn-outline-warning:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}#conversejs .btn-outline-warning:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}#conversejs .btn-outline-danger{color:#dc3545;border-color:#dc3545}#conversejs .btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-outline-danger.focus,#conversejs .btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}#conversejs .btn-outline-danger.disabled,#conversejs .btn-outline-danger:disabled{color:#dc3545;background-color:transparent}#conversejs .btn-outline-danger:not(:disabled):not(.disabled).active,#conversejs .btn-outline-danger:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}#conversejs .btn-outline-danger:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}#conversejs .btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-outline-light.focus,#conversejs .btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}#conversejs .btn-outline-light.disabled,#conversejs .btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}#conversejs .btn-outline-light:not(:disabled):not(.disabled).active,#conversejs .btn-outline-light:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}#conversejs .btn-outline-light:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}#conversejs .btn-outline-dark{color:#343a40;border-color:#343a40}#conversejs .btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-outline-dark.focus,#conversejs .btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}#conversejs .btn-outline-dark.disabled,#conversejs .btn-outline-dark:disabled{color:#343a40;background-color:transparent}#conversejs .btn-outline-dark:not(:disabled):not(.disabled).active,#conversejs .btn-outline-dark:not(:disabled):not(.disabled):active,.show>#conversejs .btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}#conversejs .btn-outline-dark:not(:disabled):not(.disabled).active:focus,#conversejs .btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>#conversejs .btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}#conversejs .btn-link{font-weight:400;color:#007bff;text-decoration:none}#conversejs .btn-link:hover{color:#0056b3;text-decoration:underline}#conversejs .btn-link.focus,#conversejs .btn-link:focus{text-decoration:underline;box-shadow:none}#conversejs .btn-link.disabled,#conversejs .btn-link:disabled{color:#6c757d;pointer-events:none}#conversejs .btn-group-lg>.btn,#conversejs .btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}#conversejs .btn-group-sm>.btn,#conversejs .btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}#conversejs .btn-block{display:block;width:100%}#conversejs .btn-block+.btn-block{margin-top:.5rem}#conversejs input[type=button].btn-block,#conversejs input[type=reset].btn-block,#conversejs input[type=submit].btn-block{width:100%}#conversejs .fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){#conversejs .fade{transition:none}}#conversejs .fade:not(.show){opacity:0}#conversejs .collapse:not(.show){display:none}#conversejs .collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){#conversejs .collapsing{transition:none}}#conversejs .dropdown,#conversejs .dropleft,#conversejs .dropright,#conversejs .dropup{position:relative}#conversejs .dropdown-toggle{white-space:nowrap}#conversejs .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}#conversejs .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}#conversejs .dropdown-menu-left{right:auto;left:0}#conversejs .dropdown-menu-right{right:0;left:auto}@media (min-width:576px){#conversejs .dropdown-menu-sm-left{right:auto;left:0}#conversejs .dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){#conversejs .dropdown-menu-md-left{right:auto;left:0}#conversejs .dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){#conversejs .dropdown-menu-lg-left{right:auto;left:0}#conversejs .dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){#conversejs .dropdown-menu-xl-left{right:auto;left:0}#conversejs .dropdown-menu-xl-right{right:0;left:auto}}#conversejs .dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}#conversejs .dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}#conversejs .dropup .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}#conversejs .dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}#conversejs .dropright .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropright .dropdown-toggle::after{vertical-align:0}#conversejs .dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}#conversejs .dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:\"\"}#conversejs .dropleft .dropdown-toggle::after{display:none}#conversejs .dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:\"\";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}#conversejs .dropleft .dropdown-toggle:empty::after{margin-left:0}#conversejs .dropleft .dropdown-toggle::before{vertical-align:0}#conversejs .dropdown-menu[x-placement^=bottom],#conversejs .dropdown-menu[x-placement^=left],#conversejs .dropdown-menu[x-placement^=right],#conversejs .dropdown-menu[x-placement^=top]{right:auto;bottom:auto}#conversejs .dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}#conversejs .dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}#conversejs .dropdown-item:focus,#conversejs .dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}#conversejs .dropdown-item.active,#conversejs .dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}#conversejs .dropdown-item.disabled,#conversejs .dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}#conversejs .dropdown-menu.show{display:block}#conversejs .dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}#conversejs .dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}#conversejs .btn-group,#conversejs .btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}#conversejs .btn-group-vertical>.btn,#conversejs .btn-group>.btn{position:relative;flex:1 1 auto}#conversejs .btn-group-vertical>.btn:hover,#conversejs .btn-group>.btn:hover{z-index:1}#conversejs .btn-group-vertical>.btn.active,#conversejs .btn-group-vertical>.btn:active,#conversejs .btn-group-vertical>.btn:focus,#conversejs .btn-group>.btn.active,#conversejs .btn-group>.btn:active,#conversejs .btn-group>.btn:focus{z-index:1}#conversejs .btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}#conversejs .btn-toolbar .input-group{width:auto}#conversejs .btn-group>.btn-group:not(:first-child),#conversejs .btn-group>.btn:not(:first-child){margin-left:-1px}#conversejs .btn-group>.btn-group:not(:last-child)>.btn,#conversejs .btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .btn-group>.btn-group:not(:first-child)>.btn,#conversejs .btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}#conversejs .dropdown-toggle-split::after,.dropright #conversejs .dropdown-toggle-split::after,.dropup #conversejs .dropdown-toggle-split::after{margin-left:0}.dropleft #conversejs .dropdown-toggle-split::before{margin-right:0}#conversejs .btn-group-sm>.btn+.dropdown-toggle-split,#conversejs .btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}#conversejs .btn-group-lg>.btn+.dropdown-toggle-split,#conversejs .btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}#conversejs .btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}#conversejs .btn-group-vertical>.btn,#conversejs .btn-group-vertical>.btn-group{width:100%}#conversejs .btn-group-vertical>.btn-group:not(:first-child),#conversejs .btn-group-vertical>.btn:not(:first-child){margin-top:-1px}#conversejs .btn-group-vertical>.btn-group:not(:last-child)>.btn,#conversejs .btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}#conversejs .btn-group-vertical>.btn-group:not(:first-child)>.btn,#conversejs .btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}#conversejs .btn-group-toggle>.btn,#conversejs .btn-group-toggle>.btn-group>.btn{margin-bottom:0}#conversejs .btn-group-toggle>.btn input[type=checkbox],#conversejs .btn-group-toggle>.btn input[type=radio],#conversejs .btn-group-toggle>.btn-group>.btn input[type=checkbox],#conversejs .btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}#conversejs .input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}#conversejs .input-group>.custom-file,#conversejs .input-group>.custom-select,#conversejs .input-group>.form-control,#conversejs .input-group>.form-control-plaintext{position:relative;flex:1 1 0%;min-width:0;margin-bottom:0}#conversejs .input-group>.custom-file+.custom-file,#conversejs .input-group>.custom-file+.custom-select,#conversejs .input-group>.custom-file+.form-control,#conversejs .input-group>.custom-select+.custom-file,#conversejs .input-group>.custom-select+.custom-select,#conversejs .input-group>.custom-select+.form-control,#conversejs .input-group>.form-control+.custom-file,#conversejs .input-group>.form-control+.custom-select,#conversejs .input-group>.form-control+.form-control,#conversejs .input-group>.form-control-plaintext+.custom-file,#conversejs .input-group>.form-control-plaintext+.custom-select,#conversejs .input-group>.form-control-plaintext+.form-control{margin-left:-1px}#conversejs .input-group>.custom-file .custom-file-input:focus~.custom-file-label,#conversejs .input-group>.custom-select:focus,#conversejs .input-group>.form-control:focus{z-index:3}#conversejs .input-group>.custom-file .custom-file-input:focus{z-index:4}#conversejs .input-group>.custom-select:not(:last-child),#conversejs .input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .input-group>.custom-select:not(:first-child),#conversejs .input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .input-group>.custom-file{display:flex;align-items:center}#conversejs .input-group>.custom-file:not(:last-child) .custom-file-label,#conversejs .input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .input-group-append,#conversejs .input-group-prepend{display:flex}#conversejs .input-group-append .btn,#conversejs .input-group-prepend .btn{position:relative;z-index:2}#conversejs .input-group-append .btn:focus,#conversejs .input-group-prepend .btn:focus{z-index:3}#conversejs .input-group-append .btn+.btn,#conversejs .input-group-append .btn+.input-group-text,#conversejs .input-group-append .input-group-text+.btn,#conversejs .input-group-append .input-group-text+.input-group-text,#conversejs .input-group-prepend .btn+.btn,#conversejs .input-group-prepend .btn+.input-group-text,#conversejs .input-group-prepend .input-group-text+.btn,#conversejs .input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}#conversejs .input-group-prepend{margin-right:-1px}#conversejs .input-group-append{margin-left:-1px}#conversejs .input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}#conversejs .input-group-text input[type=checkbox],#conversejs .input-group-text input[type=radio]{margin-top:0}#conversejs .input-group-lg>.custom-select,#conversejs .input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}#conversejs .input-group-lg>.custom-select,#conversejs .input-group-lg>.form-control,#conversejs .input-group-lg>.input-group-append>.btn,#conversejs .input-group-lg>.input-group-append>.input-group-text,#conversejs .input-group-lg>.input-group-prepend>.btn,#conversejs .input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}#conversejs .input-group-sm>.custom-select,#conversejs .input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}#conversejs .input-group-sm>.custom-select,#conversejs .input-group-sm>.form-control,#conversejs .input-group-sm>.input-group-append>.btn,#conversejs .input-group-sm>.input-group-append>.input-group-text,#conversejs .input-group-sm>.input-group-prepend>.btn,#conversejs .input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}#conversejs .input-group-lg>.custom-select,#conversejs .input-group-sm>.custom-select{padding-right:1.75rem}#conversejs .input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),#conversejs .input-group>.input-group-append:last-child>.input-group-text:not(:last-child),#conversejs .input-group>.input-group-append:not(:last-child)>.btn,#conversejs .input-group>.input-group-append:not(:last-child)>.input-group-text,#conversejs .input-group>.input-group-prepend>.btn,#conversejs .input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}#conversejs .input-group>.input-group-append>.btn,#conversejs .input-group>.input-group-append>.input-group-text,#conversejs .input-group>.input-group-prepend:first-child>.btn:not(:first-child),#conversejs .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),#conversejs .input-group>.input-group-prepend:not(:first-child)>.btn,#conversejs .input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}#conversejs .custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}#conversejs .custom-control-inline{display:inline-flex;margin-right:1rem}#conversejs .custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}#conversejs .custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}#conversejs .custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}#conversejs .custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}#conversejs .custom-control-input:disabled~.custom-control-label,#conversejs .custom-control-input[disabled]~.custom-control-label{color:#6c757d}#conversejs .custom-control-input:disabled~.custom-control-label::before,#conversejs .custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}#conversejs .custom-control-label{position:relative;margin-bottom:0;vertical-align:top}#conversejs .custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:\"\";background-color:#fff;border:#adb5bd solid 1px}#conversejs .custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:\"\";background:no-repeat 50%/50% 50%}#conversejs .custom-checkbox .custom-control-label::before{border-radius:.25rem}#conversejs .custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e\")}#conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}#conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\")}#conversejs .custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-radio .custom-control-label::before{border-radius:50%}#conversejs .custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\")}#conversejs .custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-switch{padding-left:2.25rem}#conversejs .custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}#conversejs .custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .custom-switch .custom-control-label::after{transition:none}}#conversejs .custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}#conversejs .custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}#conversejs .custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}#conversejs .custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-select:focus::-ms-value{color:#495057;background-color:#fff}#conversejs .custom-select[multiple],#conversejs .custom-select[size]:not([size=\"1\"]){height:auto;padding-right:.75rem;background-image:none}#conversejs .custom-select:disabled{color:#6c757d;background-color:#e9ecef}#conversejs .custom-select::-ms-expand{display:none}#conversejs .custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}#conversejs .custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}#conversejs .custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}#conversejs .custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}#conversejs .custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}#conversejs .custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-file-input:disabled~.custom-file-label,#conversejs .custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}#conversejs .custom-file-input:lang(en)~.custom-file-label::after{content:\"Browse\"}#conversejs .custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}#conversejs .custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}#conversejs .custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:\"Browse\";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}#conversejs .custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}#conversejs .custom-range:focus{outline:0}#conversejs .custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}#conversejs .custom-range::-moz-focus-outer{border:0}#conversejs .custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){#conversejs .custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}#conversejs .custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}#conversejs .custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}#conversejs .custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){#conversejs .custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}#conversejs .custom-range::-moz-range-thumb:active{background-color:#b3d7ff}#conversejs .custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}#conversejs .custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){#conversejs .custom-range::-ms-thumb{-ms-transition:none;transition:none}}#conversejs .custom-range::-ms-thumb:active{background-color:#b3d7ff}#conversejs .custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}#conversejs .custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}#conversejs .custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}#conversejs .custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}#conversejs .custom-range:disabled::-webkit-slider-runnable-track{cursor:default}#conversejs .custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}#conversejs .custom-range:disabled::-moz-range-track{cursor:default}#conversejs .custom-range:disabled::-ms-thumb{background-color:#adb5bd}#conversejs .custom-control-label::before,#conversejs .custom-file-label,#conversejs .custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .custom-control-label::before,#conversejs .custom-file-label,#conversejs .custom-select{transition:none}}#conversejs .nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}#conversejs .nav-link{display:block;padding:.5rem 1rem}#conversejs .nav-link:focus,#conversejs .nav-link:hover{text-decoration:none}#conversejs .nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}#conversejs .nav-tabs{border-bottom:1px solid #dee2e6}#conversejs .nav-tabs .nav-item{margin-bottom:-1px}#conversejs .nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}#conversejs .nav-tabs .nav-link:focus,#conversejs .nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}#conversejs .nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}#conversejs .nav-tabs .nav-item.show .nav-link,#conversejs .nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}#conversejs .nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}#conversejs .nav-pills .nav-link{border-radius:.25rem}#conversejs .nav-pills .nav-link.active,#conversejs .nav-pills .show>.nav-link{color:#fff;background-color:#007bff}#conversejs .nav-fill .nav-item{flex:1 1 auto;text-align:center}#conversejs .nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}#conversejs .tab-content>.tab-pane{display:none}#conversejs .tab-content>.active{display:block}#conversejs .badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){#conversejs .badge{transition:none}}a#conversejs .badge:focus,a#conversejs .badge:hover{text-decoration:none}#conversejs .badge:empty{display:none}#conversejs .btn .badge{position:relative;top:-1px}#conversejs .badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}#conversejs .badge-primary{color:#fff;background-color:#007bff}a#conversejs .badge-primary:focus,a#conversejs .badge-primary:hover{color:#fff;background-color:#0062cc}a#conversejs .badge-primary.focus,a#conversejs .badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}#conversejs .badge-secondary{color:#fff;background-color:#6c757d}a#conversejs .badge-secondary:focus,a#conversejs .badge-secondary:hover{color:#fff;background-color:#545b62}a#conversejs .badge-secondary.focus,a#conversejs .badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}#conversejs .badge-success{color:#fff;background-color:#28a745}a#conversejs .badge-success:focus,a#conversejs .badge-success:hover{color:#fff;background-color:#1e7e34}a#conversejs .badge-success.focus,a#conversejs .badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}#conversejs .badge-info{color:#fff;background-color:#17a2b8}a#conversejs .badge-info:focus,a#conversejs .badge-info:hover{color:#fff;background-color:#117a8b}a#conversejs .badge-info.focus,a#conversejs .badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}#conversejs .badge-warning{color:#212529;background-color:#ffc107}a#conversejs .badge-warning:focus,a#conversejs .badge-warning:hover{color:#212529;background-color:#d39e00}a#conversejs .badge-warning.focus,a#conversejs .badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}#conversejs .badge-danger{color:#fff;background-color:#dc3545}a#conversejs .badge-danger:focus,a#conversejs .badge-danger:hover{color:#fff;background-color:#bd2130}a#conversejs .badge-danger.focus,a#conversejs .badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}#conversejs .badge-light{color:#212529;background-color:#f8f9fa}a#conversejs .badge-light:focus,a#conversejs .badge-light:hover{color:#212529;background-color:#dae0e5}a#conversejs .badge-light.focus,a#conversejs .badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}#conversejs .badge-dark{color:#fff;background-color:#343a40}a#conversejs .badge-dark:focus,a#conversejs .badge-dark:hover{color:#fff;background-color:#1d2124}a#conversejs .badge-dark.focus,a#conversejs .badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}#conversejs .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}#conversejs .alert-heading{color:inherit}#conversejs .alert-link{font-weight:700}#conversejs .alert-dismissible{padding-right:4rem}#conversejs .alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}#conversejs .alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}#conversejs .alert-primary hr{border-top-color:#9fcdff}#conversejs .alert-primary .alert-link{color:#002752}#conversejs .alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}#conversejs .alert-secondary hr{border-top-color:#c8cbcf}#conversejs .alert-secondary .alert-link{color:#202326}#conversejs .alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}#conversejs .alert-success hr{border-top-color:#b1dfbb}#conversejs .alert-success .alert-link{color:#0b2e13}#conversejs .alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}#conversejs .alert-info hr{border-top-color:#abdde5}#conversejs .alert-info .alert-link{color:#062c33}#conversejs .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}#conversejs .alert-warning hr{border-top-color:#ffe8a1}#conversejs .alert-warning .alert-link{color:#533f03}#conversejs .alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}#conversejs .alert-danger hr{border-top-color:#f1b0b7}#conversejs .alert-danger .alert-link{color:#491217}#conversejs .alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}#conversejs .alert-light hr{border-top-color:#ececf6}#conversejs .alert-light .alert-link{color:#686868}#conversejs .alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}#conversejs .alert-dark hr{border-top-color:#b9bbbe}#conversejs .alert-dark .alert-link{color:#040505}#conversejs .media{display:flex;align-items:flex-start}#conversejs .media-body{flex:1}#conversejs .list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}#conversejs .list-group-item-action{width:100%;color:#495057;text-align:inherit}#conversejs .list-group-item-action:focus,#conversejs .list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}#conversejs .list-group-item-action:active{color:#212529;background-color:#e9ecef}#conversejs .list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}#conversejs .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}#conversejs .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}#conversejs .list-group-item.disabled,#conversejs .list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}#conversejs .list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}#conversejs .list-group-item+#conversejs .list-group-item{border-top-width:0}#conversejs .list-group-item+#conversejs .list-group-item.active{margin-top:-1px;border-top-width:1px}#conversejs .list-group-horizontal{flex-direction:row}#conversejs .list-group-horizontal .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){#conversejs .list-group-horizontal-sm{flex-direction:row}#conversejs .list-group-horizontal-sm .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-sm .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-sm .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-sm .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-sm .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){#conversejs .list-group-horizontal-md{flex-direction:row}#conversejs .list-group-horizontal-md .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-md .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-md .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-md .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-md .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){#conversejs .list-group-horizontal-lg{flex-direction:row}#conversejs .list-group-horizontal-lg .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-lg .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-lg .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-lg .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-lg .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){#conversejs .list-group-horizontal-xl{flex-direction:row}#conversejs .list-group-horizontal-xl .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}#conversejs .list-group-horizontal-xl .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}#conversejs .list-group-horizontal-xl .list-group-item.active{margin-top:0}#conversejs .list-group-horizontal-xl .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}#conversejs .list-group-horizontal-xl .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}#conversejs .list-group-flush .list-group-item{border-right-width:0;border-left-width:0;border-radius:0}#conversejs .list-group-flush .list-group-item:first-child{border-top-width:0}#conversejs .list-group-flush:last-child .list-group-item:last-child{border-bottom-width:0}#conversejs .list-group-item-primary{color:#004085;background-color:#b8daff}#conversejs .list-group-item-primary.list-group-item-action:focus,#conversejs .list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}#conversejs .list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}#conversejs .list-group-item-secondary{color:#383d41;background-color:#d6d8db}#conversejs .list-group-item-secondary.list-group-item-action:focus,#conversejs .list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}#conversejs .list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}#conversejs .list-group-item-success{color:#155724;background-color:#c3e6cb}#conversejs .list-group-item-success.list-group-item-action:focus,#conversejs .list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}#conversejs .list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}#conversejs .list-group-item-info{color:#0c5460;background-color:#bee5eb}#conversejs .list-group-item-info.list-group-item-action:focus,#conversejs .list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}#conversejs .list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}#conversejs .list-group-item-warning{color:#856404;background-color:#ffeeba}#conversejs .list-group-item-warning.list-group-item-action:focus,#conversejs .list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}#conversejs .list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}#conversejs .list-group-item-danger{color:#721c24;background-color:#f5c6cb}#conversejs .list-group-item-danger.list-group-item-action:focus,#conversejs .list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}#conversejs .list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}#conversejs .list-group-item-light{color:#818182;background-color:#fdfdfe}#conversejs .list-group-item-light.list-group-item-action:focus,#conversejs .list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}#conversejs .list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}#conversejs .list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}#conversejs .list-group-item-dark.list-group-item-action:focus,#conversejs .list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}#conversejs .list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}#conversejs .close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}#conversejs .close:hover{color:#000;text-decoration:none}#conversejs .close:not(:disabled):not(.disabled):focus,#conversejs .close:not(:disabled):not(.disabled):hover{opacity:.75}#conversejs button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}#conversejs a.close.disabled{pointer-events:none}#conversejs .modal-open{overflow:hidden}#conversejs .modal-open .modal{overflow-x:hidden;overflow-y:auto}#conversejs .modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}#conversejs .modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade #conversejs .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade #conversejs .modal-dialog{transition:none}}.modal.show #conversejs .modal-dialog{transform:none}.modal.modal-static #conversejs .modal-dialog{transform:scale(1.02)}#conversejs .modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}#conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}#conversejs .modal-dialog-scrollable .modal-footer,#conversejs .modal-dialog-scrollable .modal-header{flex-shrink:0}#conversejs .modal-dialog-scrollable .modal-body{overflow-y:auto}#conversejs .modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}#conversejs .modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:\"\"}#conversejs .modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}#conversejs .modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}#conversejs .modal-dialog-centered.modal-dialog-scrollable::before{content:none}#conversejs .modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}#conversejs .modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}#conversejs .modal-backdrop.fade{opacity:0}#conversejs .modal-backdrop.show{opacity:.5}#conversejs .modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}#conversejs .modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}#conversejs .modal-title{margin-bottom:0;line-height:1.5}#conversejs .modal-body{position:relative;flex:1 1 auto;padding:1rem}#conversejs .modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}#conversejs .modal-footer>*{margin:.25rem}#conversejs .modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){#conversejs .modal-dialog{max-width:500px;margin:1.75rem auto}#conversejs .modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}#conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}#conversejs .modal-dialog-centered{min-height:calc(100% - 3.5rem)}#conversejs .modal-dialog-centered::before{height:calc(100vh - 3.5rem)}#conversejs .modal-sm{max-width:300px}}@media (min-width:992px){#conversejs .modal-lg,#conversejs .modal-xl{max-width:800px}}@media (min-width:1200px){#conversejs .modal-xl{max-width:1140px}}#conversejs .tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}#conversejs .tooltip.show{opacity:.9}#conversejs .tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}#conversejs .tooltip .arrow::before{position:absolute;content:\"\";border-color:transparent;border-style:solid}#conversejs .bs-tooltip-auto[x-placement^=top],#conversejs .bs-tooltip-top{padding:.4rem 0}#conversejs .bs-tooltip-auto[x-placement^=top] .arrow,#conversejs .bs-tooltip-top .arrow{bottom:0}#conversejs .bs-tooltip-auto[x-placement^=top] .arrow::before,#conversejs .bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}#conversejs .bs-tooltip-auto[x-placement^=right],#conversejs .bs-tooltip-right{padding:0 .4rem}#conversejs .bs-tooltip-auto[x-placement^=right] .arrow,#conversejs .bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}#conversejs .bs-tooltip-auto[x-placement^=right] .arrow::before,#conversejs .bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}#conversejs .bs-tooltip-auto[x-placement^=bottom],#conversejs .bs-tooltip-bottom{padding:.4rem 0}#conversejs .bs-tooltip-auto[x-placement^=bottom] .arrow,#conversejs .bs-tooltip-bottom .arrow{top:0}#conversejs .bs-tooltip-auto[x-placement^=bottom] .arrow::before,#conversejs .bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}#conversejs .bs-tooltip-auto[x-placement^=left],#conversejs .bs-tooltip-left{padding:0 .4rem}#conversejs .bs-tooltip-auto[x-placement^=left] .arrow,#conversejs .bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}#conversejs .bs-tooltip-auto[x-placement^=left] .arrow::before,#conversejs .bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}#conversejs .tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}#conversejs .popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}#conversejs .popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}#conversejs .popover .arrow::after,#conversejs .popover .arrow::before{position:absolute;display:block;content:\"\";border-color:transparent;border-style:solid}#conversejs .bs-popover-auto[x-placement^=top],#conversejs .bs-popover-top{margin-bottom:.5rem}#conversejs .bs-popover-auto[x-placement^=top]>.arrow,#conversejs .bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}#conversejs .bs-popover-auto[x-placement^=top]>.arrow::before,#conversejs .bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=top]>.arrow::after,#conversejs .bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}#conversejs .bs-popover-auto[x-placement^=right],#conversejs .bs-popover-right{margin-left:.5rem}#conversejs .bs-popover-auto[x-placement^=right]>.arrow,#conversejs .bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}#conversejs .bs-popover-auto[x-placement^=right]>.arrow::before,#conversejs .bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=right]>.arrow::after,#conversejs .bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}#conversejs .bs-popover-auto[x-placement^=bottom],#conversejs .bs-popover-bottom{margin-top:.5rem}#conversejs .bs-popover-auto[x-placement^=bottom]>.arrow,#conversejs .bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}#conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::before,#conversejs .bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::after,#conversejs .bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}#conversejs .bs-popover-auto[x-placement^=bottom] .popover-header::before,#conversejs .bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:\"\";border-bottom:1px solid #f7f7f7}#conversejs .bs-popover-auto[x-placement^=left],#conversejs .bs-popover-left{margin-right:.5rem}#conversejs .bs-popover-auto[x-placement^=left]>.arrow,#conversejs .bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}#conversejs .bs-popover-auto[x-placement^=left]>.arrow::before,#conversejs .bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}#conversejs .bs-popover-auto[x-placement^=left]>.arrow::after,#conversejs .bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}#conversejs .popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}#conversejs .popover-header:empty{display:none}#conversejs .popover-body{padding:.5rem .75rem;color:#212529}#conversejs .align-baseline{vertical-align:baseline!important}#conversejs .align-top{vertical-align:top!important}#conversejs .align-middle{vertical-align:middle!important}#conversejs .align-bottom{vertical-align:bottom!important}#conversejs .align-text-bottom{vertical-align:text-bottom!important}#conversejs .align-text-top{vertical-align:text-top!important}#conversejs .bg-primary{background-color:#007bff!important}#conversejs a.bg-primary:focus,#conversejs a.bg-primary:hover,#conversejs button.bg-primary:focus,#conversejs button.bg-primary:hover{background-color:#0062cc!important}#conversejs .bg-secondary{background-color:#6c757d!important}#conversejs a.bg-secondary:focus,#conversejs a.bg-secondary:hover,#conversejs button.bg-secondary:focus,#conversejs button.bg-secondary:hover{background-color:#545b62!important}#conversejs .bg-success{background-color:#28a745!important}#conversejs a.bg-success:focus,#conversejs a.bg-success:hover,#conversejs button.bg-success:focus,#conversejs button.bg-success:hover{background-color:#1e7e34!important}#conversejs .bg-info{background-color:#17a2b8!important}#conversejs a.bg-info:focus,#conversejs a.bg-info:hover,#conversejs button.bg-info:focus,#conversejs button.bg-info:hover{background-color:#117a8b!important}#conversejs .bg-warning{background-color:#ffc107!important}#conversejs a.bg-warning:focus,#conversejs a.bg-warning:hover,#conversejs button.bg-warning:focus,#conversejs button.bg-warning:hover{background-color:#d39e00!important}#conversejs .bg-danger{background-color:#dc3545!important}#conversejs a.bg-danger:focus,#conversejs a.bg-danger:hover,#conversejs button.bg-danger:focus,#conversejs button.bg-danger:hover{background-color:#bd2130!important}#conversejs .bg-light{background-color:#f8f9fa!important}#conversejs a.bg-light:focus,#conversejs a.bg-light:hover,#conversejs button.bg-light:focus,#conversejs button.bg-light:hover{background-color:#dae0e5!important}#conversejs .bg-dark{background-color:#343a40!important}#conversejs a.bg-dark:focus,#conversejs a.bg-dark:hover,#conversejs button.bg-dark:focus,#conversejs button.bg-dark:hover{background-color:#1d2124!important}#conversejs .bg-white{background-color:#fff!important}#conversejs .bg-transparent{background-color:transparent!important}#conversejs .border{border:1px solid #dee2e6!important}#conversejs .border-top{border-top:1px solid #dee2e6!important}#conversejs .border-right{border-right:1px solid #dee2e6!important}#conversejs .border-bottom{border-bottom:1px solid #dee2e6!important}#conversejs .border-left{border-left:1px solid #dee2e6!important}#conversejs .border-0{border:0!important}#conversejs .border-top-0{border-top:0!important}#conversejs .border-right-0{border-right:0!important}#conversejs .border-bottom-0{border-bottom:0!important}#conversejs .border-left-0{border-left:0!important}#conversejs .border-primary{border-color:#007bff!important}#conversejs .border-secondary{border-color:#6c757d!important}#conversejs .border-success{border-color:#28a745!important}#conversejs .border-info{border-color:#17a2b8!important}#conversejs .border-warning{border-color:#ffc107!important}#conversejs .border-danger{border-color:#dc3545!important}#conversejs .border-light{border-color:#f8f9fa!important}#conversejs .border-dark{border-color:#343a40!important}#conversejs .border-white{border-color:#fff!important}#conversejs .rounded-sm{border-radius:.2rem!important}#conversejs .rounded{border-radius:.25rem!important}#conversejs .rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}#conversejs .rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}#conversejs .rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}#conversejs .rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}#conversejs .rounded-lg{border-radius:.3rem!important}#conversejs .rounded-circle{border-radius:50%!important}#conversejs .rounded-pill{border-radius:50rem!important}#conversejs .rounded-0{border-radius:0!important}#conversejs .clearfix::after{display:block;clear:both;content:\"\"}#conversejs .d-none{display:none!important}#conversejs .d-inline{display:inline!important}#conversejs .d-inline-block{display:inline-block!important}#conversejs .d-block{display:block!important}#conversejs .d-table{display:table!important}#conversejs .d-table-row{display:table-row!important}#conversejs .d-table-cell{display:table-cell!important}#conversejs .d-flex{display:flex!important}#conversejs .d-inline-flex{display:inline-flex!important}@media (min-width:576px){#conversejs .d-sm-none{display:none!important}#conversejs .d-sm-inline{display:inline!important}#conversejs .d-sm-inline-block{display:inline-block!important}#conversejs .d-sm-block{display:block!important}#conversejs .d-sm-table{display:table!important}#conversejs .d-sm-table-row{display:table-row!important}#conversejs .d-sm-table-cell{display:table-cell!important}#conversejs .d-sm-flex{display:flex!important}#conversejs .d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){#conversejs .d-md-none{display:none!important}#conversejs .d-md-inline{display:inline!important}#conversejs .d-md-inline-block{display:inline-block!important}#conversejs .d-md-block{display:block!important}#conversejs .d-md-table{display:table!important}#conversejs .d-md-table-row{display:table-row!important}#conversejs .d-md-table-cell{display:table-cell!important}#conversejs .d-md-flex{display:flex!important}#conversejs .d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){#conversejs .d-lg-none{display:none!important}#conversejs .d-lg-inline{display:inline!important}#conversejs .d-lg-inline-block{display:inline-block!important}#conversejs .d-lg-block{display:block!important}#conversejs .d-lg-table{display:table!important}#conversejs .d-lg-table-row{display:table-row!important}#conversejs .d-lg-table-cell{display:table-cell!important}#conversejs .d-lg-flex{display:flex!important}#conversejs .d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){#conversejs .d-xl-none{display:none!important}#conversejs .d-xl-inline{display:inline!important}#conversejs .d-xl-inline-block{display:inline-block!important}#conversejs .d-xl-block{display:block!important}#conversejs .d-xl-table{display:table!important}#conversejs .d-xl-table-row{display:table-row!important}#conversejs .d-xl-table-cell{display:table-cell!important}#conversejs .d-xl-flex{display:flex!important}#conversejs .d-xl-inline-flex{display:inline-flex!important}}@media print{#conversejs .d-print-none{display:none!important}#conversejs .d-print-inline{display:inline!important}#conversejs .d-print-inline-block{display:inline-block!important}#conversejs .d-print-block{display:block!important}#conversejs .d-print-table{display:table!important}#conversejs .d-print-table-row{display:table-row!important}#conversejs .d-print-table-cell{display:table-cell!important}#conversejs .d-print-flex{display:flex!important}#conversejs .d-print-inline-flex{display:inline-flex!important}}#conversejs .embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}#conversejs .embed-responsive::before{display:block;content:\"\"}#conversejs .embed-responsive .embed-responsive-item,#conversejs .embed-responsive embed,#conversejs .embed-responsive iframe,#conversejs .embed-responsive object,#conversejs .embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}#conversejs .embed-responsive-21by9::before{padding-top:42.85714%}#conversejs .embed-responsive-16by9::before{padding-top:56.25%}#conversejs .embed-responsive-4by3::before{padding-top:75%}#conversejs .embed-responsive-1by1::before{padding-top:100%}#conversejs .flex-row{flex-direction:row!important}#conversejs .flex-column{flex-direction:column!important}#conversejs .flex-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-wrap{flex-wrap:wrap!important}#conversejs .flex-nowrap{flex-wrap:nowrap!important}#conversejs .flex-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-fill{flex:1 1 auto!important}#conversejs .flex-grow-0{flex-grow:0!important}#conversejs .flex-grow-1{flex-grow:1!important}#conversejs .flex-shrink-0{flex-shrink:0!important}#conversejs .flex-shrink-1{flex-shrink:1!important}#conversejs .justify-content-start{justify-content:flex-start!important}#conversejs .justify-content-end{justify-content:flex-end!important}#conversejs .justify-content-center{justify-content:center!important}#conversejs .justify-content-between{justify-content:space-between!important}#conversejs .justify-content-around{justify-content:space-around!important}#conversejs .align-items-start{align-items:flex-start!important}#conversejs .align-items-end{align-items:flex-end!important}#conversejs .align-items-center{align-items:center!important}#conversejs .align-items-baseline{align-items:baseline!important}#conversejs .align-items-stretch{align-items:stretch!important}#conversejs .align-content-start{align-content:flex-start!important}#conversejs .align-content-end{align-content:flex-end!important}#conversejs .align-content-center{align-content:center!important}#conversejs .align-content-between{align-content:space-between!important}#conversejs .align-content-around{align-content:space-around!important}#conversejs .align-content-stretch{align-content:stretch!important}#conversejs .align-self-auto{align-self:auto!important}#conversejs .align-self-start{align-self:flex-start!important}#conversejs .align-self-end{align-self:flex-end!important}#conversejs .align-self-center{align-self:center!important}#conversejs .align-self-baseline{align-self:baseline!important}#conversejs .align-self-stretch{align-self:stretch!important}@media (min-width:576px){#conversejs .flex-sm-row{flex-direction:row!important}#conversejs .flex-sm-column{flex-direction:column!important}#conversejs .flex-sm-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-sm-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-sm-wrap{flex-wrap:wrap!important}#conversejs .flex-sm-nowrap{flex-wrap:nowrap!important}#conversejs .flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-sm-fill{flex:1 1 auto!important}#conversejs .flex-sm-grow-0{flex-grow:0!important}#conversejs .flex-sm-grow-1{flex-grow:1!important}#conversejs .flex-sm-shrink-0{flex-shrink:0!important}#conversejs .flex-sm-shrink-1{flex-shrink:1!important}#conversejs .justify-content-sm-start{justify-content:flex-start!important}#conversejs .justify-content-sm-end{justify-content:flex-end!important}#conversejs .justify-content-sm-center{justify-content:center!important}#conversejs .justify-content-sm-between{justify-content:space-between!important}#conversejs .justify-content-sm-around{justify-content:space-around!important}#conversejs .align-items-sm-start{align-items:flex-start!important}#conversejs .align-items-sm-end{align-items:flex-end!important}#conversejs .align-items-sm-center{align-items:center!important}#conversejs .align-items-sm-baseline{align-items:baseline!important}#conversejs .align-items-sm-stretch{align-items:stretch!important}#conversejs .align-content-sm-start{align-content:flex-start!important}#conversejs .align-content-sm-end{align-content:flex-end!important}#conversejs .align-content-sm-center{align-content:center!important}#conversejs .align-content-sm-between{align-content:space-between!important}#conversejs .align-content-sm-around{align-content:space-around!important}#conversejs .align-content-sm-stretch{align-content:stretch!important}#conversejs .align-self-sm-auto{align-self:auto!important}#conversejs .align-self-sm-start{align-self:flex-start!important}#conversejs .align-self-sm-end{align-self:flex-end!important}#conversejs .align-self-sm-center{align-self:center!important}#conversejs .align-self-sm-baseline{align-self:baseline!important}#conversejs .align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){#conversejs .flex-md-row{flex-direction:row!important}#conversejs .flex-md-column{flex-direction:column!important}#conversejs .flex-md-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-md-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-md-wrap{flex-wrap:wrap!important}#conversejs .flex-md-nowrap{flex-wrap:nowrap!important}#conversejs .flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-md-fill{flex:1 1 auto!important}#conversejs .flex-md-grow-0{flex-grow:0!important}#conversejs .flex-md-grow-1{flex-grow:1!important}#conversejs .flex-md-shrink-0{flex-shrink:0!important}#conversejs .flex-md-shrink-1{flex-shrink:1!important}#conversejs .justify-content-md-start{justify-content:flex-start!important}#conversejs .justify-content-md-end{justify-content:flex-end!important}#conversejs .justify-content-md-center{justify-content:center!important}#conversejs .justify-content-md-between{justify-content:space-between!important}#conversejs .justify-content-md-around{justify-content:space-around!important}#conversejs .align-items-md-start{align-items:flex-start!important}#conversejs .align-items-md-end{align-items:flex-end!important}#conversejs .align-items-md-center{align-items:center!important}#conversejs .align-items-md-baseline{align-items:baseline!important}#conversejs .align-items-md-stretch{align-items:stretch!important}#conversejs .align-content-md-start{align-content:flex-start!important}#conversejs .align-content-md-end{align-content:flex-end!important}#conversejs .align-content-md-center{align-content:center!important}#conversejs .align-content-md-between{align-content:space-between!important}#conversejs .align-content-md-around{align-content:space-around!important}#conversejs .align-content-md-stretch{align-content:stretch!important}#conversejs .align-self-md-auto{align-self:auto!important}#conversejs .align-self-md-start{align-self:flex-start!important}#conversejs .align-self-md-end{align-self:flex-end!important}#conversejs .align-self-md-center{align-self:center!important}#conversejs .align-self-md-baseline{align-self:baseline!important}#conversejs .align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){#conversejs .flex-lg-row{flex-direction:row!important}#conversejs .flex-lg-column{flex-direction:column!important}#conversejs .flex-lg-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-lg-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-lg-wrap{flex-wrap:wrap!important}#conversejs .flex-lg-nowrap{flex-wrap:nowrap!important}#conversejs .flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-lg-fill{flex:1 1 auto!important}#conversejs .flex-lg-grow-0{flex-grow:0!important}#conversejs .flex-lg-grow-1{flex-grow:1!important}#conversejs .flex-lg-shrink-0{flex-shrink:0!important}#conversejs .flex-lg-shrink-1{flex-shrink:1!important}#conversejs .justify-content-lg-start{justify-content:flex-start!important}#conversejs .justify-content-lg-end{justify-content:flex-end!important}#conversejs .justify-content-lg-center{justify-content:center!important}#conversejs .justify-content-lg-between{justify-content:space-between!important}#conversejs .justify-content-lg-around{justify-content:space-around!important}#conversejs .align-items-lg-start{align-items:flex-start!important}#conversejs .align-items-lg-end{align-items:flex-end!important}#conversejs .align-items-lg-center{align-items:center!important}#conversejs .align-items-lg-baseline{align-items:baseline!important}#conversejs .align-items-lg-stretch{align-items:stretch!important}#conversejs .align-content-lg-start{align-content:flex-start!important}#conversejs .align-content-lg-end{align-content:flex-end!important}#conversejs .align-content-lg-center{align-content:center!important}#conversejs .align-content-lg-between{align-content:space-between!important}#conversejs .align-content-lg-around{align-content:space-around!important}#conversejs .align-content-lg-stretch{align-content:stretch!important}#conversejs .align-self-lg-auto{align-self:auto!important}#conversejs .align-self-lg-start{align-self:flex-start!important}#conversejs .align-self-lg-end{align-self:flex-end!important}#conversejs .align-self-lg-center{align-self:center!important}#conversejs .align-self-lg-baseline{align-self:baseline!important}#conversejs .align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){#conversejs .flex-xl-row{flex-direction:row!important}#conversejs .flex-xl-column{flex-direction:column!important}#conversejs .flex-xl-row-reverse{flex-direction:row-reverse!important}#conversejs .flex-xl-column-reverse{flex-direction:column-reverse!important}#conversejs .flex-xl-wrap{flex-wrap:wrap!important}#conversejs .flex-xl-nowrap{flex-wrap:nowrap!important}#conversejs .flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}#conversejs .flex-xl-fill{flex:1 1 auto!important}#conversejs .flex-xl-grow-0{flex-grow:0!important}#conversejs .flex-xl-grow-1{flex-grow:1!important}#conversejs .flex-xl-shrink-0{flex-shrink:0!important}#conversejs .flex-xl-shrink-1{flex-shrink:1!important}#conversejs .justify-content-xl-start{justify-content:flex-start!important}#conversejs .justify-content-xl-end{justify-content:flex-end!important}#conversejs .justify-content-xl-center{justify-content:center!important}#conversejs .justify-content-xl-between{justify-content:space-between!important}#conversejs .justify-content-xl-around{justify-content:space-around!important}#conversejs .align-items-xl-start{align-items:flex-start!important}#conversejs .align-items-xl-end{align-items:flex-end!important}#conversejs .align-items-xl-center{align-items:center!important}#conversejs .align-items-xl-baseline{align-items:baseline!important}#conversejs .align-items-xl-stretch{align-items:stretch!important}#conversejs .align-content-xl-start{align-content:flex-start!important}#conversejs .align-content-xl-end{align-content:flex-end!important}#conversejs .align-content-xl-center{align-content:center!important}#conversejs .align-content-xl-between{align-content:space-between!important}#conversejs .align-content-xl-around{align-content:space-around!important}#conversejs .align-content-xl-stretch{align-content:stretch!important}#conversejs .align-self-xl-auto{align-self:auto!important}#conversejs .align-self-xl-start{align-self:flex-start!important}#conversejs .align-self-xl-end{align-self:flex-end!important}#conversejs .align-self-xl-center{align-self:center!important}#conversejs .align-self-xl-baseline{align-self:baseline!important}#conversejs .align-self-xl-stretch{align-self:stretch!important}}#conversejs .float-left{float:left!important}#conversejs .float-right{float:right!important}#conversejs .float-none{float:none!important}@media (min-width:576px){#conversejs .float-sm-left{float:left!important}#conversejs .float-sm-right{float:right!important}#conversejs .float-sm-none{float:none!important}}@media (min-width:768px){#conversejs .float-md-left{float:left!important}#conversejs .float-md-right{float:right!important}#conversejs .float-md-none{float:none!important}}@media (min-width:992px){#conversejs .float-lg-left{float:left!important}#conversejs .float-lg-right{float:right!important}#conversejs .float-lg-none{float:none!important}}@media (min-width:1200px){#conversejs .float-xl-left{float:left!important}#conversejs .float-xl-right{float:right!important}#conversejs .float-xl-none{float:none!important}}#conversejs .overflow-auto{overflow:auto!important}#conversejs .overflow-hidden{overflow:hidden!important}#conversejs .position-static{position:static!important}#conversejs .position-relative{position:relative!important}#conversejs .position-absolute{position:absolute!important}#conversejs .position-fixed{position:fixed!important}#conversejs .position-sticky{position:-webkit-sticky!important;position:sticky!important}#conversejs .fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}#conversejs .fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){#conversejs .sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}#conversejs .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}#conversejs .sr-only-focusable:active,#conversejs .sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}#conversejs .shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}#conversejs .shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}#conversejs .shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}#conversejs .shadow-none{box-shadow:none!important}#conversejs .w-25{width:25%!important}#conversejs .w-50{width:50%!important}#conversejs .w-75{width:75%!important}#conversejs .w-100{width:100%!important}#conversejs .w-auto{width:auto!important}#conversejs .h-25{height:25%!important}#conversejs .h-50{height:50%!important}#conversejs .h-75{height:75%!important}#conversejs .h-100{height:100%!important}#conversejs .h-auto{height:auto!important}#conversejs .mw-100{max-width:100%!important}#conversejs .mh-100{max-height:100%!important}#conversejs .min-vw-100{min-width:100vw!important}#conversejs .min-vh-100{min-height:100vh!important}#conversejs .vw-100{width:100vw!important}#conversejs .vh-100{height:100vh!important}#conversejs .stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:\"\";background-color:rgba(0,0,0,0)}#conversejs .m-0{margin:0!important}#conversejs .mt-0,#conversejs .my-0{margin-top:0!important}#conversejs .mr-0,#conversejs .mx-0{margin-right:0!important}#conversejs .mb-0,#conversejs .my-0{margin-bottom:0!important}#conversejs .ml-0,#conversejs .mx-0{margin-left:0!important}#conversejs .m-1{margin:.25rem!important}#conversejs .mt-1,#conversejs .my-1{margin-top:.25rem!important}#conversejs .mr-1,#conversejs .mx-1{margin-right:.25rem!important}#conversejs .mb-1,#conversejs .my-1{margin-bottom:.25rem!important}#conversejs .ml-1,#conversejs .mx-1{margin-left:.25rem!important}#conversejs .m-2{margin:.5rem!important}#conversejs .mt-2,#conversejs .my-2{margin-top:.5rem!important}#conversejs .mr-2,#conversejs .mx-2{margin-right:.5rem!important}#conversejs .mb-2,#conversejs .my-2{margin-bottom:.5rem!important}#conversejs .ml-2,#conversejs .mx-2{margin-left:.5rem!important}#conversejs .m-3{margin:1rem!important}#conversejs .mt-3,#conversejs .my-3{margin-top:1rem!important}#conversejs .mr-3,#conversejs .mx-3{margin-right:1rem!important}#conversejs .mb-3,#conversejs .my-3{margin-bottom:1rem!important}#conversejs .ml-3,#conversejs .mx-3{margin-left:1rem!important}#conversejs .m-4{margin:1.5rem!important}#conversejs .mt-4,#conversejs .my-4{margin-top:1.5rem!important}#conversejs .mr-4,#conversejs .mx-4{margin-right:1.5rem!important}#conversejs .mb-4,#conversejs .my-4{margin-bottom:1.5rem!important}#conversejs .ml-4,#conversejs .mx-4{margin-left:1.5rem!important}#conversejs .m-5{margin:3rem!important}#conversejs .mt-5,#conversejs .my-5{margin-top:3rem!important}#conversejs .mr-5,#conversejs .mx-5{margin-right:3rem!important}#conversejs .mb-5,#conversejs .my-5{margin-bottom:3rem!important}#conversejs .ml-5,#conversejs .mx-5{margin-left:3rem!important}#conversejs .p-0{padding:0!important}#conversejs .pt-0,#conversejs .py-0{padding-top:0!important}#conversejs .pr-0,#conversejs .px-0{padding-right:0!important}#conversejs .pb-0,#conversejs .py-0{padding-bottom:0!important}#conversejs .pl-0,#conversejs .px-0{padding-left:0!important}#conversejs .p-1{padding:.25rem!important}#conversejs .pt-1,#conversejs .py-1{padding-top:.25rem!important}#conversejs .pr-1,#conversejs .px-1{padding-right:.25rem!important}#conversejs .pb-1,#conversejs .py-1{padding-bottom:.25rem!important}#conversejs .pl-1,#conversejs .px-1{padding-left:.25rem!important}#conversejs .p-2{padding:.5rem!important}#conversejs .pt-2,#conversejs .py-2{padding-top:.5rem!important}#conversejs .pr-2,#conversejs .px-2{padding-right:.5rem!important}#conversejs .pb-2,#conversejs .py-2{padding-bottom:.5rem!important}#conversejs .pl-2,#conversejs .px-2{padding-left:.5rem!important}#conversejs .p-3{padding:1rem!important}#conversejs .pt-3,#conversejs .py-3{padding-top:1rem!important}#conversejs .pr-3,#conversejs .px-3{padding-right:1rem!important}#conversejs .pb-3,#conversejs .py-3{padding-bottom:1rem!important}#conversejs .pl-3,#conversejs .px-3{padding-left:1rem!important}#conversejs .p-4{padding:1.5rem!important}#conversejs .pt-4,#conversejs .py-4{padding-top:1.5rem!important}#conversejs .pr-4,#conversejs .px-4{padding-right:1.5rem!important}#conversejs .pb-4,#conversejs .py-4{padding-bottom:1.5rem!important}#conversejs .pl-4,#conversejs .px-4{padding-left:1.5rem!important}#conversejs .p-5{padding:3rem!important}#conversejs .pt-5,#conversejs .py-5{padding-top:3rem!important}#conversejs .pr-5,#conversejs .px-5{padding-right:3rem!important}#conversejs .pb-5,#conversejs .py-5{padding-bottom:3rem!important}#conversejs .pl-5,#conversejs .px-5{padding-left:3rem!important}#conversejs .m-n1{margin:-.25rem!important}#conversejs .mt-n1,#conversejs .my-n1{margin-top:-.25rem!important}#conversejs .mr-n1,#conversejs .mx-n1{margin-right:-.25rem!important}#conversejs .mb-n1,#conversejs .my-n1{margin-bottom:-.25rem!important}#conversejs .ml-n1,#conversejs .mx-n1{margin-left:-.25rem!important}#conversejs .m-n2{margin:-.5rem!important}#conversejs .mt-n2,#conversejs .my-n2{margin-top:-.5rem!important}#conversejs .mr-n2,#conversejs .mx-n2{margin-right:-.5rem!important}#conversejs .mb-n2,#conversejs .my-n2{margin-bottom:-.5rem!important}#conversejs .ml-n2,#conversejs .mx-n2{margin-left:-.5rem!important}#conversejs .m-n3{margin:-1rem!important}#conversejs .mt-n3,#conversejs .my-n3{margin-top:-1rem!important}#conversejs .mr-n3,#conversejs .mx-n3{margin-right:-1rem!important}#conversejs .mb-n3,#conversejs .my-n3{margin-bottom:-1rem!important}#conversejs .ml-n3,#conversejs .mx-n3{margin-left:-1rem!important}#conversejs .m-n4{margin:-1.5rem!important}#conversejs .mt-n4,#conversejs .my-n4{margin-top:-1.5rem!important}#conversejs .mr-n4,#conversejs .mx-n4{margin-right:-1.5rem!important}#conversejs .mb-n4,#conversejs .my-n4{margin-bottom:-1.5rem!important}#conversejs .ml-n4,#conversejs .mx-n4{margin-left:-1.5rem!important}#conversejs .m-n5{margin:-3rem!important}#conversejs .mt-n5,#conversejs .my-n5{margin-top:-3rem!important}#conversejs .mr-n5,#conversejs .mx-n5{margin-right:-3rem!important}#conversejs .mb-n5,#conversejs .my-n5{margin-bottom:-3rem!important}#conversejs .ml-n5,#conversejs .mx-n5{margin-left:-3rem!important}#conversejs .m-auto{margin:auto!important}#conversejs .mt-auto,#conversejs .my-auto{margin-top:auto!important}#conversejs .mr-auto,#conversejs .mx-auto{margin-right:auto!important}#conversejs .mb-auto,#conversejs .my-auto{margin-bottom:auto!important}#conversejs .ml-auto,#conversejs .mx-auto{margin-left:auto!important}@media (min-width:576px){#conversejs .m-sm-0{margin:0!important}#conversejs .mt-sm-0,#conversejs .my-sm-0{margin-top:0!important}#conversejs .mr-sm-0,#conversejs .mx-sm-0{margin-right:0!important}#conversejs .mb-sm-0,#conversejs .my-sm-0{margin-bottom:0!important}#conversejs .ml-sm-0,#conversejs .mx-sm-0{margin-left:0!important}#conversejs .m-sm-1{margin:.25rem!important}#conversejs .mt-sm-1,#conversejs .my-sm-1{margin-top:.25rem!important}#conversejs .mr-sm-1,#conversejs .mx-sm-1{margin-right:.25rem!important}#conversejs .mb-sm-1,#conversejs .my-sm-1{margin-bottom:.25rem!important}#conversejs .ml-sm-1,#conversejs .mx-sm-1{margin-left:.25rem!important}#conversejs .m-sm-2{margin:.5rem!important}#conversejs .mt-sm-2,#conversejs .my-sm-2{margin-top:.5rem!important}#conversejs .mr-sm-2,#conversejs .mx-sm-2{margin-right:.5rem!important}#conversejs .mb-sm-2,#conversejs .my-sm-2{margin-bottom:.5rem!important}#conversejs .ml-sm-2,#conversejs .mx-sm-2{margin-left:.5rem!important}#conversejs .m-sm-3{margin:1rem!important}#conversejs .mt-sm-3,#conversejs .my-sm-3{margin-top:1rem!important}#conversejs .mr-sm-3,#conversejs .mx-sm-3{margin-right:1rem!important}#conversejs .mb-sm-3,#conversejs .my-sm-3{margin-bottom:1rem!important}#conversejs .ml-sm-3,#conversejs .mx-sm-3{margin-left:1rem!important}#conversejs .m-sm-4{margin:1.5rem!important}#conversejs .mt-sm-4,#conversejs .my-sm-4{margin-top:1.5rem!important}#conversejs .mr-sm-4,#conversejs .mx-sm-4{margin-right:1.5rem!important}#conversejs .mb-sm-4,#conversejs .my-sm-4{margin-bottom:1.5rem!important}#conversejs .ml-sm-4,#conversejs .mx-sm-4{margin-left:1.5rem!important}#conversejs .m-sm-5{margin:3rem!important}#conversejs .mt-sm-5,#conversejs .my-sm-5{margin-top:3rem!important}#conversejs .mr-sm-5,#conversejs .mx-sm-5{margin-right:3rem!important}#conversejs .mb-sm-5,#conversejs .my-sm-5{margin-bottom:3rem!important}#conversejs .ml-sm-5,#conversejs .mx-sm-5{margin-left:3rem!important}#conversejs .p-sm-0{padding:0!important}#conversejs .pt-sm-0,#conversejs .py-sm-0{padding-top:0!important}#conversejs .pr-sm-0,#conversejs .px-sm-0{padding-right:0!important}#conversejs .pb-sm-0,#conversejs .py-sm-0{padding-bottom:0!important}#conversejs .pl-sm-0,#conversejs .px-sm-0{padding-left:0!important}#conversejs .p-sm-1{padding:.25rem!important}#conversejs .pt-sm-1,#conversejs .py-sm-1{padding-top:.25rem!important}#conversejs .pr-sm-1,#conversejs .px-sm-1{padding-right:.25rem!important}#conversejs .pb-sm-1,#conversejs .py-sm-1{padding-bottom:.25rem!important}#conversejs .pl-sm-1,#conversejs .px-sm-1{padding-left:.25rem!important}#conversejs .p-sm-2{padding:.5rem!important}#conversejs .pt-sm-2,#conversejs .py-sm-2{padding-top:.5rem!important}#conversejs .pr-sm-2,#conversejs .px-sm-2{padding-right:.5rem!important}#conversejs .pb-sm-2,#conversejs .py-sm-2{padding-bottom:.5rem!important}#conversejs .pl-sm-2,#conversejs .px-sm-2{padding-left:.5rem!important}#conversejs .p-sm-3{padding:1rem!important}#conversejs .pt-sm-3,#conversejs .py-sm-3{padding-top:1rem!important}#conversejs .pr-sm-3,#conversejs .px-sm-3{padding-right:1rem!important}#conversejs .pb-sm-3,#conversejs .py-sm-3{padding-bottom:1rem!important}#conversejs .pl-sm-3,#conversejs .px-sm-3{padding-left:1rem!important}#conversejs .p-sm-4{padding:1.5rem!important}#conversejs .pt-sm-4,#conversejs .py-sm-4{padding-top:1.5rem!important}#conversejs .pr-sm-4,#conversejs .px-sm-4{padding-right:1.5rem!important}#conversejs .pb-sm-4,#conversejs .py-sm-4{padding-bottom:1.5rem!important}#conversejs .pl-sm-4,#conversejs .px-sm-4{padding-left:1.5rem!important}#conversejs .p-sm-5{padding:3rem!important}#conversejs .pt-sm-5,#conversejs .py-sm-5{padding-top:3rem!important}#conversejs .pr-sm-5,#conversejs .px-sm-5{padding-right:3rem!important}#conversejs .pb-sm-5,#conversejs .py-sm-5{padding-bottom:3rem!important}#conversejs .pl-sm-5,#conversejs .px-sm-5{padding-left:3rem!important}#conversejs .m-sm-n1{margin:-.25rem!important}#conversejs .mt-sm-n1,#conversejs .my-sm-n1{margin-top:-.25rem!important}#conversejs .mr-sm-n1,#conversejs .mx-sm-n1{margin-right:-.25rem!important}#conversejs .mb-sm-n1,#conversejs .my-sm-n1{margin-bottom:-.25rem!important}#conversejs .ml-sm-n1,#conversejs .mx-sm-n1{margin-left:-.25rem!important}#conversejs .m-sm-n2{margin:-.5rem!important}#conversejs .mt-sm-n2,#conversejs .my-sm-n2{margin-top:-.5rem!important}#conversejs .mr-sm-n2,#conversejs .mx-sm-n2{margin-right:-.5rem!important}#conversejs .mb-sm-n2,#conversejs .my-sm-n2{margin-bottom:-.5rem!important}#conversejs .ml-sm-n2,#conversejs .mx-sm-n2{margin-left:-.5rem!important}#conversejs .m-sm-n3{margin:-1rem!important}#conversejs .mt-sm-n3,#conversejs .my-sm-n3{margin-top:-1rem!important}#conversejs .mr-sm-n3,#conversejs .mx-sm-n3{margin-right:-1rem!important}#conversejs .mb-sm-n3,#conversejs .my-sm-n3{margin-bottom:-1rem!important}#conversejs .ml-sm-n3,#conversejs .mx-sm-n3{margin-left:-1rem!important}#conversejs .m-sm-n4{margin:-1.5rem!important}#conversejs .mt-sm-n4,#conversejs .my-sm-n4{margin-top:-1.5rem!important}#conversejs .mr-sm-n4,#conversejs .mx-sm-n4{margin-right:-1.5rem!important}#conversejs .mb-sm-n4,#conversejs .my-sm-n4{margin-bottom:-1.5rem!important}#conversejs .ml-sm-n4,#conversejs .mx-sm-n4{margin-left:-1.5rem!important}#conversejs .m-sm-n5{margin:-3rem!important}#conversejs .mt-sm-n5,#conversejs .my-sm-n5{margin-top:-3rem!important}#conversejs .mr-sm-n5,#conversejs .mx-sm-n5{margin-right:-3rem!important}#conversejs .mb-sm-n5,#conversejs .my-sm-n5{margin-bottom:-3rem!important}#conversejs .ml-sm-n5,#conversejs .mx-sm-n5{margin-left:-3rem!important}#conversejs .m-sm-auto{margin:auto!important}#conversejs .mt-sm-auto,#conversejs .my-sm-auto{margin-top:auto!important}#conversejs .mr-sm-auto,#conversejs .mx-sm-auto{margin-right:auto!important}#conversejs .mb-sm-auto,#conversejs .my-sm-auto{margin-bottom:auto!important}#conversejs .ml-sm-auto,#conversejs .mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){#conversejs .m-md-0{margin:0!important}#conversejs .mt-md-0,#conversejs .my-md-0{margin-top:0!important}#conversejs .mr-md-0,#conversejs .mx-md-0{margin-right:0!important}#conversejs .mb-md-0,#conversejs .my-md-0{margin-bottom:0!important}#conversejs .ml-md-0,#conversejs .mx-md-0{margin-left:0!important}#conversejs .m-md-1{margin:.25rem!important}#conversejs .mt-md-1,#conversejs .my-md-1{margin-top:.25rem!important}#conversejs .mr-md-1,#conversejs .mx-md-1{margin-right:.25rem!important}#conversejs .mb-md-1,#conversejs .my-md-1{margin-bottom:.25rem!important}#conversejs .ml-md-1,#conversejs .mx-md-1{margin-left:.25rem!important}#conversejs .m-md-2{margin:.5rem!important}#conversejs .mt-md-2,#conversejs .my-md-2{margin-top:.5rem!important}#conversejs .mr-md-2,#conversejs .mx-md-2{margin-right:.5rem!important}#conversejs .mb-md-2,#conversejs .my-md-2{margin-bottom:.5rem!important}#conversejs .ml-md-2,#conversejs .mx-md-2{margin-left:.5rem!important}#conversejs .m-md-3{margin:1rem!important}#conversejs .mt-md-3,#conversejs .my-md-3{margin-top:1rem!important}#conversejs .mr-md-3,#conversejs .mx-md-3{margin-right:1rem!important}#conversejs .mb-md-3,#conversejs .my-md-3{margin-bottom:1rem!important}#conversejs .ml-md-3,#conversejs .mx-md-3{margin-left:1rem!important}#conversejs .m-md-4{margin:1.5rem!important}#conversejs .mt-md-4,#conversejs .my-md-4{margin-top:1.5rem!important}#conversejs .mr-md-4,#conversejs .mx-md-4{margin-right:1.5rem!important}#conversejs .mb-md-4,#conversejs .my-md-4{margin-bottom:1.5rem!important}#conversejs .ml-md-4,#conversejs .mx-md-4{margin-left:1.5rem!important}#conversejs .m-md-5{margin:3rem!important}#conversejs .mt-md-5,#conversejs .my-md-5{margin-top:3rem!important}#conversejs .mr-md-5,#conversejs .mx-md-5{margin-right:3rem!important}#conversejs .mb-md-5,#conversejs .my-md-5{margin-bottom:3rem!important}#conversejs .ml-md-5,#conversejs .mx-md-5{margin-left:3rem!important}#conversejs .p-md-0{padding:0!important}#conversejs .pt-md-0,#conversejs .py-md-0{padding-top:0!important}#conversejs .pr-md-0,#conversejs .px-md-0{padding-right:0!important}#conversejs .pb-md-0,#conversejs .py-md-0{padding-bottom:0!important}#conversejs .pl-md-0,#conversejs .px-md-0{padding-left:0!important}#conversejs .p-md-1{padding:.25rem!important}#conversejs .pt-md-1,#conversejs .py-md-1{padding-top:.25rem!important}#conversejs .pr-md-1,#conversejs .px-md-1{padding-right:.25rem!important}#conversejs .pb-md-1,#conversejs .py-md-1{padding-bottom:.25rem!important}#conversejs .pl-md-1,#conversejs .px-md-1{padding-left:.25rem!important}#conversejs .p-md-2{padding:.5rem!important}#conversejs .pt-md-2,#conversejs .py-md-2{padding-top:.5rem!important}#conversejs .pr-md-2,#conversejs .px-md-2{padding-right:.5rem!important}#conversejs .pb-md-2,#conversejs .py-md-2{padding-bottom:.5rem!important}#conversejs .pl-md-2,#conversejs .px-md-2{padding-left:.5rem!important}#conversejs .p-md-3{padding:1rem!important}#conversejs .pt-md-3,#conversejs .py-md-3{padding-top:1rem!important}#conversejs .pr-md-3,#conversejs .px-md-3{padding-right:1rem!important}#conversejs .pb-md-3,#conversejs .py-md-3{padding-bottom:1rem!important}#conversejs .pl-md-3,#conversejs .px-md-3{padding-left:1rem!important}#conversejs .p-md-4{padding:1.5rem!important}#conversejs .pt-md-4,#conversejs .py-md-4{padding-top:1.5rem!important}#conversejs .pr-md-4,#conversejs .px-md-4{padding-right:1.5rem!important}#conversejs .pb-md-4,#conversejs .py-md-4{padding-bottom:1.5rem!important}#conversejs .pl-md-4,#conversejs .px-md-4{padding-left:1.5rem!important}#conversejs .p-md-5{padding:3rem!important}#conversejs .pt-md-5,#conversejs .py-md-5{padding-top:3rem!important}#conversejs .pr-md-5,#conversejs .px-md-5{padding-right:3rem!important}#conversejs .pb-md-5,#conversejs .py-md-5{padding-bottom:3rem!important}#conversejs .pl-md-5,#conversejs .px-md-5{padding-left:3rem!important}#conversejs .m-md-n1{margin:-.25rem!important}#conversejs .mt-md-n1,#conversejs .my-md-n1{margin-top:-.25rem!important}#conversejs .mr-md-n1,#conversejs .mx-md-n1{margin-right:-.25rem!important}#conversejs .mb-md-n1,#conversejs .my-md-n1{margin-bottom:-.25rem!important}#conversejs .ml-md-n1,#conversejs .mx-md-n1{margin-left:-.25rem!important}#conversejs .m-md-n2{margin:-.5rem!important}#conversejs .mt-md-n2,#conversejs .my-md-n2{margin-top:-.5rem!important}#conversejs .mr-md-n2,#conversejs .mx-md-n2{margin-right:-.5rem!important}#conversejs .mb-md-n2,#conversejs .my-md-n2{margin-bottom:-.5rem!important}#conversejs .ml-md-n2,#conversejs .mx-md-n2{margin-left:-.5rem!important}#conversejs .m-md-n3{margin:-1rem!important}#conversejs .mt-md-n3,#conversejs .my-md-n3{margin-top:-1rem!important}#conversejs .mr-md-n3,#conversejs .mx-md-n3{margin-right:-1rem!important}#conversejs .mb-md-n3,#conversejs .my-md-n3{margin-bottom:-1rem!important}#conversejs .ml-md-n3,#conversejs .mx-md-n3{margin-left:-1rem!important}#conversejs .m-md-n4{margin:-1.5rem!important}#conversejs .mt-md-n4,#conversejs .my-md-n4{margin-top:-1.5rem!important}#conversejs .mr-md-n4,#conversejs .mx-md-n4{margin-right:-1.5rem!important}#conversejs .mb-md-n4,#conversejs .my-md-n4{margin-bottom:-1.5rem!important}#conversejs .ml-md-n4,#conversejs .mx-md-n4{margin-left:-1.5rem!important}#conversejs .m-md-n5{margin:-3rem!important}#conversejs .mt-md-n5,#conversejs .my-md-n5{margin-top:-3rem!important}#conversejs .mr-md-n5,#conversejs .mx-md-n5{margin-right:-3rem!important}#conversejs .mb-md-n5,#conversejs .my-md-n5{margin-bottom:-3rem!important}#conversejs .ml-md-n5,#conversejs .mx-md-n5{margin-left:-3rem!important}#conversejs .m-md-auto{margin:auto!important}#conversejs .mt-md-auto,#conversejs .my-md-auto{margin-top:auto!important}#conversejs .mr-md-auto,#conversejs .mx-md-auto{margin-right:auto!important}#conversejs .mb-md-auto,#conversejs .my-md-auto{margin-bottom:auto!important}#conversejs .ml-md-auto,#conversejs .mx-md-auto{margin-left:auto!important}}@media (min-width:992px){#conversejs .m-lg-0{margin:0!important}#conversejs .mt-lg-0,#conversejs .my-lg-0{margin-top:0!important}#conversejs .mr-lg-0,#conversejs .mx-lg-0{margin-right:0!important}#conversejs .mb-lg-0,#conversejs .my-lg-0{margin-bottom:0!important}#conversejs .ml-lg-0,#conversejs .mx-lg-0{margin-left:0!important}#conversejs .m-lg-1{margin:.25rem!important}#conversejs .mt-lg-1,#conversejs .my-lg-1{margin-top:.25rem!important}#conversejs .mr-lg-1,#conversejs .mx-lg-1{margin-right:.25rem!important}#conversejs .mb-lg-1,#conversejs .my-lg-1{margin-bottom:.25rem!important}#conversejs .ml-lg-1,#conversejs .mx-lg-1{margin-left:.25rem!important}#conversejs .m-lg-2{margin:.5rem!important}#conversejs .mt-lg-2,#conversejs .my-lg-2{margin-top:.5rem!important}#conversejs .mr-lg-2,#conversejs .mx-lg-2{margin-right:.5rem!important}#conversejs .mb-lg-2,#conversejs .my-lg-2{margin-bottom:.5rem!important}#conversejs .ml-lg-2,#conversejs .mx-lg-2{margin-left:.5rem!important}#conversejs .m-lg-3{margin:1rem!important}#conversejs .mt-lg-3,#conversejs .my-lg-3{margin-top:1rem!important}#conversejs .mr-lg-3,#conversejs .mx-lg-3{margin-right:1rem!important}#conversejs .mb-lg-3,#conversejs .my-lg-3{margin-bottom:1rem!important}#conversejs .ml-lg-3,#conversejs .mx-lg-3{margin-left:1rem!important}#conversejs .m-lg-4{margin:1.5rem!important}#conversejs .mt-lg-4,#conversejs .my-lg-4{margin-top:1.5rem!important}#conversejs .mr-lg-4,#conversejs .mx-lg-4{margin-right:1.5rem!important}#conversejs .mb-lg-4,#conversejs .my-lg-4{margin-bottom:1.5rem!important}#conversejs .ml-lg-4,#conversejs .mx-lg-4{margin-left:1.5rem!important}#conversejs .m-lg-5{margin:3rem!important}#conversejs .mt-lg-5,#conversejs .my-lg-5{margin-top:3rem!important}#conversejs .mr-lg-5,#conversejs .mx-lg-5{margin-right:3rem!important}#conversejs .mb-lg-5,#conversejs .my-lg-5{margin-bottom:3rem!important}#conversejs .ml-lg-5,#conversejs .mx-lg-5{margin-left:3rem!important}#conversejs .p-lg-0{padding:0!important}#conversejs .pt-lg-0,#conversejs .py-lg-0{padding-top:0!important}#conversejs .pr-lg-0,#conversejs .px-lg-0{padding-right:0!important}#conversejs .pb-lg-0,#conversejs .py-lg-0{padding-bottom:0!important}#conversejs .pl-lg-0,#conversejs .px-lg-0{padding-left:0!important}#conversejs .p-lg-1{padding:.25rem!important}#conversejs .pt-lg-1,#conversejs .py-lg-1{padding-top:.25rem!important}#conversejs .pr-lg-1,#conversejs .px-lg-1{padding-right:.25rem!important}#conversejs .pb-lg-1,#conversejs .py-lg-1{padding-bottom:.25rem!important}#conversejs .pl-lg-1,#conversejs .px-lg-1{padding-left:.25rem!important}#conversejs .p-lg-2{padding:.5rem!important}#conversejs .pt-lg-2,#conversejs .py-lg-2{padding-top:.5rem!important}#conversejs .pr-lg-2,#conversejs .px-lg-2{padding-right:.5rem!important}#conversejs .pb-lg-2,#conversejs .py-lg-2{padding-bottom:.5rem!important}#conversejs .pl-lg-2,#conversejs .px-lg-2{padding-left:.5rem!important}#conversejs .p-lg-3{padding:1rem!important}#conversejs .pt-lg-3,#conversejs .py-lg-3{padding-top:1rem!important}#conversejs .pr-lg-3,#conversejs .px-lg-3{padding-right:1rem!important}#conversejs .pb-lg-3,#conversejs .py-lg-3{padding-bottom:1rem!important}#conversejs .pl-lg-3,#conversejs .px-lg-3{padding-left:1rem!important}#conversejs .p-lg-4{padding:1.5rem!important}#conversejs .pt-lg-4,#conversejs .py-lg-4{padding-top:1.5rem!important}#conversejs .pr-lg-4,#conversejs .px-lg-4{padding-right:1.5rem!important}#conversejs .pb-lg-4,#conversejs .py-lg-4{padding-bottom:1.5rem!important}#conversejs .pl-lg-4,#conversejs .px-lg-4{padding-left:1.5rem!important}#conversejs .p-lg-5{padding:3rem!important}#conversejs .pt-lg-5,#conversejs .py-lg-5{padding-top:3rem!important}#conversejs .pr-lg-5,#conversejs .px-lg-5{padding-right:3rem!important}#conversejs .pb-lg-5,#conversejs .py-lg-5{padding-bottom:3rem!important}#conversejs .pl-lg-5,#conversejs .px-lg-5{padding-left:3rem!important}#conversejs .m-lg-n1{margin:-.25rem!important}#conversejs .mt-lg-n1,#conversejs .my-lg-n1{margin-top:-.25rem!important}#conversejs .mr-lg-n1,#conversejs .mx-lg-n1{margin-right:-.25rem!important}#conversejs .mb-lg-n1,#conversejs .my-lg-n1{margin-bottom:-.25rem!important}#conversejs .ml-lg-n1,#conversejs .mx-lg-n1{margin-left:-.25rem!important}#conversejs .m-lg-n2{margin:-.5rem!important}#conversejs .mt-lg-n2,#conversejs .my-lg-n2{margin-top:-.5rem!important}#conversejs .mr-lg-n2,#conversejs .mx-lg-n2{margin-right:-.5rem!important}#conversejs .mb-lg-n2,#conversejs .my-lg-n2{margin-bottom:-.5rem!important}#conversejs .ml-lg-n2,#conversejs .mx-lg-n2{margin-left:-.5rem!important}#conversejs .m-lg-n3{margin:-1rem!important}#conversejs .mt-lg-n3,#conversejs .my-lg-n3{margin-top:-1rem!important}#conversejs .mr-lg-n3,#conversejs .mx-lg-n3{margin-right:-1rem!important}#conversejs .mb-lg-n3,#conversejs .my-lg-n3{margin-bottom:-1rem!important}#conversejs .ml-lg-n3,#conversejs .mx-lg-n3{margin-left:-1rem!important}#conversejs .m-lg-n4{margin:-1.5rem!important}#conversejs .mt-lg-n4,#conversejs .my-lg-n4{margin-top:-1.5rem!important}#conversejs .mr-lg-n4,#conversejs .mx-lg-n4{margin-right:-1.5rem!important}#conversejs .mb-lg-n4,#conversejs .my-lg-n4{margin-bottom:-1.5rem!important}#conversejs .ml-lg-n4,#conversejs .mx-lg-n4{margin-left:-1.5rem!important}#conversejs .m-lg-n5{margin:-3rem!important}#conversejs .mt-lg-n5,#conversejs .my-lg-n5{margin-top:-3rem!important}#conversejs .mr-lg-n5,#conversejs .mx-lg-n5{margin-right:-3rem!important}#conversejs .mb-lg-n5,#conversejs .my-lg-n5{margin-bottom:-3rem!important}#conversejs .ml-lg-n5,#conversejs .mx-lg-n5{margin-left:-3rem!important}#conversejs .m-lg-auto{margin:auto!important}#conversejs .mt-lg-auto,#conversejs .my-lg-auto{margin-top:auto!important}#conversejs .mr-lg-auto,#conversejs .mx-lg-auto{margin-right:auto!important}#conversejs .mb-lg-auto,#conversejs .my-lg-auto{margin-bottom:auto!important}#conversejs .ml-lg-auto,#conversejs .mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){#conversejs .m-xl-0{margin:0!important}#conversejs .mt-xl-0,#conversejs .my-xl-0{margin-top:0!important}#conversejs .mr-xl-0,#conversejs .mx-xl-0{margin-right:0!important}#conversejs .mb-xl-0,#conversejs .my-xl-0{margin-bottom:0!important}#conversejs .ml-xl-0,#conversejs .mx-xl-0{margin-left:0!important}#conversejs .m-xl-1{margin:.25rem!important}#conversejs .mt-xl-1,#conversejs .my-xl-1{margin-top:.25rem!important}#conversejs .mr-xl-1,#conversejs .mx-xl-1{margin-right:.25rem!important}#conversejs .mb-xl-1,#conversejs .my-xl-1{margin-bottom:.25rem!important}#conversejs .ml-xl-1,#conversejs .mx-xl-1{margin-left:.25rem!important}#conversejs .m-xl-2{margin:.5rem!important}#conversejs .mt-xl-2,#conversejs .my-xl-2{margin-top:.5rem!important}#conversejs .mr-xl-2,#conversejs .mx-xl-2{margin-right:.5rem!important}#conversejs .mb-xl-2,#conversejs .my-xl-2{margin-bottom:.5rem!important}#conversejs .ml-xl-2,#conversejs .mx-xl-2{margin-left:.5rem!important}#conversejs .m-xl-3{margin:1rem!important}#conversejs .mt-xl-3,#conversejs .my-xl-3{margin-top:1rem!important}#conversejs .mr-xl-3,#conversejs .mx-xl-3{margin-right:1rem!important}#conversejs .mb-xl-3,#conversejs .my-xl-3{margin-bottom:1rem!important}#conversejs .ml-xl-3,#conversejs .mx-xl-3{margin-left:1rem!important}#conversejs .m-xl-4{margin:1.5rem!important}#conversejs .mt-xl-4,#conversejs .my-xl-4{margin-top:1.5rem!important}#conversejs .mr-xl-4,#conversejs .mx-xl-4{margin-right:1.5rem!important}#conversejs .mb-xl-4,#conversejs .my-xl-4{margin-bottom:1.5rem!important}#conversejs .ml-xl-4,#conversejs .mx-xl-4{margin-left:1.5rem!important}#conversejs .m-xl-5{margin:3rem!important}#conversejs .mt-xl-5,#conversejs .my-xl-5{margin-top:3rem!important}#conversejs .mr-xl-5,#conversejs .mx-xl-5{margin-right:3rem!important}#conversejs .mb-xl-5,#conversejs .my-xl-5{margin-bottom:3rem!important}#conversejs .ml-xl-5,#conversejs .mx-xl-5{margin-left:3rem!important}#conversejs .p-xl-0{padding:0!important}#conversejs .pt-xl-0,#conversejs .py-xl-0{padding-top:0!important}#conversejs .pr-xl-0,#conversejs .px-xl-0{padding-right:0!important}#conversejs .pb-xl-0,#conversejs .py-xl-0{padding-bottom:0!important}#conversejs .pl-xl-0,#conversejs .px-xl-0{padding-left:0!important}#conversejs .p-xl-1{padding:.25rem!important}#conversejs .pt-xl-1,#conversejs .py-xl-1{padding-top:.25rem!important}#conversejs .pr-xl-1,#conversejs .px-xl-1{padding-right:.25rem!important}#conversejs .pb-xl-1,#conversejs .py-xl-1{padding-bottom:.25rem!important}#conversejs .pl-xl-1,#conversejs .px-xl-1{padding-left:.25rem!important}#conversejs .p-xl-2{padding:.5rem!important}#conversejs .pt-xl-2,#conversejs .py-xl-2{padding-top:.5rem!important}#conversejs .pr-xl-2,#conversejs .px-xl-2{padding-right:.5rem!important}#conversejs .pb-xl-2,#conversejs .py-xl-2{padding-bottom:.5rem!important}#conversejs .pl-xl-2,#conversejs .px-xl-2{padding-left:.5rem!important}#conversejs .p-xl-3{padding:1rem!important}#conversejs .pt-xl-3,#conversejs .py-xl-3{padding-top:1rem!important}#conversejs .pr-xl-3,#conversejs .px-xl-3{padding-right:1rem!important}#conversejs .pb-xl-3,#conversejs .py-xl-3{padding-bottom:1rem!important}#conversejs .pl-xl-3,#conversejs .px-xl-3{padding-left:1rem!important}#conversejs .p-xl-4{padding:1.5rem!important}#conversejs .pt-xl-4,#conversejs .py-xl-4{padding-top:1.5rem!important}#conversejs .pr-xl-4,#conversejs .px-xl-4{padding-right:1.5rem!important}#conversejs .pb-xl-4,#conversejs .py-xl-4{padding-bottom:1.5rem!important}#conversejs .pl-xl-4,#conversejs .px-xl-4{padding-left:1.5rem!important}#conversejs .p-xl-5{padding:3rem!important}#conversejs .pt-xl-5,#conversejs .py-xl-5{padding-top:3rem!important}#conversejs .pr-xl-5,#conversejs .px-xl-5{padding-right:3rem!important}#conversejs .pb-xl-5,#conversejs .py-xl-5{padding-bottom:3rem!important}#conversejs .pl-xl-5,#conversejs .px-xl-5{padding-left:3rem!important}#conversejs .m-xl-n1{margin:-.25rem!important}#conversejs .mt-xl-n1,#conversejs .my-xl-n1{margin-top:-.25rem!important}#conversejs .mr-xl-n1,#conversejs .mx-xl-n1{margin-right:-.25rem!important}#conversejs .mb-xl-n1,#conversejs .my-xl-n1{margin-bottom:-.25rem!important}#conversejs .ml-xl-n1,#conversejs .mx-xl-n1{margin-left:-.25rem!important}#conversejs .m-xl-n2{margin:-.5rem!important}#conversejs .mt-xl-n2,#conversejs .my-xl-n2{margin-top:-.5rem!important}#conversejs .mr-xl-n2,#conversejs .mx-xl-n2{margin-right:-.5rem!important}#conversejs .mb-xl-n2,#conversejs .my-xl-n2{margin-bottom:-.5rem!important}#conversejs .ml-xl-n2,#conversejs .mx-xl-n2{margin-left:-.5rem!important}#conversejs .m-xl-n3{margin:-1rem!important}#conversejs .mt-xl-n3,#conversejs .my-xl-n3{margin-top:-1rem!important}#conversejs .mr-xl-n3,#conversejs .mx-xl-n3{margin-right:-1rem!important}#conversejs .mb-xl-n3,#conversejs .my-xl-n3{margin-bottom:-1rem!important}#conversejs .ml-xl-n3,#conversejs .mx-xl-n3{margin-left:-1rem!important}#conversejs .m-xl-n4{margin:-1.5rem!important}#conversejs .mt-xl-n4,#conversejs .my-xl-n4{margin-top:-1.5rem!important}#conversejs .mr-xl-n4,#conversejs .mx-xl-n4{margin-right:-1.5rem!important}#conversejs .mb-xl-n4,#conversejs .my-xl-n4{margin-bottom:-1.5rem!important}#conversejs .ml-xl-n4,#conversejs .mx-xl-n4{margin-left:-1.5rem!important}#conversejs .m-xl-n5{margin:-3rem!important}#conversejs .mt-xl-n5,#conversejs .my-xl-n5{margin-top:-3rem!important}#conversejs .mr-xl-n5,#conversejs .mx-xl-n5{margin-right:-3rem!important}#conversejs .mb-xl-n5,#conversejs .my-xl-n5{margin-bottom:-3rem!important}#conversejs .ml-xl-n5,#conversejs .mx-xl-n5{margin-left:-3rem!important}#conversejs .m-xl-auto{margin:auto!important}#conversejs .mt-xl-auto,#conversejs .my-xl-auto{margin-top:auto!important}#conversejs .mr-xl-auto,#conversejs .mx-xl-auto{margin-right:auto!important}#conversejs .mb-xl-auto,#conversejs .my-xl-auto{margin-bottom:auto!important}#conversejs .ml-xl-auto,#conversejs .mx-xl-auto{margin-left:auto!important}}#conversejs .text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace!important}#conversejs .text-justify{text-align:justify!important}#conversejs .text-wrap{white-space:normal!important}#conversejs .text-nowrap{white-space:nowrap!important}#conversejs .text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs .text-left{text-align:left!important}#conversejs .text-right{text-align:right!important}#conversejs .text-center{text-align:center!important}@media (min-width:576px){#conversejs .text-sm-left{text-align:left!important}#conversejs .text-sm-right{text-align:right!important}#conversejs .text-sm-center{text-align:center!important}}@media (min-width:768px){#conversejs .text-md-left{text-align:left!important}#conversejs .text-md-right{text-align:right!important}#conversejs .text-md-center{text-align:center!important}}@media (min-width:992px){#conversejs .text-lg-left{text-align:left!important}#conversejs .text-lg-right{text-align:right!important}#conversejs .text-lg-center{text-align:center!important}}@media (min-width:1200px){#conversejs .text-xl-left{text-align:left!important}#conversejs .text-xl-right{text-align:right!important}#conversejs .text-xl-center{text-align:center!important}}#conversejs .text-lowercase{text-transform:lowercase!important}#conversejs .text-uppercase{text-transform:uppercase!important}#conversejs .text-capitalize{text-transform:capitalize!important}#conversejs .font-weight-light{font-weight:300!important}#conversejs .font-weight-lighter{font-weight:lighter!important}#conversejs .font-weight-normal{font-weight:400!important}#conversejs .font-weight-bold{font-weight:700!important}#conversejs .font-weight-bolder{font-weight:bolder!important}#conversejs .font-italic{font-style:italic!important}#conversejs .text-white{color:#fff!important}#conversejs .text-primary{color:#007bff!important}#conversejs a.text-primary:focus,#conversejs a.text-primary:hover{color:#0056b3!important}#conversejs .text-secondary{color:#6c757d!important}#conversejs a.text-secondary:focus,#conversejs a.text-secondary:hover{color:#494f54!important}#conversejs .text-success{color:#28a745!important}#conversejs a.text-success:focus,#conversejs a.text-success:hover{color:#19692c!important}#conversejs .text-info{color:#17a2b8!important}#conversejs a.text-info:focus,#conversejs a.text-info:hover{color:#0f6674!important}#conversejs .text-warning{color:#ffc107!important}#conversejs a.text-warning:focus,#conversejs a.text-warning:hover{color:#ba8b00!important}#conversejs .text-danger{color:#dc3545!important}#conversejs a.text-danger:focus,#conversejs a.text-danger:hover{color:#a71d2a!important}#conversejs .text-light{color:#f8f9fa!important}#conversejs a.text-light:focus,#conversejs a.text-light:hover{color:#cbd3da!important}#conversejs .text-dark{color:#343a40!important}#conversejs a.text-dark:focus,#conversejs a.text-dark:hover{color:#121416!important}#conversejs .text-body{color:#212529!important}#conversejs .text-muted{color:#6c757d!important}#conversejs .text-black-50{color:rgba(0,0,0,.5)!important}#conversejs .text-white-50{color:rgba(255,255,255,.5)!important}#conversejs .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}#conversejs .text-decoration-none{text-decoration:none!important}#conversejs .text-break{word-break:break-word!important;overflow-wrap:break-word!important}#conversejs .text-reset{color:inherit!important}#conversejs .visible{visibility:visible!important}#conversejs .invisible{visibility:hidden!important}@font-face{font-family:Baumans;font-style:normal;font-weight:400;src:local(\"Baumans Regular\"),local(\"Baumans-Regular\"),url(webfonts/baumans.ttf) format(\"truetype\")}@font-face{font-family:Muli;font-style:normal;font-weight:400;src:local(\"Muli Regular\"),local(\"Muli-Regular\"),url(webfonts/muli.ttf) format(\"truetype\")}@font-face{font-family:ConverseFontAwesomeBrands;font-style:normal;font-weight:400;src:url(webfonts/fa-brands-400.eot);src:url(webfonts/fa-brands-400.eot?#iefix) format(\"embedded-opentype\"),url(webfonts/fa-brands-400.woff2) format(\"woff2\"),url(webfonts/fa-brands-400.woff) format(\"woff\"),url(webfonts/fa-brands-400.ttf) format(\"truetype\"),url(webfonts/fa-brands-400.svg#fontawesome) format(\"svg\")}@font-face{font-family:ConverseFontAwesomeRegular;font-style:normal;font-weight:400;src:url(webfonts/fa-regular-400.eot);src:url(webfonts/fa-regular-400.eot?#iefix) format(\"embedded-opentype\"),url(webfonts/fa-regular-400.woff2) format(\"woff2\"),url(webfonts/fa-regular-400.woff) format(\"woff\"),url(webfonts/fa-regular-400.ttf) format(\"truetype\"),url(webfonts/fa-regular-400.svg#fontawesome) format(\"svg\");font-weight:400;font-style:normal}@font-face{font-family:ConverseFontAwesomeSolid;font-style:normal;font-weight:900;src:url(webfonts/fa-solid-900.eot);src:url(webfonts/fa-solid-900.eot?#iefix) format(\"embedded-opentype\"),url(webfonts/fa-solid-900.svg#fontawesome) format(\"svg\"),url(webfonts/fa-solid-900.woff2) format(\"woff2\"),url(webfonts/fa-solid-900.woff) format(\"woff\"),url(webfonts/fa-solid-900.ttf) format(\"truetype\")}.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scale(-1,1)}.fa-flip-vertical{transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:\"\\f26e\"}.fa-accessible-icon:before{content:\"\\f368\"}.fa-accusoft:before{content:\"\\f369\"}.fa-acquisitions-incorporated:before{content:\"\\f6af\"}.fa-ad:before{content:\"\\f641\"}.fa-address-book:before{content:\"\\f2b9\"}.fa-address-card:before{content:\"\\f2bb\"}.fa-adjust:before{content:\"\\f042\"}.fa-adn:before{content:\"\\f170\"}.fa-adobe:before{content:\"\\f778\"}.fa-adversal:before{content:\"\\f36a\"}.fa-affiliatetheme:before{content:\"\\f36b\"}.fa-air-freshener:before{content:\"\\f5d0\"}.fa-airbnb:before{content:\"\\f834\"}.fa-algolia:before{content:\"\\f36c\"}.fa-align-center:before{content:\"\\f037\"}.fa-align-justify:before{content:\"\\f039\"}.fa-align-left:before{content:\"\\f036\"}.fa-align-right:before{content:\"\\f038\"}.fa-alipay:before{content:\"\\f642\"}.fa-allergies:before{content:\"\\f461\"}.fa-amazon:before{content:\"\\f270\"}.fa-amazon-pay:before{content:\"\\f42c\"}.fa-ambulance:before{content:\"\\f0f9\"}.fa-american-sign-language-interpreting:before{content:\"\\f2a3\"}.fa-amilia:before{content:\"\\f36d\"}.fa-anchor:before{content:\"\\f13d\"}.fa-android:before{content:\"\\f17b\"}.fa-angellist:before{content:\"\\f209\"}.fa-angle-double-down:before{content:\"\\f103\"}.fa-angle-double-left:before{content:\"\\f100\"}.fa-angle-double-right:before{content:\"\\f101\"}.fa-angle-double-up:before{content:\"\\f102\"}.fa-angle-down:before{content:\"\\f107\"}.fa-angle-left:before{content:\"\\f104\"}.fa-angle-right:before{content:\"\\f105\"}.fa-angle-up:before{content:\"\\f106\"}.fa-angry:before{content:\"\\f556\"}.fa-angrycreative:before{content:\"\\f36e\"}.fa-angular:before{content:\"\\f420\"}.fa-ankh:before{content:\"\\f644\"}.fa-app-store:before{content:\"\\f36f\"}.fa-app-store-ios:before{content:\"\\f370\"}.fa-apper:before{content:\"\\f371\"}.fa-apple:before{content:\"\\f179\"}.fa-apple-alt:before{content:\"\\f5d1\"}.fa-apple-pay:before{content:\"\\f415\"}.fa-archive:before{content:\"\\f187\"}.fa-archway:before{content:\"\\f557\"}.fa-arrow-alt-circle-down:before{content:\"\\f358\"}.fa-arrow-alt-circle-left:before{content:\"\\f359\"}.fa-arrow-alt-circle-right:before{content:\"\\f35a\"}.fa-arrow-alt-circle-up:before{content:\"\\f35b\"}.fa-arrow-circle-down:before{content:\"\\f0ab\"}.fa-arrow-circle-left:before{content:\"\\f0a8\"}.fa-arrow-circle-right:before{content:\"\\f0a9\"}.fa-arrow-circle-up:before{content:\"\\f0aa\"}.fa-arrow-down:before{content:\"\\f063\"}.fa-arrow-left:before{content:\"\\f060\"}.fa-arrow-right:before{content:\"\\f061\"}.fa-arrow-up:before{content:\"\\f062\"}.fa-arrows-alt:before{content:\"\\f0b2\"}.fa-arrows-alt-h:before{content:\"\\f337\"}.fa-arrows-alt-v:before{content:\"\\f338\"}.fa-artstation:before{content:\"\\f77a\"}.fa-assistive-listening-systems:before{content:\"\\f2a2\"}.fa-asterisk:before{content:\"\\f069\"}.fa-asymmetrik:before{content:\"\\f372\"}.fa-at:before{content:\"\\f1fa\"}.fa-atlas:before{content:\"\\f558\"}.fa-atlassian:before{content:\"\\f77b\"}.fa-atom:before{content:\"\\f5d2\"}.fa-audible:before{content:\"\\f373\"}.fa-audio-description:before{content:\"\\f29e\"}.fa-autoprefixer:before{content:\"\\f41c\"}.fa-avianex:before{content:\"\\f374\"}.fa-aviato:before{content:\"\\f421\"}.fa-award:before{content:\"\\f559\"}.fa-aws:before{content:\"\\f375\"}.fa-baby:before{content:\"\\f77c\"}.fa-baby-carriage:before{content:\"\\f77d\"}.fa-backspace:before{content:\"\\f55a\"}.fa-backward:before{content:\"\\f04a\"}.fa-bacon:before{content:\"\\f7e5\"}.fa-bacteria:before{content:\"\\e059\"}.fa-bacterium:before{content:\"\\e05a\"}.fa-bahai:before{content:\"\\f666\"}.fa-balance-scale:before{content:\"\\f24e\"}.fa-balance-scale-left:before{content:\"\\f515\"}.fa-balance-scale-right:before{content:\"\\f516\"}.fa-ban:before{content:\"\\f05e\"}.fa-band-aid:before{content:\"\\f462\"}.fa-bandcamp:before{content:\"\\f2d5\"}.fa-barcode:before{content:\"\\f02a\"}.fa-bars:before{content:\"\\f0c9\"}.fa-baseball-ball:before{content:\"\\f433\"}.fa-basketball-ball:before{content:\"\\f434\"}.fa-bath:before{content:\"\\f2cd\"}.fa-battery-empty:before{content:\"\\f244\"}.fa-battery-full:before{content:\"\\f240\"}.fa-battery-half:before{content:\"\\f242\"}.fa-battery-quarter:before{content:\"\\f243\"}.fa-battery-three-quarters:before{content:\"\\f241\"}.fa-battle-net:before{content:\"\\f835\"}.fa-bed:before{content:\"\\f236\"}.fa-beer:before{content:\"\\f0fc\"}.fa-behance:before{content:\"\\f1b4\"}.fa-behance-square:before{content:\"\\f1b5\"}.fa-bell:before{content:\"\\f0f3\"}.fa-bell-slash:before{content:\"\\f1f6\"}.fa-bezier-curve:before{content:\"\\f55b\"}.fa-bible:before{content:\"\\f647\"}.fa-bicycle:before{content:\"\\f206\"}.fa-biking:before{content:\"\\f84a\"}.fa-bimobject:before{content:\"\\f378\"}.fa-binoculars:before{content:\"\\f1e5\"}.fa-biohazard:before{content:\"\\f780\"}.fa-birthday-cake:before{content:\"\\f1fd\"}.fa-bitbucket:before{content:\"\\f171\"}.fa-bitcoin:before{content:\"\\f379\"}.fa-bity:before{content:\"\\f37a\"}.fa-black-tie:before{content:\"\\f27e\"}.fa-blackberry:before{content:\"\\f37b\"}.fa-blender:before{content:\"\\f517\"}.fa-blender-phone:before{content:\"\\f6b6\"}.fa-blind:before{content:\"\\f29d\"}.fa-blog:before{content:\"\\f781\"}.fa-blogger:before{content:\"\\f37c\"}.fa-blogger-b:before{content:\"\\f37d\"}.fa-bluetooth:before{content:\"\\f293\"}.fa-bluetooth-b:before{content:\"\\f294\"}.fa-bold:before{content:\"\\f032\"}.fa-bolt:before{content:\"\\f0e7\"}.fa-bomb:before{content:\"\\f1e2\"}.fa-bone:before{content:\"\\f5d7\"}.fa-bong:before{content:\"\\f55c\"}.fa-book:before{content:\"\\f02d\"}.fa-book-dead:before{content:\"\\f6b7\"}.fa-book-medical:before{content:\"\\f7e6\"}.fa-book-open:before{content:\"\\f518\"}.fa-book-reader:before{content:\"\\f5da\"}.fa-bookmark:before{content:\"\\f02e\"}.fa-bootstrap:before{content:\"\\f836\"}.fa-border-all:before{content:\"\\f84c\"}.fa-border-none:before{content:\"\\f850\"}.fa-border-style:before{content:\"\\f853\"}.fa-bowling-ball:before{content:\"\\f436\"}.fa-box:before{content:\"\\f466\"}.fa-box-open:before{content:\"\\f49e\"}.fa-box-tissue:before{content:\"\\e05b\"}.fa-boxes:before{content:\"\\f468\"}.fa-braille:before{content:\"\\f2a1\"}.fa-brain:before{content:\"\\f5dc\"}.fa-bread-slice:before{content:\"\\f7ec\"}.fa-briefcase:before{content:\"\\f0b1\"}.fa-briefcase-medical:before{content:\"\\f469\"}.fa-broadcast-tower:before{content:\"\\f519\"}.fa-broom:before{content:\"\\f51a\"}.fa-brush:before{content:\"\\f55d\"}.fa-btc:before{content:\"\\f15a\"}.fa-buffer:before{content:\"\\f837\"}.fa-bug:before{content:\"\\f188\"}.fa-building:before{content:\"\\f1ad\"}.fa-bullhorn:before{content:\"\\f0a1\"}.fa-bullseye:before{content:\"\\f140\"}.fa-burn:before{content:\"\\f46a\"}.fa-buromobelexperte:before{content:\"\\f37f\"}.fa-bus:before{content:\"\\f207\"}.fa-bus-alt:before{content:\"\\f55e\"}.fa-business-time:before{content:\"\\f64a\"}.fa-buy-n-large:before{content:\"\\f8a6\"}.fa-buysellads:before{content:\"\\f20d\"}.fa-calculator:before{content:\"\\f1ec\"}.fa-calendar:before{content:\"\\f133\"}.fa-calendar-alt:before{content:\"\\f073\"}.fa-calendar-check:before{content:\"\\f274\"}.fa-calendar-day:before{content:\"\\f783\"}.fa-calendar-minus:before{content:\"\\f272\"}.fa-calendar-plus:before{content:\"\\f271\"}.fa-calendar-times:before{content:\"\\f273\"}.fa-calendar-week:before{content:\"\\f784\"}.fa-camera:before{content:\"\\f030\"}.fa-camera-retro:before{content:\"\\f083\"}.fa-campground:before{content:\"\\f6bb\"}.fa-canadian-maple-leaf:before{content:\"\\f785\"}.fa-candy-cane:before{content:\"\\f786\"}.fa-cannabis:before{content:\"\\f55f\"}.fa-capsules:before{content:\"\\f46b\"}.fa-car:before{content:\"\\f1b9\"}.fa-car-alt:before{content:\"\\f5de\"}.fa-car-battery:before{content:\"\\f5df\"}.fa-car-crash:before{content:\"\\f5e1\"}.fa-car-side:before{content:\"\\f5e4\"}.fa-caravan:before{content:\"\\f8ff\"}.fa-caret-down:before{content:\"\\f0d7\"}.fa-caret-left:before{content:\"\\f0d9\"}.fa-caret-right:before{content:\"\\f0da\"}.fa-caret-square-down:before{content:\"\\f150\"}.fa-caret-square-left:before{content:\"\\f191\"}.fa-caret-square-right:before{content:\"\\f152\"}.fa-caret-square-up:before{content:\"\\f151\"}.fa-caret-up:before{content:\"\\f0d8\"}.fa-carrot:before{content:\"\\f787\"}.fa-cart-arrow-down:before{content:\"\\f218\"}.fa-cart-plus:before{content:\"\\f217\"}.fa-cash-register:before{content:\"\\f788\"}.fa-cat:before{content:\"\\f6be\"}.fa-cc-amazon-pay:before{content:\"\\f42d\"}.fa-cc-amex:before{content:\"\\f1f3\"}.fa-cc-apple-pay:before{content:\"\\f416\"}.fa-cc-diners-club:before{content:\"\\f24c\"}.fa-cc-discover:before{content:\"\\f1f2\"}.fa-cc-jcb:before{content:\"\\f24b\"}.fa-cc-mastercard:before{content:\"\\f1f1\"}.fa-cc-paypal:before{content:\"\\f1f4\"}.fa-cc-stripe:before{content:\"\\f1f5\"}.fa-cc-visa:before{content:\"\\f1f0\"}.fa-centercode:before{content:\"\\f380\"}.fa-centos:before{content:\"\\f789\"}.fa-certificate:before{content:\"\\f0a3\"}.fa-chair:before{content:\"\\f6c0\"}.fa-chalkboard:before{content:\"\\f51b\"}.fa-chalkboard-teacher:before{content:\"\\f51c\"}.fa-charging-station:before{content:\"\\f5e7\"}.fa-chart-area:before{content:\"\\f1fe\"}.fa-chart-bar:before{content:\"\\f080\"}.fa-chart-line:before{content:\"\\f201\"}.fa-chart-pie:before{content:\"\\f200\"}.fa-check:before{content:\"\\f00c\"}.fa-check-circle:before{content:\"\\f058\"}.fa-check-double:before{content:\"\\f560\"}.fa-check-square:before{content:\"\\f14a\"}.fa-cheese:before{content:\"\\f7ef\"}.fa-chess:before{content:\"\\f439\"}.fa-chess-bishop:before{content:\"\\f43a\"}.fa-chess-board:before{content:\"\\f43c\"}.fa-chess-king:before{content:\"\\f43f\"}.fa-chess-knight:before{content:\"\\f441\"}.fa-chess-pawn:before{content:\"\\f443\"}.fa-chess-queen:before{content:\"\\f445\"}.fa-chess-rook:before{content:\"\\f447\"}.fa-chevron-circle-down:before{content:\"\\f13a\"}.fa-chevron-circle-left:before{content:\"\\f137\"}.fa-chevron-circle-right:before{content:\"\\f138\"}.fa-chevron-circle-up:before{content:\"\\f139\"}.fa-chevron-down:before{content:\"\\f078\"}.fa-chevron-left:before{content:\"\\f053\"}.fa-chevron-right:before{content:\"\\f054\"}.fa-chevron-up:before{content:\"\\f077\"}.fa-child:before{content:\"\\f1ae\"}.fa-chrome:before{content:\"\\f268\"}.fa-chromecast:before{content:\"\\f838\"}.fa-church:before{content:\"\\f51d\"}.fa-circle:before{content:\"\\f111\"}.fa-circle-notch:before{content:\"\\f1ce\"}.fa-city:before{content:\"\\f64f\"}.fa-clinic-medical:before{content:\"\\f7f2\"}.fa-clipboard:before{content:\"\\f328\"}.fa-clipboard-check:before{content:\"\\f46c\"}.fa-clipboard-list:before{content:\"\\f46d\"}.fa-clock:before{content:\"\\f017\"}.fa-clone:before{content:\"\\f24d\"}.fa-closed-captioning:before{content:\"\\f20a\"}.fa-cloud:before{content:\"\\f0c2\"}.fa-cloud-download-alt:before{content:\"\\f381\"}.fa-cloud-meatball:before{content:\"\\f73b\"}.fa-cloud-moon:before{content:\"\\f6c3\"}.fa-cloud-moon-rain:before{content:\"\\f73c\"}.fa-cloud-rain:before{content:\"\\f73d\"}.fa-cloud-showers-heavy:before{content:\"\\f740\"}.fa-cloud-sun:before{content:\"\\f6c4\"}.fa-cloud-sun-rain:before{content:\"\\f743\"}.fa-cloud-upload-alt:before{content:\"\\f382\"}.fa-cloudscale:before{content:\"\\f383\"}.fa-cloudsmith:before{content:\"\\f384\"}.fa-cloudversify:before{content:\"\\f385\"}.fa-cocktail:before{content:\"\\f561\"}.fa-code:before{content:\"\\f121\"}.fa-code-branch:before{content:\"\\f126\"}.fa-codepen:before{content:\"\\f1cb\"}.fa-codiepie:before{content:\"\\f284\"}.fa-coffee:before{content:\"\\f0f4\"}.fa-cog:before{content:\"\\f013\"}.fa-cogs:before{content:\"\\f085\"}.fa-coins:before{content:\"\\f51e\"}.fa-columns:before{content:\"\\f0db\"}.fa-comment:before{content:\"\\f075\"}.fa-comment-alt:before{content:\"\\f27a\"}.fa-comment-dollar:before{content:\"\\f651\"}.fa-comment-dots:before{content:\"\\f4ad\"}.fa-comment-medical:before{content:\"\\f7f5\"}.fa-comment-slash:before{content:\"\\f4b3\"}.fa-comments:before{content:\"\\f086\"}.fa-comments-dollar:before{content:\"\\f653\"}.fa-compact-disc:before{content:\"\\f51f\"}.fa-compass:before{content:\"\\f14e\"}.fa-compress:before{content:\"\\f066\"}.fa-compress-alt:before{content:\"\\f422\"}.fa-compress-arrows-alt:before{content:\"\\f78c\"}.fa-concierge-bell:before{content:\"\\f562\"}.fa-confluence:before{content:\"\\f78d\"}.fa-connectdevelop:before{content:\"\\f20e\"}.fa-contao:before{content:\"\\f26d\"}.fa-cookie:before{content:\"\\f563\"}.fa-cookie-bite:before{content:\"\\f564\"}.fa-copy:before{content:\"\\f0c5\"}.fa-copyright:before{content:\"\\f1f9\"}.fa-cotton-bureau:before{content:\"\\f89e\"}.fa-couch:before{content:\"\\f4b8\"}.fa-cpanel:before{content:\"\\f388\"}.fa-creative-commons:before{content:\"\\f25e\"}.fa-creative-commons-by:before{content:\"\\f4e7\"}.fa-creative-commons-nc:before{content:\"\\f4e8\"}.fa-creative-commons-nc-eu:before{content:\"\\f4e9\"}.fa-creative-commons-nc-jp:before{content:\"\\f4ea\"}.fa-creative-commons-nd:before{content:\"\\f4eb\"}.fa-creative-commons-pd:before{content:\"\\f4ec\"}.fa-creative-commons-pd-alt:before{content:\"\\f4ed\"}.fa-creative-commons-remix:before{content:\"\\f4ee\"}.fa-creative-commons-sa:before{content:\"\\f4ef\"}.fa-creative-commons-sampling:before{content:\"\\f4f0\"}.fa-creative-commons-sampling-plus:before{content:\"\\f4f1\"}.fa-creative-commons-share:before{content:\"\\f4f2\"}.fa-creative-commons-zero:before{content:\"\\f4f3\"}.fa-credit-card:before{content:\"\\f09d\"}.fa-critical-role:before{content:\"\\f6c9\"}.fa-crop:before{content:\"\\f125\"}.fa-crop-alt:before{content:\"\\f565\"}.fa-cross:before{content:\"\\f654\"}.fa-crosshairs:before{content:\"\\f05b\"}.fa-crow:before{content:\"\\f520\"}.fa-crown:before{content:\"\\f521\"}.fa-crutch:before{content:\"\\f7f7\"}.fa-css3:before{content:\"\\f13c\"}.fa-css3-alt:before{content:\"\\f38b\"}.fa-cube:before{content:\"\\f1b2\"}.fa-cubes:before{content:\"\\f1b3\"}.fa-cut:before{content:\"\\f0c4\"}.fa-cuttlefish:before{content:\"\\f38c\"}.fa-d-and-d:before{content:\"\\f38d\"}.fa-d-and-d-beyond:before{content:\"\\f6ca\"}.fa-dailymotion:before{content:\"\\e052\"}.fa-dashcube:before{content:\"\\f210\"}.fa-database:before{content:\"\\f1c0\"}.fa-deaf:before{content:\"\\f2a4\"}.fa-deezer:before{content:\"\\e077\"}.fa-delicious:before{content:\"\\f1a5\"}.fa-democrat:before{content:\"\\f747\"}.fa-deploydog:before{content:\"\\f38e\"}.fa-deskpro:before{content:\"\\f38f\"}.fa-desktop:before{content:\"\\f108\"}.fa-dev:before{content:\"\\f6cc\"}.fa-deviantart:before{content:\"\\f1bd\"}.fa-dharmachakra:before{content:\"\\f655\"}.fa-dhl:before{content:\"\\f790\"}.fa-diagnoses:before{content:\"\\f470\"}.fa-diaspora:before{content:\"\\f791\"}.fa-dice:before{content:\"\\f522\"}.fa-dice-d20:before{content:\"\\f6cf\"}.fa-dice-d6:before{content:\"\\f6d1\"}.fa-dice-five:before{content:\"\\f523\"}.fa-dice-four:before{content:\"\\f524\"}.fa-dice-one:before{content:\"\\f525\"}.fa-dice-six:before{content:\"\\f526\"}.fa-dice-three:before{content:\"\\f527\"}.fa-dice-two:before{content:\"\\f528\"}.fa-digg:before{content:\"\\f1a6\"}.fa-digital-ocean:before{content:\"\\f391\"}.fa-digital-tachograph:before{content:\"\\f566\"}.fa-directions:before{content:\"\\f5eb\"}.fa-discord:before{content:\"\\f392\"}.fa-discourse:before{content:\"\\f393\"}.fa-disease:before{content:\"\\f7fa\"}.fa-divide:before{content:\"\\f529\"}.fa-dizzy:before{content:\"\\f567\"}.fa-dna:before{content:\"\\f471\"}.fa-dochub:before{content:\"\\f394\"}.fa-docker:before{content:\"\\f395\"}.fa-dog:before{content:\"\\f6d3\"}.fa-dollar-sign:before{content:\"\\f155\"}.fa-dolly:before{content:\"\\f472\"}.fa-dolly-flatbed:before{content:\"\\f474\"}.fa-donate:before{content:\"\\f4b9\"}.fa-door-closed:before{content:\"\\f52a\"}.fa-door-open:before{content:\"\\f52b\"}.fa-dot-circle:before{content:\"\\f192\"}.fa-dove:before{content:\"\\f4ba\"}.fa-download:before{content:\"\\f019\"}.fa-draft2digital:before{content:\"\\f396\"}.fa-drafting-compass:before{content:\"\\f568\"}.fa-dragon:before{content:\"\\f6d5\"}.fa-draw-polygon:before{content:\"\\f5ee\"}.fa-dribbble:before{content:\"\\f17d\"}.fa-dribbble-square:before{content:\"\\f397\"}.fa-dropbox:before{content:\"\\f16b\"}.fa-drum:before{content:\"\\f569\"}.fa-drum-steelpan:before{content:\"\\f56a\"}.fa-drumstick-bite:before{content:\"\\f6d7\"}.fa-drupal:before{content:\"\\f1a9\"}.fa-dumbbell:before{content:\"\\f44b\"}.fa-dumpster:before{content:\"\\f793\"}.fa-dumpster-fire:before{content:\"\\f794\"}.fa-dungeon:before{content:\"\\f6d9\"}.fa-dyalog:before{content:\"\\f399\"}.fa-earlybirds:before{content:\"\\f39a\"}.fa-ebay:before{content:\"\\f4f4\"}.fa-edge:before{content:\"\\f282\"}.fa-edge-legacy:before{content:\"\\e078\"}.fa-edit:before{content:\"\\f044\"}.fa-egg:before{content:\"\\f7fb\"}.fa-eject:before{content:\"\\f052\"}.fa-elementor:before{content:\"\\f430\"}.fa-ellipsis-h:before{content:\"\\f141\"}.fa-ellipsis-v:before{content:\"\\f142\"}.fa-ello:before{content:\"\\f5f1\"}.fa-ember:before{content:\"\\f423\"}.fa-empire:before{content:\"\\f1d1\"}.fa-envelope:before{content:\"\\f0e0\"}.fa-envelope-open:before{content:\"\\f2b6\"}.fa-envelope-open-text:before{content:\"\\f658\"}.fa-envelope-square:before{content:\"\\f199\"}.fa-envira:before{content:\"\\f299\"}.fa-equals:before{content:\"\\f52c\"}.fa-eraser:before{content:\"\\f12d\"}.fa-erlang:before{content:\"\\f39d\"}.fa-ethereum:before{content:\"\\f42e\"}.fa-ethernet:before{content:\"\\f796\"}.fa-etsy:before{content:\"\\f2d7\"}.fa-euro-sign:before{content:\"\\f153\"}.fa-evernote:before{content:\"\\f839\"}.fa-exchange-alt:before{content:\"\\f362\"}.fa-exclamation:before{content:\"\\f12a\"}.fa-exclamation-circle:before{content:\"\\f06a\"}.fa-exclamation-triangle:before{content:\"\\f071\"}.fa-expand:before{content:\"\\f065\"}.fa-expand-alt:before{content:\"\\f424\"}.fa-expand-arrows-alt:before{content:\"\\f31e\"}.fa-expeditedssl:before{content:\"\\f23e\"}.fa-external-link-alt:before{content:\"\\f35d\"}.fa-external-link-square-alt:before{content:\"\\f360\"}.fa-eye:before{content:\"\\f06e\"}.fa-eye-dropper:before{content:\"\\f1fb\"}.fa-eye-slash:before{content:\"\\f070\"}.fa-facebook:before{content:\"\\f09a\"}.fa-facebook-f:before{content:\"\\f39e\"}.fa-facebook-messenger:before{content:\"\\f39f\"}.fa-facebook-square:before{content:\"\\f082\"}.fa-fan:before{content:\"\\f863\"}.fa-fantasy-flight-games:before{content:\"\\f6dc\"}.fa-fast-backward:before{content:\"\\f049\"}.fa-fast-forward:before{content:\"\\f050\"}.fa-faucet:before{content:\"\\e005\"}.fa-fax:before{content:\"\\f1ac\"}.fa-feather:before{content:\"\\f52d\"}.fa-feather-alt:before{content:\"\\f56b\"}.fa-fedex:before{content:\"\\f797\"}.fa-fedora:before{content:\"\\f798\"}.fa-female:before{content:\"\\f182\"}.fa-fighter-jet:before{content:\"\\f0fb\"}.fa-figma:before{content:\"\\f799\"}.fa-file:before{content:\"\\f15b\"}.fa-file-alt:before{content:\"\\f15c\"}.fa-file-archive:before{content:\"\\f1c6\"}.fa-file-audio:before{content:\"\\f1c7\"}.fa-file-code:before{content:\"\\f1c9\"}.fa-file-contract:before{content:\"\\f56c\"}.fa-file-csv:before{content:\"\\f6dd\"}.fa-file-download:before{content:\"\\f56d\"}.fa-file-excel:before{content:\"\\f1c3\"}.fa-file-export:before{content:\"\\f56e\"}.fa-file-image:before{content:\"\\f1c5\"}.fa-file-import:before{content:\"\\f56f\"}.fa-file-invoice:before{content:\"\\f570\"}.fa-file-invoice-dollar:before{content:\"\\f571\"}.fa-file-medical:before{content:\"\\f477\"}.fa-file-medical-alt:before{content:\"\\f478\"}.fa-file-pdf:before{content:\"\\f1c1\"}.fa-file-powerpoint:before{content:\"\\f1c4\"}.fa-file-prescription:before{content:\"\\f572\"}.fa-file-signature:before{content:\"\\f573\"}.fa-file-upload:before{content:\"\\f574\"}.fa-file-video:before{content:\"\\f1c8\"}.fa-file-word:before{content:\"\\f1c2\"}.fa-fill:before{content:\"\\f575\"}.fa-fill-drip:before{content:\"\\f576\"}.fa-film:before{content:\"\\f008\"}.fa-filter:before{content:\"\\f0b0\"}.fa-fingerprint:before{content:\"\\f577\"}.fa-fire:before{content:\"\\f06d\"}.fa-fire-alt:before{content:\"\\f7e4\"}.fa-fire-extinguisher:before{content:\"\\f134\"}.fa-firefox:before{content:\"\\f269\"}.fa-firefox-browser:before{content:\"\\e007\"}.fa-first-aid:before{content:\"\\f479\"}.fa-first-order:before{content:\"\\f2b0\"}.fa-first-order-alt:before{content:\"\\f50a\"}.fa-firstdraft:before{content:\"\\f3a1\"}.fa-fish:before{content:\"\\f578\"}.fa-fist-raised:before{content:\"\\f6de\"}.fa-flag:before{content:\"\\f024\"}.fa-flag-checkered:before{content:\"\\f11e\"}.fa-flag-usa:before{content:\"\\f74d\"}.fa-flask:before{content:\"\\f0c3\"}.fa-flickr:before{content:\"\\f16e\"}.fa-flipboard:before{content:\"\\f44d\"}.fa-flushed:before{content:\"\\f579\"}.fa-fly:before{content:\"\\f417\"}.fa-folder:before{content:\"\\f07b\"}.fa-folder-minus:before{content:\"\\f65d\"}.fa-folder-open:before{content:\"\\f07c\"}.fa-folder-plus:before{content:\"\\f65e\"}.fa-font:before{content:\"\\f031\"}.fa-font-awesome:before{content:\"\\f2b4\"}.fa-font-awesome-alt:before{content:\"\\f35c\"}.fa-font-awesome-flag:before{content:\"\\f425\"}.fa-font-awesome-logo-full:before{content:\"\\f4e6\"}.fa-fonticons:before{content:\"\\f280\"}.fa-fonticons-fi:before{content:\"\\f3a2\"}.fa-football-ball:before{content:\"\\f44e\"}.fa-fort-awesome:before{content:\"\\f286\"}.fa-fort-awesome-alt:before{content:\"\\f3a3\"}.fa-forumbee:before{content:\"\\f211\"}.fa-forward:before{content:\"\\f04e\"}.fa-foursquare:before{content:\"\\f180\"}.fa-free-code-camp:before{content:\"\\f2c5\"}.fa-freebsd:before{content:\"\\f3a4\"}.fa-frog:before{content:\"\\f52e\"}.fa-frown:before{content:\"\\f119\"}.fa-frown-open:before{content:\"\\f57a\"}.fa-fulcrum:before{content:\"\\f50b\"}.fa-funnel-dollar:before{content:\"\\f662\"}.fa-futbol:before{content:\"\\f1e3\"}.fa-galactic-republic:before{content:\"\\f50c\"}.fa-galactic-senate:before{content:\"\\f50d\"}.fa-gamepad:before{content:\"\\f11b\"}.fa-gas-pump:before{content:\"\\f52f\"}.fa-gavel:before{content:\"\\f0e3\"}.fa-gem:before{content:\"\\f3a5\"}.fa-genderless:before{content:\"\\f22d\"}.fa-get-pocket:before{content:\"\\f265\"}.fa-gg:before{content:\"\\f260\"}.fa-gg-circle:before{content:\"\\f261\"}.fa-ghost:before{content:\"\\f6e2\"}.fa-gift:before{content:\"\\f06b\"}.fa-gifts:before{content:\"\\f79c\"}.fa-git:before{content:\"\\f1d3\"}.fa-git-alt:before{content:\"\\f841\"}.fa-git-square:before{content:\"\\f1d2\"}.fa-github:before{content:\"\\f09b\"}.fa-github-alt:before{content:\"\\f113\"}.fa-github-square:before{content:\"\\f092\"}.fa-gitkraken:before{content:\"\\f3a6\"}.fa-gitlab:before{content:\"\\f296\"}.fa-gitter:before{content:\"\\f426\"}.fa-glass-cheers:before{content:\"\\f79f\"}.fa-glass-martini:before{content:\"\\f000\"}.fa-glass-martini-alt:before{content:\"\\f57b\"}.fa-glass-whiskey:before{content:\"\\f7a0\"}.fa-glasses:before{content:\"\\f530\"}.fa-glide:before{content:\"\\f2a5\"}.fa-glide-g:before{content:\"\\f2a6\"}.fa-globe:before{content:\"\\f0ac\"}.fa-globe-africa:before{content:\"\\f57c\"}.fa-globe-americas:before{content:\"\\f57d\"}.fa-globe-asia:before{content:\"\\f57e\"}.fa-globe-europe:before{content:\"\\f7a2\"}.fa-gofore:before{content:\"\\f3a7\"}.fa-golf-ball:before{content:\"\\f450\"}.fa-goodreads:before{content:\"\\f3a8\"}.fa-goodreads-g:before{content:\"\\f3a9\"}.fa-google:before{content:\"\\f1a0\"}.fa-google-drive:before{content:\"\\f3aa\"}.fa-google-pay:before{content:\"\\e079\"}.fa-google-play:before{content:\"\\f3ab\"}.fa-google-plus:before{content:\"\\f2b3\"}.fa-google-plus-g:before{content:\"\\f0d5\"}.fa-google-plus-square:before{content:\"\\f0d4\"}.fa-google-wallet:before{content:\"\\f1ee\"}.fa-gopuram:before{content:\"\\f664\"}.fa-graduation-cap:before{content:\"\\f19d\"}.fa-gratipay:before{content:\"\\f184\"}.fa-grav:before{content:\"\\f2d6\"}.fa-greater-than:before{content:\"\\f531\"}.fa-greater-than-equal:before{content:\"\\f532\"}.fa-grimace:before{content:\"\\f57f\"}.fa-grin:before{content:\"\\f580\"}.fa-grin-alt:before{content:\"\\f581\"}.fa-grin-beam:before{content:\"\\f582\"}.fa-grin-beam-sweat:before{content:\"\\f583\"}.fa-grin-hearts:before{content:\"\\f584\"}.fa-grin-squint:before{content:\"\\f585\"}.fa-grin-squint-tears:before{content:\"\\f586\"}.fa-grin-stars:before{content:\"\\f587\"}.fa-grin-tears:before{content:\"\\f588\"}.fa-grin-tongue:before{content:\"\\f589\"}.fa-grin-tongue-squint:before{content:\"\\f58a\"}.fa-grin-tongue-wink:before{content:\"\\f58b\"}.fa-grin-wink:before{content:\"\\f58c\"}.fa-grip-horizontal:before{content:\"\\f58d\"}.fa-grip-lines:before{content:\"\\f7a4\"}.fa-grip-lines-vertical:before{content:\"\\f7a5\"}.fa-grip-vertical:before{content:\"\\f58e\"}.fa-gripfire:before{content:\"\\f3ac\"}.fa-grunt:before{content:\"\\f3ad\"}.fa-guitar:before{content:\"\\f7a6\"}.fa-gulp:before{content:\"\\f3ae\"}.fa-h-square:before{content:\"\\f0fd\"}.fa-hacker-news:before{content:\"\\f1d4\"}.fa-hacker-news-square:before{content:\"\\f3af\"}.fa-hackerrank:before{content:\"\\f5f7\"}.fa-hamburger:before{content:\"\\f805\"}.fa-hammer:before{content:\"\\f6e3\"}.fa-hamsa:before{content:\"\\f665\"}.fa-hand-holding:before{content:\"\\f4bd\"}.fa-hand-holding-heart:before{content:\"\\f4be\"}.fa-hand-holding-medical:before{content:\"\\e05c\"}.fa-hand-holding-usd:before{content:\"\\f4c0\"}.fa-hand-holding-water:before{content:\"\\f4c1\"}.fa-hand-lizard:before{content:\"\\f258\"}.fa-hand-middle-finger:before{content:\"\\f806\"}.fa-hand-paper:before{content:\"\\f256\"}.fa-hand-peace:before{content:\"\\f25b\"}.fa-hand-point-down:before{content:\"\\f0a7\"}.fa-hand-point-left:before{content:\"\\f0a5\"}.fa-hand-point-right:before{content:\"\\f0a4\"}.fa-hand-point-up:before{content:\"\\f0a6\"}.fa-hand-pointer:before{content:\"\\f25a\"}.fa-hand-rock:before{content:\"\\f255\"}.fa-hand-scissors:before{content:\"\\f257\"}.fa-hand-sparkles:before{content:\"\\e05d\"}.fa-hand-spock:before{content:\"\\f259\"}.fa-hands:before{content:\"\\f4c2\"}.fa-hands-helping:before{content:\"\\f4c4\"}.fa-hands-wash:before{content:\"\\e05e\"}.fa-handshake:before{content:\"\\f2b5\"}.fa-handshake-alt-slash:before{content:\"\\e05f\"}.fa-handshake-slash:before{content:\"\\e060\"}.fa-hanukiah:before{content:\"\\f6e6\"}.fa-hard-hat:before{content:\"\\f807\"}.fa-hashtag:before{content:\"\\f292\"}.fa-hat-cowboy:before{content:\"\\f8c0\"}.fa-hat-cowboy-side:before{content:\"\\f8c1\"}.fa-hat-wizard:before{content:\"\\f6e8\"}.fa-hdd:before{content:\"\\f0a0\"}.fa-head-side-cough:before{content:\"\\e061\"}.fa-head-side-cough-slash:before{content:\"\\e062\"}.fa-head-side-mask:before{content:\"\\e063\"}.fa-head-side-virus:before{content:\"\\e064\"}.fa-heading:before{content:\"\\f1dc\"}.fa-headphones:before{content:\"\\f025\"}.fa-headphones-alt:before{content:\"\\f58f\"}.fa-headset:before{content:\"\\f590\"}.fa-heart:before{content:\"\\f004\"}.fa-heart-broken:before{content:\"\\f7a9\"}.fa-heartbeat:before{content:\"\\f21e\"}.fa-helicopter:before{content:\"\\f533\"}.fa-highlighter:before{content:\"\\f591\"}.fa-hiking:before{content:\"\\f6ec\"}.fa-hippo:before{content:\"\\f6ed\"}.fa-hips:before{content:\"\\f452\"}.fa-hire-a-helper:before{content:\"\\f3b0\"}.fa-history:before{content:\"\\f1da\"}.fa-hockey-puck:before{content:\"\\f453\"}.fa-holly-berry:before{content:\"\\f7aa\"}.fa-home:before{content:\"\\f015\"}.fa-hooli:before{content:\"\\f427\"}.fa-hornbill:before{content:\"\\f592\"}.fa-horse:before{content:\"\\f6f0\"}.fa-horse-head:before{content:\"\\f7ab\"}.fa-hospital:before{content:\"\\f0f8\"}.fa-hospital-alt:before{content:\"\\f47d\"}.fa-hospital-symbol:before{content:\"\\f47e\"}.fa-hospital-user:before{content:\"\\f80d\"}.fa-hot-tub:before{content:\"\\f593\"}.fa-hotdog:before{content:\"\\f80f\"}.fa-hotel:before{content:\"\\f594\"}.fa-hotjar:before{content:\"\\f3b1\"}.fa-hourglass:before{content:\"\\f254\"}.fa-hourglass-end:before{content:\"\\f253\"}.fa-hourglass-half:before{content:\"\\f252\"}.fa-hourglass-start:before{content:\"\\f251\"}.fa-house-damage:before{content:\"\\f6f1\"}.fa-house-user:before{content:\"\\e065\"}.fa-houzz:before{content:\"\\f27c\"}.fa-hryvnia:before{content:\"\\f6f2\"}.fa-html5:before{content:\"\\f13b\"}.fa-hubspot:before{content:\"\\f3b2\"}.fa-i-cursor:before{content:\"\\f246\"}.fa-ice-cream:before{content:\"\\f810\"}.fa-icicles:before{content:\"\\f7ad\"}.fa-icons:before{content:\"\\f86d\"}.fa-id-badge:before{content:\"\\f2c1\"}.fa-id-card:before{content:\"\\f2c2\"}.fa-id-card-alt:before{content:\"\\f47f\"}.fa-ideal:before{content:\"\\e013\"}.fa-igloo:before{content:\"\\f7ae\"}.fa-image:before{content:\"\\f03e\"}.fa-images:before{content:\"\\f302\"}.fa-imdb:before{content:\"\\f2d8\"}.fa-inbox:before{content:\"\\f01c\"}.fa-indent:before{content:\"\\f03c\"}.fa-industry:before{content:\"\\f275\"}.fa-infinity:before{content:\"\\f534\"}.fa-info:before{content:\"\\f129\"}.fa-info-circle:before{content:\"\\f05a\"}.fa-instagram:before{content:\"\\f16d\"}.fa-instagram-square:before{content:\"\\e055\"}.fa-intercom:before{content:\"\\f7af\"}.fa-internet-explorer:before{content:\"\\f26b\"}.fa-invision:before{content:\"\\f7b0\"}.fa-ioxhost:before{content:\"\\f208\"}.fa-italic:before{content:\"\\f033\"}.fa-itch-io:before{content:\"\\f83a\"}.fa-itunes:before{content:\"\\f3b4\"}.fa-itunes-note:before{content:\"\\f3b5\"}.fa-java:before{content:\"\\f4e4\"}.fa-jedi:before{content:\"\\f669\"}.fa-jedi-order:before{content:\"\\f50e\"}.fa-jenkins:before{content:\"\\f3b6\"}.fa-jira:before{content:\"\\f7b1\"}.fa-joget:before{content:\"\\f3b7\"}.fa-joint:before{content:\"\\f595\"}.fa-joomla:before{content:\"\\f1aa\"}.fa-journal-whills:before{content:\"\\f66a\"}.fa-js:before{content:\"\\f3b8\"}.fa-js-square:before{content:\"\\f3b9\"}.fa-jsfiddle:before{content:\"\\f1cc\"}.fa-kaaba:before{content:\"\\f66b\"}.fa-kaggle:before{content:\"\\f5fa\"}.fa-key:before{content:\"\\f084\"}.fa-keybase:before{content:\"\\f4f5\"}.fa-keyboard:before{content:\"\\f11c\"}.fa-keycdn:before{content:\"\\f3ba\"}.fa-khanda:before{content:\"\\f66d\"}.fa-kickstarter:before{content:\"\\f3bb\"}.fa-kickstarter-k:before{content:\"\\f3bc\"}.fa-kiss:before{content:\"\\f596\"}.fa-kiss-beam:before{content:\"\\f597\"}.fa-kiss-wink-heart:before{content:\"\\f598\"}.fa-kiwi-bird:before{content:\"\\f535\"}.fa-korvue:before{content:\"\\f42f\"}.fa-landmark:before{content:\"\\f66f\"}.fa-language:before{content:\"\\f1ab\"}.fa-laptop:before{content:\"\\f109\"}.fa-laptop-code:before{content:\"\\f5fc\"}.fa-laptop-house:before{content:\"\\e066\"}.fa-laptop-medical:before{content:\"\\f812\"}.fa-laravel:before{content:\"\\f3bd\"}.fa-lastfm:before{content:\"\\f202\"}.fa-lastfm-square:before{content:\"\\f203\"}.fa-laugh:before{content:\"\\f599\"}.fa-laugh-beam:before{content:\"\\f59a\"}.fa-laugh-squint:before{content:\"\\f59b\"}.fa-laugh-wink:before{content:\"\\f59c\"}.fa-layer-group:before{content:\"\\f5fd\"}.fa-leaf:before{content:\"\\f06c\"}.fa-leanpub:before{content:\"\\f212\"}.fa-lemon:before{content:\"\\f094\"}.fa-less:before{content:\"\\f41d\"}.fa-less-than:before{content:\"\\f536\"}.fa-less-than-equal:before{content:\"\\f537\"}.fa-level-down-alt:before{content:\"\\f3be\"}.fa-level-up-alt:before{content:\"\\f3bf\"}.fa-life-ring:before{content:\"\\f1cd\"}.fa-lightbulb:before{content:\"\\f0eb\"}.fa-line:before{content:\"\\f3c0\"}.fa-link:before{content:\"\\f0c1\"}.fa-linkedin:before{content:\"\\f08c\"}.fa-linkedin-in:before{content:\"\\f0e1\"}.fa-linode:before{content:\"\\f2b8\"}.fa-linux:before{content:\"\\f17c\"}.fa-lira-sign:before{content:\"\\f195\"}.fa-list:before{content:\"\\f03a\"}.fa-list-alt:before{content:\"\\f022\"}.fa-list-ol:before{content:\"\\f0cb\"}.fa-list-ul:before{content:\"\\f0ca\"}.fa-location-arrow:before{content:\"\\f124\"}.fa-lock:before{content:\"\\f023\"}.fa-lock-open:before{content:\"\\f3c1\"}.fa-long-arrow-alt-down:before{content:\"\\f309\"}.fa-long-arrow-alt-left:before{content:\"\\f30a\"}.fa-long-arrow-alt-right:before{content:\"\\f30b\"}.fa-long-arrow-alt-up:before{content:\"\\f30c\"}.fa-low-vision:before{content:\"\\f2a8\"}.fa-luggage-cart:before{content:\"\\f59d\"}.fa-lungs:before{content:\"\\f604\"}.fa-lungs-virus:before{content:\"\\e067\"}.fa-lyft:before{content:\"\\f3c3\"}.fa-magento:before{content:\"\\f3c4\"}.fa-magic:before{content:\"\\f0d0\"}.fa-magnet:before{content:\"\\f076\"}.fa-mail-bulk:before{content:\"\\f674\"}.fa-mailchimp:before{content:\"\\f59e\"}.fa-male:before{content:\"\\f183\"}.fa-mandalorian:before{content:\"\\f50f\"}.fa-map:before{content:\"\\f279\"}.fa-map-marked:before{content:\"\\f59f\"}.fa-map-marked-alt:before{content:\"\\f5a0\"}.fa-map-marker:before{content:\"\\f041\"}.fa-map-marker-alt:before{content:\"\\f3c5\"}.fa-map-pin:before{content:\"\\f276\"}.fa-map-signs:before{content:\"\\f277\"}.fa-markdown:before{content:\"\\f60f\"}.fa-marker:before{content:\"\\f5a1\"}.fa-mars:before{content:\"\\f222\"}.fa-mars-double:before{content:\"\\f227\"}.fa-mars-stroke:before{content:\"\\f229\"}.fa-mars-stroke-h:before{content:\"\\f22b\"}.fa-mars-stroke-v:before{content:\"\\f22a\"}.fa-mask:before{content:\"\\f6fa\"}.fa-mastodon:before{content:\"\\f4f6\"}.fa-maxcdn:before{content:\"\\f136\"}.fa-mdb:before{content:\"\\f8ca\"}.fa-medal:before{content:\"\\f5a2\"}.fa-medapps:before{content:\"\\f3c6\"}.fa-medium:before{content:\"\\f23a\"}.fa-medium-m:before{content:\"\\f3c7\"}.fa-medkit:before{content:\"\\f0fa\"}.fa-medrt:before{content:\"\\f3c8\"}.fa-meetup:before{content:\"\\f2e0\"}.fa-megaport:before{content:\"\\f5a3\"}.fa-meh:before{content:\"\\f11a\"}.fa-meh-blank:before{content:\"\\f5a4\"}.fa-meh-rolling-eyes:before{content:\"\\f5a5\"}.fa-memory:before{content:\"\\f538\"}.fa-mendeley:before{content:\"\\f7b3\"}.fa-menorah:before{content:\"\\f676\"}.fa-mercury:before{content:\"\\f223\"}.fa-meteor:before{content:\"\\f753\"}.fa-microblog:before{content:\"\\e01a\"}.fa-microchip:before{content:\"\\f2db\"}.fa-microphone:before{content:\"\\f130\"}.fa-microphone-alt:before{content:\"\\f3c9\"}.fa-microphone-alt-slash:before{content:\"\\f539\"}.fa-microphone-slash:before{content:\"\\f131\"}.fa-microscope:before{content:\"\\f610\"}.fa-microsoft:before{content:\"\\f3ca\"}.fa-minus:before{content:\"\\f068\"}.fa-minus-circle:before{content:\"\\f056\"}.fa-minus-square:before{content:\"\\f146\"}.fa-mitten:before{content:\"\\f7b5\"}.fa-mix:before{content:\"\\f3cb\"}.fa-mixcloud:before{content:\"\\f289\"}.fa-mixer:before{content:\"\\e056\"}.fa-mizuni:before{content:\"\\f3cc\"}.fa-mobile:before{content:\"\\f10b\"}.fa-mobile-alt:before{content:\"\\f3cd\"}.fa-modx:before{content:\"\\f285\"}.fa-monero:before{content:\"\\f3d0\"}.fa-money-bill:before{content:\"\\f0d6\"}.fa-money-bill-alt:before{content:\"\\f3d1\"}.fa-money-bill-wave:before{content:\"\\f53a\"}.fa-money-bill-wave-alt:before{content:\"\\f53b\"}.fa-money-check:before{content:\"\\f53c\"}.fa-money-check-alt:before{content:\"\\f53d\"}.fa-monument:before{content:\"\\f5a6\"}.fa-moon:before{content:\"\\f186\"}.fa-mortar-pestle:before{content:\"\\f5a7\"}.fa-mosque:before{content:\"\\f678\"}.fa-motorcycle:before{content:\"\\f21c\"}.fa-mountain:before{content:\"\\f6fc\"}.fa-mouse:before{content:\"\\f8cc\"}.fa-mouse-pointer:before{content:\"\\f245\"}.fa-mug-hot:before{content:\"\\f7b6\"}.fa-music:before{content:\"\\f001\"}.fa-napster:before{content:\"\\f3d2\"}.fa-neos:before{content:\"\\f612\"}.fa-network-wired:before{content:\"\\f6ff\"}.fa-neuter:before{content:\"\\f22c\"}.fa-newspaper:before{content:\"\\f1ea\"}.fa-nimblr:before{content:\"\\f5a8\"}.fa-node:before{content:\"\\f419\"}.fa-node-js:before{content:\"\\f3d3\"}.fa-not-equal:before{content:\"\\f53e\"}.fa-notes-medical:before{content:\"\\f481\"}.fa-npm:before{content:\"\\f3d4\"}.fa-ns8:before{content:\"\\f3d5\"}.fa-nutritionix:before{content:\"\\f3d6\"}.fa-object-group:before{content:\"\\f247\"}.fa-object-ungroup:before{content:\"\\f248\"}.fa-odnoklassniki:before{content:\"\\f263\"}.fa-odnoklassniki-square:before{content:\"\\f264\"}.fa-oil-can:before{content:\"\\f613\"}.fa-old-republic:before{content:\"\\f510\"}.fa-om:before{content:\"\\f679\"}.fa-opencart:before{content:\"\\f23d\"}.fa-openid:before{content:\"\\f19b\"}.fa-opera:before{content:\"\\f26a\"}.fa-optin-monster:before{content:\"\\f23c\"}.fa-orcid:before{content:\"\\f8d2\"}.fa-osi:before{content:\"\\f41a\"}.fa-otter:before{content:\"\\f700\"}.fa-outdent:before{content:\"\\f03b\"}.fa-page4:before{content:\"\\f3d7\"}.fa-pagelines:before{content:\"\\f18c\"}.fa-pager:before{content:\"\\f815\"}.fa-paint-brush:before{content:\"\\f1fc\"}.fa-paint-roller:before{content:\"\\f5aa\"}.fa-palette:before{content:\"\\f53f\"}.fa-palfed:before{content:\"\\f3d8\"}.fa-pallet:before{content:\"\\f482\"}.fa-paper-plane:before{content:\"\\f1d8\"}.fa-paperclip:before{content:\"\\f0c6\"}.fa-parachute-box:before{content:\"\\f4cd\"}.fa-paragraph:before{content:\"\\f1dd\"}.fa-parking:before{content:\"\\f540\"}.fa-passport:before{content:\"\\f5ab\"}.fa-pastafarianism:before{content:\"\\f67b\"}.fa-paste:before{content:\"\\f0ea\"}.fa-patreon:before{content:\"\\f3d9\"}.fa-pause:before{content:\"\\f04c\"}.fa-pause-circle:before{content:\"\\f28b\"}.fa-paw:before{content:\"\\f1b0\"}.fa-paypal:before{content:\"\\f1ed\"}.fa-peace:before{content:\"\\f67c\"}.fa-pen:before{content:\"\\f304\"}.fa-pen-alt:before{content:\"\\f305\"}.fa-pen-fancy:before{content:\"\\f5ac\"}.fa-pen-nib:before{content:\"\\f5ad\"}.fa-pen-square:before{content:\"\\f14b\"}.fa-pencil-alt:before{content:\"\\f303\"}.fa-pencil-ruler:before{content:\"\\f5ae\"}.fa-penny-arcade:before{content:\"\\f704\"}.fa-people-arrows:before{content:\"\\e068\"}.fa-people-carry:before{content:\"\\f4ce\"}.fa-pepper-hot:before{content:\"\\f816\"}.fa-percent:before{content:\"\\f295\"}.fa-percentage:before{content:\"\\f541\"}.fa-periscope:before{content:\"\\f3da\"}.fa-person-booth:before{content:\"\\f756\"}.fa-phabricator:before{content:\"\\f3db\"}.fa-phoenix-framework:before{content:\"\\f3dc\"}.fa-phoenix-squadron:before{content:\"\\f511\"}.fa-phone:before{content:\"\\f095\"}.fa-phone-alt:before{content:\"\\f879\"}.fa-phone-slash:before{content:\"\\f3dd\"}.fa-phone-square:before{content:\"\\f098\"}.fa-phone-square-alt:before{content:\"\\f87b\"}.fa-phone-volume:before{content:\"\\f2a0\"}.fa-photo-video:before{content:\"\\f87c\"}.fa-php:before{content:\"\\f457\"}.fa-pied-piper:before{content:\"\\f2ae\"}.fa-pied-piper-alt:before{content:\"\\f1a8\"}.fa-pied-piper-hat:before{content:\"\\f4e5\"}.fa-pied-piper-pp:before{content:\"\\f1a7\"}.fa-pied-piper-square:before{content:\"\\e01e\"}.fa-piggy-bank:before{content:\"\\f4d3\"}.fa-pills:before{content:\"\\f484\"}.fa-pinterest:before{content:\"\\f0d2\"}.fa-pinterest-p:before{content:\"\\f231\"}.fa-pinterest-square:before{content:\"\\f0d3\"}.fa-pizza-slice:before{content:\"\\f818\"}.fa-place-of-worship:before{content:\"\\f67f\"}.fa-plane:before{content:\"\\f072\"}.fa-plane-arrival:before{content:\"\\f5af\"}.fa-plane-departure:before{content:\"\\f5b0\"}.fa-plane-slash:before{content:\"\\e069\"}.fa-play:before{content:\"\\f04b\"}.fa-play-circle:before{content:\"\\f144\"}.fa-playstation:before{content:\"\\f3df\"}.fa-plug:before{content:\"\\f1e6\"}.fa-plus:before{content:\"\\f067\"}.fa-plus-circle:before{content:\"\\f055\"}.fa-plus-square:before{content:\"\\f0fe\"}.fa-podcast:before{content:\"\\f2ce\"}.fa-poll:before{content:\"\\f681\"}.fa-poll-h:before{content:\"\\f682\"}.fa-poo:before{content:\"\\f2fe\"}.fa-poo-storm:before{content:\"\\f75a\"}.fa-poop:before{content:\"\\f619\"}.fa-portrait:before{content:\"\\f3e0\"}.fa-pound-sign:before{content:\"\\f154\"}.fa-power-off:before{content:\"\\f011\"}.fa-pray:before{content:\"\\f683\"}.fa-praying-hands:before{content:\"\\f684\"}.fa-prescription:before{content:\"\\f5b1\"}.fa-prescription-bottle:before{content:\"\\f485\"}.fa-prescription-bottle-alt:before{content:\"\\f486\"}.fa-print:before{content:\"\\f02f\"}.fa-procedures:before{content:\"\\f487\"}.fa-product-hunt:before{content:\"\\f288\"}.fa-project-diagram:before{content:\"\\f542\"}.fa-pump-medical:before{content:\"\\e06a\"}.fa-pump-soap:before{content:\"\\e06b\"}.fa-pushed:before{content:\"\\f3e1\"}.fa-puzzle-piece:before{content:\"\\f12e\"}.fa-python:before{content:\"\\f3e2\"}.fa-qq:before{content:\"\\f1d6\"}.fa-qrcode:before{content:\"\\f029\"}.fa-question:before{content:\"\\f128\"}.fa-question-circle:before{content:\"\\f059\"}.fa-quidditch:before{content:\"\\f458\"}.fa-quinscape:before{content:\"\\f459\"}.fa-quora:before{content:\"\\f2c4\"}.fa-quote-left:before{content:\"\\f10d\"}.fa-quote-right:before{content:\"\\f10e\"}.fa-quran:before{content:\"\\f687\"}.fa-r-project:before{content:\"\\f4f7\"}.fa-radiation:before{content:\"\\f7b9\"}.fa-radiation-alt:before{content:\"\\f7ba\"}.fa-rainbow:before{content:\"\\f75b\"}.fa-random:before{content:\"\\f074\"}.fa-raspberry-pi:before{content:\"\\f7bb\"}.fa-ravelry:before{content:\"\\f2d9\"}.fa-react:before{content:\"\\f41b\"}.fa-reacteurope:before{content:\"\\f75d\"}.fa-readme:before{content:\"\\f4d5\"}.fa-rebel:before{content:\"\\f1d0\"}.fa-receipt:before{content:\"\\f543\"}.fa-record-vinyl:before{content:\"\\f8d9\"}.fa-recycle:before{content:\"\\f1b8\"}.fa-red-river:before{content:\"\\f3e3\"}.fa-reddit:before{content:\"\\f1a1\"}.fa-reddit-alien:before{content:\"\\f281\"}.fa-reddit-square:before{content:\"\\f1a2\"}.fa-redhat:before{content:\"\\f7bc\"}.fa-redo:before{content:\"\\f01e\"}.fa-redo-alt:before{content:\"\\f2f9\"}.fa-registered:before{content:\"\\f25d\"}.fa-remove-format:before{content:\"\\f87d\"}.fa-renren:before{content:\"\\f18b\"}.fa-reply:before{content:\"\\f3e5\"}.fa-reply-all:before{content:\"\\f122\"}.fa-replyd:before{content:\"\\f3e6\"}.fa-republican:before{content:\"\\f75e\"}.fa-researchgate:before{content:\"\\f4f8\"}.fa-resolving:before{content:\"\\f3e7\"}.fa-restroom:before{content:\"\\f7bd\"}.fa-retweet:before{content:\"\\f079\"}.fa-rev:before{content:\"\\f5b2\"}.fa-ribbon:before{content:\"\\f4d6\"}.fa-ring:before{content:\"\\f70b\"}.fa-road:before{content:\"\\f018\"}.fa-robot:before{content:\"\\f544\"}.fa-rocket:before{content:\"\\f135\"}.fa-rocketchat:before{content:\"\\f3e8\"}.fa-rockrms:before{content:\"\\f3e9\"}.fa-route:before{content:\"\\f4d7\"}.fa-rss:before{content:\"\\f09e\"}.fa-rss-square:before{content:\"\\f143\"}.fa-ruble-sign:before{content:\"\\f158\"}.fa-ruler:before{content:\"\\f545\"}.fa-ruler-combined:before{content:\"\\f546\"}.fa-ruler-horizontal:before{content:\"\\f547\"}.fa-ruler-vertical:before{content:\"\\f548\"}.fa-running:before{content:\"\\f70c\"}.fa-rupee-sign:before{content:\"\\f156\"}.fa-rust:before{content:\"\\e07a\"}.fa-sad-cry:before{content:\"\\f5b3\"}.fa-sad-tear:before{content:\"\\f5b4\"}.fa-safari:before{content:\"\\f267\"}.fa-salesforce:before{content:\"\\f83b\"}.fa-sass:before{content:\"\\f41e\"}.fa-satellite:before{content:\"\\f7bf\"}.fa-satellite-dish:before{content:\"\\f7c0\"}.fa-save:before{content:\"\\f0c7\"}.fa-schlix:before{content:\"\\f3ea\"}.fa-school:before{content:\"\\f549\"}.fa-screwdriver:before{content:\"\\f54a\"}.fa-scribd:before{content:\"\\f28a\"}.fa-scroll:before{content:\"\\f70e\"}.fa-sd-card:before{content:\"\\f7c2\"}.fa-search:before{content:\"\\f002\"}.fa-search-dollar:before{content:\"\\f688\"}.fa-search-location:before{content:\"\\f689\"}.fa-search-minus:before{content:\"\\f010\"}.fa-search-plus:before{content:\"\\f00e\"}.fa-searchengin:before{content:\"\\f3eb\"}.fa-seedling:before{content:\"\\f4d8\"}.fa-sellcast:before{content:\"\\f2da\"}.fa-sellsy:before{content:\"\\f213\"}.fa-server:before{content:\"\\f233\"}.fa-servicestack:before{content:\"\\f3ec\"}.fa-shapes:before{content:\"\\f61f\"}.fa-share:before{content:\"\\f064\"}.fa-share-alt:before{content:\"\\f1e0\"}.fa-share-alt-square:before{content:\"\\f1e1\"}.fa-share-square:before{content:\"\\f14d\"}.fa-shekel-sign:before{content:\"\\f20b\"}.fa-shield-alt:before{content:\"\\f3ed\"}.fa-shield-virus:before{content:\"\\e06c\"}.fa-ship:before{content:\"\\f21a\"}.fa-shipping-fast:before{content:\"\\f48b\"}.fa-shirtsinbulk:before{content:\"\\f214\"}.fa-shoe-prints:before{content:\"\\f54b\"}.fa-shopify:before{content:\"\\e057\"}.fa-shopping-bag:before{content:\"\\f290\"}.fa-shopping-basket:before{content:\"\\f291\"}.fa-shopping-cart:before{content:\"\\f07a\"}.fa-shopware:before{content:\"\\f5b5\"}.fa-shower:before{content:\"\\f2cc\"}.fa-shuttle-van:before{content:\"\\f5b6\"}.fa-sign:before{content:\"\\f4d9\"}.fa-sign-in-alt:before{content:\"\\f2f6\"}.fa-sign-language:before{content:\"\\f2a7\"}.fa-sign-out-alt:before{content:\"\\f2f5\"}.fa-signal:before{content:\"\\f012\"}.fa-signature:before{content:\"\\f5b7\"}.fa-sim-card:before{content:\"\\f7c4\"}.fa-simplybuilt:before{content:\"\\f215\"}.fa-sink:before{content:\"\\e06d\"}.fa-sistrix:before{content:\"\\f3ee\"}.fa-sitemap:before{content:\"\\f0e8\"}.fa-sith:before{content:\"\\f512\"}.fa-skating:before{content:\"\\f7c5\"}.fa-sketch:before{content:\"\\f7c6\"}.fa-skiing:before{content:\"\\f7c9\"}.fa-skiing-nordic:before{content:\"\\f7ca\"}.fa-skull:before{content:\"\\f54c\"}.fa-skull-crossbones:before{content:\"\\f714\"}.fa-skyatlas:before{content:\"\\f216\"}.fa-skype:before{content:\"\\f17e\"}.fa-slack:before{content:\"\\f198\"}.fa-slack-hash:before{content:\"\\f3ef\"}.fa-slash:before{content:\"\\f715\"}.fa-sleigh:before{content:\"\\f7cc\"}.fa-sliders-h:before{content:\"\\f1de\"}.fa-slideshare:before{content:\"\\f1e7\"}.fa-smile:before{content:\"\\f118\"}.fa-smile-beam:before{content:\"\\f5b8\"}.fa-smile-wink:before{content:\"\\f4da\"}.fa-smog:before{content:\"\\f75f\"}.fa-smoking:before{content:\"\\f48d\"}.fa-smoking-ban:before{content:\"\\f54d\"}.fa-sms:before{content:\"\\f7cd\"}.fa-snapchat:before{content:\"\\f2ab\"}.fa-snapchat-ghost:before{content:\"\\f2ac\"}.fa-snapchat-square:before{content:\"\\f2ad\"}.fa-snowboarding:before{content:\"\\f7ce\"}.fa-snowflake:before{content:\"\\f2dc\"}.fa-snowman:before{content:\"\\f7d0\"}.fa-snowplow:before{content:\"\\f7d2\"}.fa-soap:before{content:\"\\e06e\"}.fa-socks:before{content:\"\\f696\"}.fa-solar-panel:before{content:\"\\f5ba\"}.fa-sort:before{content:\"\\f0dc\"}.fa-sort-alpha-down:before{content:\"\\f15d\"}.fa-sort-alpha-down-alt:before{content:\"\\f881\"}.fa-sort-alpha-up:before{content:\"\\f15e\"}.fa-sort-alpha-up-alt:before{content:\"\\f882\"}.fa-sort-amount-down:before{content:\"\\f160\"}.fa-sort-amount-down-alt:before{content:\"\\f884\"}.fa-sort-amount-up:before{content:\"\\f161\"}.fa-sort-amount-up-alt:before{content:\"\\f885\"}.fa-sort-down:before{content:\"\\f0dd\"}.fa-sort-numeric-down:before{content:\"\\f162\"}.fa-sort-numeric-down-alt:before{content:\"\\f886\"}.fa-sort-numeric-up:before{content:\"\\f163\"}.fa-sort-numeric-up-alt:before{content:\"\\f887\"}.fa-sort-up:before{content:\"\\f0de\"}.fa-soundcloud:before{content:\"\\f1be\"}.fa-sourcetree:before{content:\"\\f7d3\"}.fa-spa:before{content:\"\\f5bb\"}.fa-space-shuttle:before{content:\"\\f197\"}.fa-speakap:before{content:\"\\f3f3\"}.fa-speaker-deck:before{content:\"\\f83c\"}.fa-spell-check:before{content:\"\\f891\"}.fa-spider:before{content:\"\\f717\"}.fa-spinner:before{content:\"\\f110\"}.fa-splotch:before{content:\"\\f5bc\"}.fa-spotify:before{content:\"\\f1bc\"}.fa-spray-can:before{content:\"\\f5bd\"}.fa-square:before{content:\"\\f0c8\"}.fa-square-full:before{content:\"\\f45c\"}.fa-square-root-alt:before{content:\"\\f698\"}.fa-squarespace:before{content:\"\\f5be\"}.fa-stack-exchange:before{content:\"\\f18d\"}.fa-stack-overflow:before{content:\"\\f16c\"}.fa-stackpath:before{content:\"\\f842\"}.fa-stamp:before{content:\"\\f5bf\"}.fa-star:before{content:\"\\f005\"}.fa-star-and-crescent:before{content:\"\\f699\"}.fa-star-half:before{content:\"\\f089\"}.fa-star-half-alt:before{content:\"\\f5c0\"}.fa-star-of-david:before{content:\"\\f69a\"}.fa-star-of-life:before{content:\"\\f621\"}.fa-staylinked:before{content:\"\\f3f5\"}.fa-steam:before{content:\"\\f1b6\"}.fa-steam-square:before{content:\"\\f1b7\"}.fa-steam-symbol:before{content:\"\\f3f6\"}.fa-step-backward:before{content:\"\\f048\"}.fa-step-forward:before{content:\"\\f051\"}.fa-stethoscope:before{content:\"\\f0f1\"}.fa-sticker-mule:before{content:\"\\f3f7\"}.fa-sticky-note:before{content:\"\\f249\"}.fa-stop:before{content:\"\\f04d\"}.fa-stop-circle:before{content:\"\\f28d\"}.fa-stopwatch:before{content:\"\\f2f2\"}.fa-stopwatch-20:before{content:\"\\e06f\"}.fa-store:before{content:\"\\f54e\"}.fa-store-alt:before{content:\"\\f54f\"}.fa-store-alt-slash:before{content:\"\\e070\"}.fa-store-slash:before{content:\"\\e071\"}.fa-strava:before{content:\"\\f428\"}.fa-stream:before{content:\"\\f550\"}.fa-street-view:before{content:\"\\f21d\"}.fa-strikethrough:before{content:\"\\f0cc\"}.fa-stripe:before{content:\"\\f429\"}.fa-stripe-s:before{content:\"\\f42a\"}.fa-stroopwafel:before{content:\"\\f551\"}.fa-studiovinari:before{content:\"\\f3f8\"}.fa-stumbleupon:before{content:\"\\f1a4\"}.fa-stumbleupon-circle:before{content:\"\\f1a3\"}.fa-subscript:before{content:\"\\f12c\"}.fa-subway:before{content:\"\\f239\"}.fa-suitcase:before{content:\"\\f0f2\"}.fa-suitcase-rolling:before{content:\"\\f5c1\"}.fa-sun:before{content:\"\\f185\"}.fa-superpowers:before{content:\"\\f2dd\"}.fa-superscript:before{content:\"\\f12b\"}.fa-supple:before{content:\"\\f3f9\"}.fa-surprise:before{content:\"\\f5c2\"}.fa-suse:before{content:\"\\f7d6\"}.fa-swatchbook:before{content:\"\\f5c3\"}.fa-swift:before{content:\"\\f8e1\"}.fa-swimmer:before{content:\"\\f5c4\"}.fa-swimming-pool:before{content:\"\\f5c5\"}.fa-symfony:before{content:\"\\f83d\"}.fa-synagogue:before{content:\"\\f69b\"}.fa-sync:before{content:\"\\f021\"}.fa-sync-alt:before{content:\"\\f2f1\"}.fa-syringe:before{content:\"\\f48e\"}.fa-table:before{content:\"\\f0ce\"}.fa-table-tennis:before{content:\"\\f45d\"}.fa-tablet:before{content:\"\\f10a\"}.fa-tablet-alt:before{content:\"\\f3fa\"}.fa-tablets:before{content:\"\\f490\"}.fa-tachometer-alt:before{content:\"\\f3fd\"}.fa-tag:before{content:\"\\f02b\"}.fa-tags:before{content:\"\\f02c\"}.fa-tape:before{content:\"\\f4db\"}.fa-tasks:before{content:\"\\f0ae\"}.fa-taxi:before{content:\"\\f1ba\"}.fa-teamspeak:before{content:\"\\f4f9\"}.fa-teeth:before{content:\"\\f62e\"}.fa-teeth-open:before{content:\"\\f62f\"}.fa-telegram:before{content:\"\\f2c6\"}.fa-telegram-plane:before{content:\"\\f3fe\"}.fa-temperature-high:before{content:\"\\f769\"}.fa-temperature-low:before{content:\"\\f76b\"}.fa-tencent-weibo:before{content:\"\\f1d5\"}.fa-tenge:before{content:\"\\f7d7\"}.fa-terminal:before{content:\"\\f120\"}.fa-text-height:before{content:\"\\f034\"}.fa-text-width:before{content:\"\\f035\"}.fa-th:before{content:\"\\f00a\"}.fa-th-large:before{content:\"\\f009\"}.fa-th-list:before{content:\"\\f00b\"}.fa-the-red-yeti:before{content:\"\\f69d\"}.fa-theater-masks:before{content:\"\\f630\"}.fa-themeco:before{content:\"\\f5c6\"}.fa-themeisle:before{content:\"\\f2b2\"}.fa-thermometer:before{content:\"\\f491\"}.fa-thermometer-empty:before{content:\"\\f2cb\"}.fa-thermometer-full:before{content:\"\\f2c7\"}.fa-thermometer-half:before{content:\"\\f2c9\"}.fa-thermometer-quarter:before{content:\"\\f2ca\"}.fa-thermometer-three-quarters:before{content:\"\\f2c8\"}.fa-think-peaks:before{content:\"\\f731\"}.fa-thumbs-down:before{content:\"\\f165\"}.fa-thumbs-up:before{content:\"\\f164\"}.fa-thumbtack:before{content:\"\\f08d\"}.fa-ticket-alt:before{content:\"\\f3ff\"}.fa-tiktok:before{content:\"\\e07b\"}.fa-times:before{content:\"\\f00d\"}.fa-times-circle:before{content:\"\\f057\"}.fa-tint:before{content:\"\\f043\"}.fa-tint-slash:before{content:\"\\f5c7\"}.fa-tired:before{content:\"\\f5c8\"}.fa-toggle-off:before{content:\"\\f204\"}.fa-toggle-on:before{content:\"\\f205\"}.fa-toilet:before{content:\"\\f7d8\"}.fa-toilet-paper:before{content:\"\\f71e\"}.fa-toilet-paper-slash:before{content:\"\\e072\"}.fa-toolbox:before{content:\"\\f552\"}.fa-tools:before{content:\"\\f7d9\"}.fa-tooth:before{content:\"\\f5c9\"}.fa-torah:before{content:\"\\f6a0\"}.fa-torii-gate:before{content:\"\\f6a1\"}.fa-tractor:before{content:\"\\f722\"}.fa-trade-federation:before{content:\"\\f513\"}.fa-trademark:before{content:\"\\f25c\"}.fa-traffic-light:before{content:\"\\f637\"}.fa-trailer:before{content:\"\\e041\"}.fa-train:before{content:\"\\f238\"}.fa-tram:before{content:\"\\f7da\"}.fa-transgender:before{content:\"\\f224\"}.fa-transgender-alt:before{content:\"\\f225\"}.fa-trash:before{content:\"\\f1f8\"}.fa-trash-alt:before{content:\"\\f2ed\"}.fa-trash-restore:before{content:\"\\f829\"}.fa-trash-restore-alt:before{content:\"\\f82a\"}.fa-tree:before{content:\"\\f1bb\"}.fa-trello:before{content:\"\\f181\"}.fa-tripadvisor:before{content:\"\\f262\"}.fa-trophy:before{content:\"\\f091\"}.fa-truck:before{content:\"\\f0d1\"}.fa-truck-loading:before{content:\"\\f4de\"}.fa-truck-monster:before{content:\"\\f63b\"}.fa-truck-moving:before{content:\"\\f4df\"}.fa-truck-pickup:before{content:\"\\f63c\"}.fa-tshirt:before{content:\"\\f553\"}.fa-tty:before{content:\"\\f1e4\"}.fa-tumblr:before{content:\"\\f173\"}.fa-tumblr-square:before{content:\"\\f174\"}.fa-tv:before{content:\"\\f26c\"}.fa-twitch:before{content:\"\\f1e8\"}.fa-twitter:before{content:\"\\f099\"}.fa-twitter-square:before{content:\"\\f081\"}.fa-typo3:before{content:\"\\f42b\"}.fa-uber:before{content:\"\\f402\"}.fa-ubuntu:before{content:\"\\f7df\"}.fa-uikit:before{content:\"\\f403\"}.fa-umbraco:before{content:\"\\f8e8\"}.fa-umbrella:before{content:\"\\f0e9\"}.fa-umbrella-beach:before{content:\"\\f5ca\"}.fa-underline:before{content:\"\\f0cd\"}.fa-undo:before{content:\"\\f0e2\"}.fa-undo-alt:before{content:\"\\f2ea\"}.fa-uniregistry:before{content:\"\\f404\"}.fa-unity:before{content:\"\\e049\"}.fa-universal-access:before{content:\"\\f29a\"}.fa-university:before{content:\"\\f19c\"}.fa-unlink:before{content:\"\\f127\"}.fa-unlock:before{content:\"\\f09c\"}.fa-unlock-alt:before{content:\"\\f13e\"}.fa-unsplash:before{content:\"\\e07c\"}.fa-untappd:before{content:\"\\f405\"}.fa-upload:before{content:\"\\f093\"}.fa-ups:before{content:\"\\f7e0\"}.fa-usb:before{content:\"\\f287\"}.fa-user:before{content:\"\\f007\"}.fa-user-alt:before{content:\"\\f406\"}.fa-user-alt-slash:before{content:\"\\f4fa\"}.fa-user-astronaut:before{content:\"\\f4fb\"}.fa-user-check:before{content:\"\\f4fc\"}.fa-user-circle:before{content:\"\\f2bd\"}.fa-user-clock:before{content:\"\\f4fd\"}.fa-user-cog:before{content:\"\\f4fe\"}.fa-user-edit:before{content:\"\\f4ff\"}.fa-user-friends:before{content:\"\\f500\"}.fa-user-graduate:before{content:\"\\f501\"}.fa-user-injured:before{content:\"\\f728\"}.fa-user-lock:before{content:\"\\f502\"}.fa-user-md:before{content:\"\\f0f0\"}.fa-user-minus:before{content:\"\\f503\"}.fa-user-ninja:before{content:\"\\f504\"}.fa-user-nurse:before{content:\"\\f82f\"}.fa-user-plus:before{content:\"\\f234\"}.fa-user-secret:before{content:\"\\f21b\"}.fa-user-shield:before{content:\"\\f505\"}.fa-user-slash:before{content:\"\\f506\"}.fa-user-tag:before{content:\"\\f507\"}.fa-user-tie:before{content:\"\\f508\"}.fa-user-times:before{content:\"\\f235\"}.fa-users:before{content:\"\\f0c0\"}.fa-users-cog:before{content:\"\\f509\"}.fa-users-slash:before{content:\"\\e073\"}.fa-usps:before{content:\"\\f7e1\"}.fa-ussunnah:before{content:\"\\f407\"}.fa-utensil-spoon:before{content:\"\\f2e5\"}.fa-utensils:before{content:\"\\f2e7\"}.fa-vaadin:before{content:\"\\f408\"}.fa-vector-square:before{content:\"\\f5cb\"}.fa-venus:before{content:\"\\f221\"}.fa-venus-double:before{content:\"\\f226\"}.fa-venus-mars:before{content:\"\\f228\"}.fa-viacoin:before{content:\"\\f237\"}.fa-viadeo:before{content:\"\\f2a9\"}.fa-viadeo-square:before{content:\"\\f2aa\"}.fa-vial:before{content:\"\\f492\"}.fa-vials:before{content:\"\\f493\"}.fa-viber:before{content:\"\\f409\"}.fa-video:before{content:\"\\f03d\"}.fa-video-slash:before{content:\"\\f4e2\"}.fa-vihara:before{content:\"\\f6a7\"}.fa-vimeo:before{content:\"\\f40a\"}.fa-vimeo-square:before{content:\"\\f194\"}.fa-vimeo-v:before{content:\"\\f27d\"}.fa-vine:before{content:\"\\f1ca\"}.fa-virus:before{content:\"\\e074\"}.fa-virus-slash:before{content:\"\\e075\"}.fa-viruses:before{content:\"\\e076\"}.fa-vk:before{content:\"\\f189\"}.fa-vnv:before{content:\"\\f40b\"}.fa-voicemail:before{content:\"\\f897\"}.fa-volleyball-ball:before{content:\"\\f45f\"}.fa-volume-down:before{content:\"\\f027\"}.fa-volume-mute:before{content:\"\\f6a9\"}.fa-volume-off:before{content:\"\\f026\"}.fa-volume-up:before{content:\"\\f028\"}.fa-vote-yea:before{content:\"\\f772\"}.fa-vr-cardboard:before{content:\"\\f729\"}.fa-vuejs:before{content:\"\\f41f\"}.fa-walking:before{content:\"\\f554\"}.fa-wallet:before{content:\"\\f555\"}.fa-warehouse:before{content:\"\\f494\"}.fa-water:before{content:\"\\f773\"}.fa-wave-square:before{content:\"\\f83e\"}.fa-waze:before{content:\"\\f83f\"}.fa-weebly:before{content:\"\\f5cc\"}.fa-weibo:before{content:\"\\f18a\"}.fa-weight:before{content:\"\\f496\"}.fa-weight-hanging:before{content:\"\\f5cd\"}.fa-weixin:before{content:\"\\f1d7\"}.fa-whatsapp:before{content:\"\\f232\"}.fa-whatsapp-square:before{content:\"\\f40c\"}.fa-wheelchair:before{content:\"\\f193\"}.fa-whmcs:before{content:\"\\f40d\"}.fa-wifi:before{content:\"\\f1eb\"}.fa-wikipedia-w:before{content:\"\\f266\"}.fa-wind:before{content:\"\\f72e\"}.fa-window-close:before{content:\"\\f410\"}.fa-window-maximize:before{content:\"\\f2d0\"}.fa-window-minimize:before{content:\"\\f2d1\"}.fa-window-restore:before{content:\"\\f2d2\"}.fa-windows:before{content:\"\\f17a\"}.fa-wine-bottle:before{content:\"\\f72f\"}.fa-wine-glass:before{content:\"\\f4e3\"}.fa-wine-glass-alt:before{content:\"\\f5ce\"}.fa-wix:before{content:\"\\f5cf\"}.fa-wizards-of-the-coast:before{content:\"\\f730\"}.fa-wolf-pack-battalion:before{content:\"\\f514\"}.fa-won-sign:before{content:\"\\f159\"}.fa-wordpress:before{content:\"\\f19a\"}.fa-wordpress-simple:before{content:\"\\f411\"}.fa-wpbeginner:before{content:\"\\f297\"}.fa-wpexplorer:before{content:\"\\f2de\"}.fa-wpforms:before{content:\"\\f298\"}.fa-wpressr:before{content:\"\\f3e4\"}.fa-wrench:before{content:\"\\f0ad\"}.fa-x-ray:before{content:\"\\f497\"}.fa-xbox:before{content:\"\\f412\"}.fa-xing:before{content:\"\\f168\"}.fa-xing-square:before{content:\"\\f169\"}.fa-y-combinator:before{content:\"\\f23b\"}.fa-yahoo:before{content:\"\\f19e\"}.fa-yammer:before{content:\"\\f840\"}.fa-yandex:before{content:\"\\f413\"}.fa-yandex-international:before{content:\"\\f414\"}.fa-yarn:before{content:\"\\f7e3\"}.fa-yelp:before{content:\"\\f1e9\"}.fa-yen-sign:before{content:\"\\f157\"}.fa-yin-yang:before{content:\"\\f6ad\"}.fa-yoast:before{content:\"\\f2b1\"}.fa-youtube:before{content:\"\\f167\"}.fa-youtube-square:before{content:\"\\f431\"}.fa-zhihu:before{content:\"\\f63f\"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}#conversejs converse-icon:before,.converse-website converse-icon:before{content:none!important}#conversejs .far:not(converse-icon),.converse-website .far:not(converse-icon){font-family:ConverseFontAwesomeRegular!important;font-weight:400}#conversejs .fa:not(converse-icon),#conversejs .fas:not(converse-icon),.converse-website .fa:not(converse-icon),.converse-website .fas:not(converse-icon){font-family:ConverseFontAwesomeSolid!important;font-weight:900}#conversejs .fab:not(converse-icon),.converse-website .fab:not(converse-icon){font-family:ConverseFontAwesomeBrands}#conversejs .fa:not(converse-icon),#conversejs .fab:not(converse-icon),#conversejs .far:not(converse-icon),#conversejs .fas:not(converse-icon),.converse-website .fa:not(converse-icon),.converse-website .fab:not(converse-icon),.converse-website .far:not(converse-icon),.converse-website .fas:not(converse-icon){display:inline-block;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs .fa-info-circle,.converse-website .fa-info-circle{height:1em}#conversejs,#conversejs-bg,.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--message-avatar-width:36px;--message-avatar-height:36px;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:\"Helvetica\",\"Arial\",sans-serif;--heading-font:'Muli',normal;--branding-font:'Baumans',cursive;--heading-display:block;--heading-color:white;--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}#conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--chat-head-text-color:#AAA;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}body.converse-fullscreen{margin:0;background-color:var(--global-background-color)}#conversejs-bg .converse-brand{display:flex;justify-content:space-between;margin-top:15vh;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:5s;animation-duration:5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media (min-width:768px){#conversejs-bg .converse-brand__padding{flex:0 0 33.33333%;max-width:33.33333%}}@media (min-width:992px){#conversejs-bg .converse-brand__padding{flex:0 0 25%;max-width:25%}}@media (min-width:1200px){#conversejs-bg .converse-brand__padding{flex:0 0 16.66667%;max-width:16.66667%}}#conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media (min-width:768px){#conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.66667%;max-width:66.66667%}}@media (min-width:992px){#conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 75%;max-width:75%}}@media (min-width:1200px){#conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.33333%;max-width:83.33333%}}#conversejs-bg .converse-brand__heading svg{margin-top:.3em}#conversejs-bg .converse-brand__text{color:#fff;font-family:var(--branding-font);font-weight:400;text-align:center;font-size:140%;margin-left:.2em}#conversejs-bg .converse-brand__text .byline{margin:0;font-family:var(--heading-font);font-size:.3em;opacity:.55;margin-bottom:2em;margin-left:-2.7em;word-spacing:5px}#conversejs .subdued,#conversejs-bg .subdued{opacity:.35}#conversejs{bottom:0;height:100%;position:fixed;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);color:var(--text-color);font-family:var(--normal-font);font-size:var(--font-size);direction:ltr;z-index:1031}#conversejs textarea:disabled{background-color:#eee!important}#conversejs .fit-content{width:-webkit-fit-content!important;width:-moz-fit-content!important;width:fit-content!important;max-width:-webkit-fit-content!important;max-width:-moz-fit-content!important;max-width:fit-content!important}#conversejs .nopadding{padding:0!important}#conversejs.converse-overlayed>.row{flex-direction:row-reverse}#conversejs.converse-fullscreen .converse-chatboxes,#conversejs.converse-mobile .converse-chatboxes{width:100vw;left:-15px}#conversejs.converse-overlayed{height:3em}#conversejs.converse-embedded{box-sizing:border-box;bottom:auto;height:100%;position:relative;right:auto;width:100%}#conversejs.converse-embedded *,#conversejs.converse-embedded :after,#conversejs.converse-embedded :before{box-sizing:border-box}#conversejs converse-brand-heading{text-align:center}#conversejs .brand-heading{display:inline-flex;flex-direction:row;align-items:flex-start;font-family:var(--branding-font);color:var(--link-color);margin-bottom:.75em}#conversejs .brand-heading .brand-name-wrapper{display:flex;white-space:nowrap;margin:auto}#conversejs .brand-heading .brand-name{color:var(--link-color);display:flex;flex-direction:column;align-items:center;margin-top:-.25em}#conversejs .brand-heading .brand-name .byline{font-family:var(--heading-font);font-size:.3em;margin-bottom:.75em;margin-left:-2.7em;opacity:.55;word-spacing:5px}#conversejs .brand-heading .brand-subtitle{color:var(--text-color)}#conversejs .brand-heading .brand-name__text{font-size:120%;vertical-align:text-bottom}#conversejs .brand-heading .converse-svg-logo{color:var(--link-color);height:1.5em;margin-right:.25em;margin-bottom:-.25em}#conversejs .brand-heading .converse-svg-logo .cls-1{isolation:isolate}#conversejs .brand-heading .converse-svg-logo .cls-2{opacity:.5;mix-blend-mode:multiply}#conversejs .brand-heading .converse-svg-logo .cls-3{fill:var(--link-color)}#conversejs .brand-heading .converse-svg-logo .cls-4{fill:var(--link-color)}#conversejs .brand-heading--inverse .converse-svg-logo{margin-bottom:0;margin-top:-.2em}#conversejs .brand-heading--inverse .byline{margin:0;font-family:var(--heading-font);font-size:.25em;opacity:.55;margin-left:-7em;word-spacing:5px}#conversejs .dropdown-item{padding:.5rem 1rem}#conversejs .dropdown-item .fa{width:1.25em;margin-right:.75rem}#conversejs .dropdown-item.selected,#conversejs .dropdown-item:active{color:#fff!important;background-color:var(--list-item-open-color)}#conversejs .dropdown-item.selected .fa,#conversejs .dropdown-item:active .fa{color:#fff!important}#conversejs .popover{position:fixed}#conversejs .converse-chatboxes{z-index:1031;position:fixed;bottom:0;right:0}#conversejs ::-moz-placeholder{color:var(--subdued-color)}#conversejs :-ms-input-placeholder{color:var(--subdued-color)}#conversejs ::-ms-input-placeholder{color:var(--subdued-color)}#conversejs ::placeholder{color:var(--subdued-color)}#conversejs ::-moz-selection{background-color:var(--highlight-color)}#conversejs ::selection{background-color:var(--highlight-color)}#conversejs ::-moz-selection{background-color:var(--highlight-color)}@media screen and (max-width:480px){#conversejs{margin:0;right:10px;left:10px;bottom:5px}}@media screen and (max-height:450px){#conversejs{margin:0;right:10px;left:10px;bottom:5px}}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs button,#conversejs input[type=button],#conversejs input[type=password],#conversejs input[type=submit],#conversejs input[type=text],#conversejs textarea{font-size:var(--font-size);min-height:0}#conversejs strong{font-weight:700}#conversejs em{font-style:italic}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0}#conversejs a{cursor:pointer}#conversejs a,#conversejs a:not([href]):not([tabindex]),#conversejs a:visited{text-decoration:none;color:var(--link-color);text-shadow:none;cursor:pointer}#conversejs a:hover,#conversejs a:not([href]):not([tabindex]):hover,#conversejs a:visited:hover{color:var(--link-hover-color);text-decoration:none;text-shadow:none}#conversejs a.fa,#conversejs a.far,#conversejs a.fas,#conversejs a:not([href]):not([tabindex]).fa,#conversejs a:not([href]):not([tabindex]).far,#conversejs a:not([href]):not([tabindex]).fas,#conversejs a:visited.fa,#conversejs a:visited.far,#conversejs a:visited.fas{color:var(--subdued-color)}#conversejs a.fa:hover,#conversejs a.far:hover,#conversejs a.fas:hover,#conversejs a:not([href]):not([tabindex]).fa:hover,#conversejs a:not([href]):not([tabindex]).far:hover,#conversejs a:not([href]):not([tabindex]).fas:hover,#conversejs a:visited.fa:hover,#conversejs a:visited.far:hover,#conversejs a:visited.fas:hover{color:var(--gray-color)}#conversejs svg{border-radius:var(--chatbox-border-radius)}#conversejs .fa,#conversejs .far,#conversejs .fas{color:var(--subdued-color)}#conversejs .fa:hover,#conversejs .far:hover,#conversejs .fas:hover{color:var(--gray-color)}#conversejs q{quotes:\"“\" \"”\" \"‘\" \"’\"}#conversejs q.reason{display:inline}#conversejs q:before{content:open-quote}#conversejs q:after{content:close-quote}#conversejs .helptext{font-size:var(--font-size-tiny);color:var(--text-color-lighten-15-percent)}#conversejs .selected{color:var(--link-color)!important}#conversejs .circle{border-radius:50%}#conversejs .badge{line-height:1;font-weight:400;font-size:90%}#conversejs .btn{font-weight:400;color:#fff}#conversejs .btn .fa,#conversejs .btn .far,#conversejs .btn .fas{color:#fff;margin-right:.5em}#conversejs .btn .fa.only-icon,#conversejs .btn .far.only-icon,#conversejs .btn .fas.only-icon{margin-right:0}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}@keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}#conversejs .fade-in{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs .visible{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs .hidden{opacity:0!important;display:none!important}#conversejs .fade-out{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}#conversejs .collapsed{height:0!important;overflow:hidden!important;padding:0!important}#conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}#conversejs .spinner{-webkit-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;width:1em;display:block;text-align:center;padding:.5em 0;font-size:24px}#conversejs .left{float:left}#conversejs .right{float:right}#conversejs .centered{text-align:center;display:block;margin:auto}#conversejs .hor_centered{width:100%;text-align:center;display:block;margin:0 auto;clear:both}#conversejs .error{color:var(--error-color)!important}#conversejs .info{color:var(--info-color)}#conversejs .reg-feedback{font-size:85%;margin-bottom:1em}#conversejs #converse-login .conn-feedback,#conversejs .reg-feedback{display:block;text-align:center;width:100%}#conversejs .avatar{border-radius:var(--avatar-border-radius);border:var(--avatar-border);background-color:var(--avatar-background-color)}#conversejs .avatar-autocomplete{margin-right:.5em;vertical-align:middle}#conversejs .activated{display:block!important}#conversejs .form-help{color:var(--subdued-color);font-size:90%}#conversejs .form-control--labeled{margin-top:.5em}#conversejs .nav-pills .nav-link.active,#conversejs .nav-pills .show>.nav-link{background-color:var(--primary-color)}#conversejs .list-group-item.active{background-color:var(--primary-color);border-color:var(--primary-color-dark)}#conversejs .badge{text-shadow:none;color:#fff}#conversejs .badge-light{color:var(--text-color)}#conversejs .badge-primary,#conversejs .btn-primary,#conversejs .button-primary{background-color:var(--primary-color);border-color:transparent}#conversejs .badge-primary:active,#conversejs .badge-primary:focus,#conversejs .badge-primary:hover,#conversejs .btn-primary:active,#conversejs .btn-primary:focus,#conversejs .btn-primary:hover,#conversejs .button-primary:active,#conversejs .button-primary:focus,#conversejs .button-primary:hover{background-color:var(--primary-color-dark)!important;border-color:transparent!important}#conversejs .btn--transparent{background:0 0;border:none}#conversejs .btn-circle{width:30px;height:30px;text-align:center;padding:.5em 0;font-size:var(--font-size-small);line-height:1.428571429;border-radius:50%}#conversejs .btn.fa{color:#fff!important}#conversejs .badge-groupchat{background-color:var(--chatroom-badge-color);border-color:transparent}#conversejs .badge-groupchat:hover{background-color:var(--chatroom-badge-hover-color);border-color:transparent}#conversejs .badge-groupchat.active{background-color:var(--chatroom-badge-hover-color)!important;border-color:transparent!important}#conversejs .badge-info,#conversejs .btn-info{background-color:var(--primary-color);border-color:var(--primary-color)}#conversejs .badge-info:hover,#conversejs .btn-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}#conversejs .badge-secondary,#conversejs .btn-secondary,#conversejs .button-cancel{color:#fff;background-color:var(--secondary-color);border-color:var(--secondary-color)}#conversejs .badge-secondary:hover,#conversejs .btn-secondary:hover,#conversejs .button-cancel:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}#conversejs .btn-warning{color:#fff;background-color:var(--warning-color);border-color:var(--warning-color)}#conversejs .btn-warning:hover{color:#fff;background-color:var(--warning-color-dark);border-color:var(--warning-color-dark)}#conversejs .btn-danger{color:#fff;background-color:var(--danger-color);border-color:var(--danger-color)!important}#conversejs .btn-danger:hover{background-color:var(--danger-color-dark);border-color:var(--danger-color-dark)}@media screen and (max-width:575px){body .converse-brand{font-size:3.75em}#conversejs:not(.converse-embedded) .chatbox .chat-body{border-radius:var(--chatbox-border-radius)}#conversejs:not(.converse-embedded) .flyout{border-radius:var(--chatbox-border-radius)}}@media screen and (min-width:576px){#conversejs .offset-sm-2{margin-left:16.666667%}}@media screen and (min-width:768px){#conversejs .offset-md-2{margin-left:16.666667%}#conversejs .offset-md-3{margin-left:25%}}@media screen and (min-width:992px){#conversejs .offset-lg-2{margin-left:16.666667%}#conversejs .offset-lg-3{margin-left:25%}}@media screen and (min-width:1200px){#conversejs .offset-xl-2{margin-left:16.666667%}}@media screen and (max-height:450px){#conversejs{left:0}}#conversejs .btn--small{font-size:80%;font-weight:400}#conversejs form .hidden-username{opacity:0!important;height:0!important;padding:0!important}#conversejs form .error-feedback{margin-bottom:.5em}#conversejs form .form-check-label{margin-top:.3rem}#conversejs form .form-control::-moz-placeholder{color:var(--subdued-color)}#conversejs form .form-control:-ms-input-placeholder{color:var(--subdued-color)}#conversejs form .form-control::-ms-input-placeholder{color:var(--subdued-color)}#conversejs form .form-control::placeholder{color:var(--subdued-color)}#conversejs form .clear-input{margin-top:.5em;margin-bottom:.5em;position:absolute;right:.2em;cursor:pointer;font-size:var(--font-size)}#conversejs form#converse-login,#conversejs form#converse-register{background:var(--controlbox-pane-background-color)}#conversejs form#converse-login legend,#conversejs form#converse-register legend{width:100%;text-align:center;margin:0 auto .5em auto}#conversejs form#converse-login fieldset.buttons,#conversejs form#converse-register fieldset.buttons{text-align:center}#conversejs form#converse-login .login-anon,#conversejs form#converse-register .login-anon{height:auto;white-space:normal}#conversejs form#converse-login .save-submit,#conversejs form#converse-register .save-submit{color:var(--save-button-color)}#conversejs form#converse-login .form-url,#conversejs form#converse-register .form-url{display:block;font-weight:400;margin:1em 0}#conversejs form.converse-form{padding:1.2rem}#conversejs form.converse-form legend{color:var(--text-color);font-size:125%;margin-bottom:1.5em}#conversejs form.converse-form input[type=number],#conversejs form.converse-form input[type=password],#conversejs form.converse-form input[type=text],#conversejs form.converse-form select{min-width:50%}#conversejs form.converse-form input[type=button],#conversejs form.converse-form input[type=number],#conversejs form.converse-form input[type=password],#conversejs form.converse-form input[type=submit],#conversejs form.converse-form input[type=text]{padding:.5em}#conversejs form.converse-form input[type=button],#conversejs form.converse-form input[type=submit]{padding-left:1em;padding-right:1em;border:none}#conversejs form.converse-form input.error{border:1px solid var(--error-color);color:var(--text-color)}#conversejs form.converse-form .text-muted{color:var(--subdued-color)!important;font-size:85%;padding-top:.5em}#conversejs form.converse-form .text-muted a{color:var(--link-color-lighten-10-percent)}#conversejs form.converse-form .text-muted.error{color:var(--error-color)}#conversejs form.converse-form--modal{padding-bottom:0}#conversejs form.converse-centered-form{min-height:66%;text-align:center}#conversejs form.converse-centered-form input{max-width:30em;margin:auto}#conversejs .send-button{border-radius:0;bottom:var(--send-button-bottom);color:var(--inverse-link-color)}#conversejs .chatbox .send-button{background-color:var(--chat-head-color)}#conversejs .chatroom .send-button{background-color:var(--muc-toolbar-btn-color)}#conversejs .chat-toolbar .toolbar-buttons{width:100%;display:inline-block}#conversejs .chat-toolbar .toolbar-buttons .message-limit{padding:.5em;font-weight:700}#conversejs .chat-toolbar .unverified,#conversejs .chat-toolbar .unverified a{color:#cf5300}#conversejs .chat-toolbar .private,#conversejs .chat-toolbar .private a{color:#4b7003}#conversejs .chat-toolbar li{cursor:pointer;display:inline-block;list-style:none;padding:0 .5em}#conversejs .chat-toolbar li:hover{cursor:pointer}#conversejs .chat-toolbar li .toolbar-menu{background-color:#fff;bottom:1.7rem;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);height:auto;margin-bottom:0;min-width:21rem;position:absolute;right:0;top:auto;z-index:1000}#conversejs .chat-toolbar li .toolbar-menu.otr-menu{left:-6em;min-width:15rem}#conversejs .chat-toolbar li .toolbar-menu.otr-menu.show{display:flex;flex-direction:column}#conversejs .chat-toolbar li .toolbar-menu a{color:var(--link-color)}#conversejs .chat-toolbar li.toggle-otr ul{z-index:99}#conversejs .chat-toolbar li.toggle-otr ul li{display:block;padding:7px}#conversejs .chat-toolbar li.toggle-otr ul li:hover{background-color:var(--highlight-color)}#conversejs .chat-toolbar li.toggle-otr ul li a{display:block}#conversejs converse-chat-toolbar{background-color:#fff;box-sizing:border-box;display:flex;justify-content:space-between;margin:0;width:100%}#conversejs converse-chat-toolbar .fa,#conversejs converse-chat-toolbar .fa:hover,#conversejs converse-chat-toolbar .far,#conversejs converse-chat-toolbar .far:hover,#conversejs converse-chat-toolbar .fas,#conversejs converse-chat-toolbar .fas:hover{color:var(--chat-head-color);font-size:var(--font-size-large)}#conversejs converse-chat-toolbar .fa svg,#conversejs converse-chat-toolbar .fa:hover svg,#conversejs converse-chat-toolbar .far svg,#conversejs converse-chat-toolbar .far:hover svg,#conversejs converse-chat-toolbar .fas svg,#conversejs converse-chat-toolbar .fas:hover svg{fill:var(--chat-head-color)}#conversejs converse-chat-toolbar .unencrypted,#conversejs converse-chat-toolbar .unencrypted a{color:var(--text-color)}#conversejs converse-chat-toolbar .unencrypted .toolbar-menu a,#conversejs converse-chat-toolbar .unencrypted a .toolbar-menu a{color:var(--link-color)}#conversejs converse-chat-toolbar button{margin-top:.4em;border:1px transparent solid;background-color:transparent}#conversejs converse-chat-toolbar button.send-button{padding-top:.2em;padding-bottom:.2em;margin:0;margin-top:-1px}#conversejs .chatbox converse-chat-toolbar{border-top:var(--chatbox-message-input-border-top);color:var(--chat-toolbar-btn-color);background-color:#fff}#conversejs .chatbox converse-chat-toolbar .fa,#conversejs .chatbox converse-chat-toolbar .fa:hover,#conversejs .chatbox converse-chat-toolbar .far,#conversejs .chatbox converse-chat-toolbar .far:hover,#conversejs .chatbox converse-chat-toolbar .fas,#conversejs .chatbox converse-chat-toolbar .fas:hover{color:var(--chat-toolbar-btn-color)}#conversejs .chatbox converse-chat-toolbar button:focus{outline-color:var(--chat-toolbar-btn-color)!important}#conversejs .chatbox converse-chat-toolbar button:disabled .fa{color:var(--chat-toolbar-btn-disabled-color)}#conversejs .chatbox converse-chat-toolbar button:disabled .fa:hover{color:var(--chat-toolbar-btn-disabled-color)}#conversejs .chatbox converse-chat-toolbar button:disabled .fa svg,#conversejs .chatbox converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--chat-toolbar-btn-disabled-color)}#conversejs .chatroom converse-chat-toolbar{border-top:var(--chatroom-message-input-border-top);color:var(--muc-toolbar-btn-color)}#conversejs .chatroom converse-chat-toolbar .fa,#conversejs .chatroom converse-chat-toolbar .fa:hover,#conversejs .chatroom converse-chat-toolbar .far,#conversejs .chatroom converse-chat-toolbar .far:hover,#conversejs .chatroom converse-chat-toolbar .fas,#conversejs .chatroom converse-chat-toolbar .fas:hover{color:var(--muc-toolbar-btn-color);font-size:var(--font-size-large)}#conversejs .chatroom converse-chat-toolbar .fa svg,#conversejs .chatroom converse-chat-toolbar .fa:hover svg,#conversejs .chatroom converse-chat-toolbar .far svg,#conversejs .chatroom converse-chat-toolbar .far:hover svg,#conversejs .chatroom converse-chat-toolbar .fas svg,#conversejs .chatroom converse-chat-toolbar .fas:hover svg{fill:var(--muc-toolbar-btn-color)}#conversejs .chatroom converse-chat-toolbar button:focus{outline-color:var(--muc-toolbar-btn-color)!important}#conversejs .chatroom converse-chat-toolbar button:disabled .fa{color:var(--muc-toolbar-btn-disabled-color)}#conversejs .chatroom converse-chat-toolbar button:disabled .fa:hover{color:var(--muc-toolbar-btn-disabled-color)}#conversejs .chatroom converse-chat-toolbar button:disabled .fa svg,#conversejs .chatroom converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--muc-toolbar-btn-disabled-color)}#conversejs.converse-overlayed .chat-toolbar li .toolbar-menu{min-width:235px}#conversejs.converse-overlayed .chatroom .chat-toolbar li .toolbar-menu{min-width:280px}#conversejs .chatbox-navback{display:none}#conversejs .flyout{position:absolute}@media screen and (max-height:450px){#conversejs .flyout{border-radius:0}}@media screen and (max-width:480px){#conversejs .flyout{border-radius:0}}@media screen and (max-height:450px){#conversejs .flyout{bottom:0}}@media screen and (max-width:480px){#conversejs .flyout{bottom:0}}#conversejs .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}#conversejs .chatbox-btn:active{position:relative;top:1px}#conversejs .chat-head{display:flex;flex-direction:row;color:#fff;font-size:100%;margin:0;padding:0;position:relative}#conversejs .chat-head.chat-head-chatbox{background-color:var(--chat-head-color)}#conversejs .chat-head .avatar{margin-right:.5em}#conversejs .chat-head .chat-head__desc{color:var(--chat-head-color-lighten-50-percent);font-size:var(--font-size-small);margin:0;overflow:hidden;padding:.5rem 1rem .5rem 1rem;text-overflow:ellipsis;width:100%;max-height:5em}#conversejs .chat-head .chatbox-title{padding:.75rem 1rem 0 1rem;display:flex;flex-direction:row;justify-content:space-between;width:100%}#conversejs .chat-head .chatbox-title--no-desc{padding:.75rem 1rem}#conversejs .chat-head .chatbox-title--row{display:flex;flex-direction:row;overflow:hidden}#conversejs .chat-head .chatbox-title__text{overflow:hidden;text-overflow:ellipsis}#conversejs .chat-head .chatbox-title__buttons{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;padding:0}#conversejs .chat-head a.chatbox-btn.fa,#conversejs .chat-head a.chatbox-btn.far,#conversejs .chat-head a.chatbox-btn.fas,#conversejs .chat-head a:hover.chatbox-btn.fa,#conversejs .chat-head a:hover.chatbox-btn.far,#conversejs .chat-head a:hover.chatbox-btn.fas,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.far,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fas,#conversejs .chat-head a:visited.chatbox-btn.fa,#conversejs .chat-head a:visited.chatbox-btn.far,#conversejs .chat-head a:visited.chatbox-btn.fas{color:#fff}#conversejs .chat-head a.chatbox-btn.fa.button-on:before,#conversejs .chat-head a.chatbox-btn.far.button-on:before,#conversejs .chat-head a.chatbox-btn.fas.button-on:before,#conversejs .chat-head a:hover.chatbox-btn.fa.button-on:before,#conversejs .chat-head a:hover.chatbox-btn.far.button-on:before,#conversejs .chat-head a:hover.chatbox-btn.fas.button-on:before,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.far.button-on:before,#conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fas.button-on:before,#conversejs .chat-head a:visited.chatbox-btn.fa.button-on:before,#conversejs .chat-head a:visited.chatbox-btn.far.button-on:before,#conversejs .chat-head a:visited.chatbox-btn.fas.button-on:before{padding:.2em;background-color:var(--chat-head-text-color);color:var(--chat-head-color)}#conversejs .chat-head .chatbox-btn{color:#fff}#conversejs .chat-head .chatbox-btn.fa,#conversejs .chat-head .chatbox-btn.far,#conversejs .chat-head .chatbox-btn.fas{color:#fff}#conversejs .chat-head .chatbox-btn:active{position:relative;top:1px}#conversejs .chat-head .chatbox-btn.button-on:before{border-radius:5%;background-color:var(--chat-head-text-color);color:var(--chat-head-color)}#conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height:450px){#conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width:480px){#conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}#conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height:450px){#conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){#conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}#conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}#conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}#conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-head-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0}@media screen and (max-height:450px){#conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width:480px){#conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}#conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}#conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}#conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}#conversejs .chatbox .chat-content converse-chat-content{display:flex;flex-direction:column;height:100%;justify-content:space-between}#conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}#conversejs .chatbox .chat-content .chat-content__help{border-top:1px solid var(--chat-head-color);max-height:100%}#conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}#conversejs .chatbox .chat-content .chat-content__help converse-chat-help{height:100%;overflow-y:auto;display:block;padding:.5em 0}#conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}#conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}#conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}#conversejs .chatbox .chat-content .chat-content__notifications:before{content:\" \"}#conversejs .chatbox .chat-content video{width:100%}#conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}#conversejs .chatbox .chat-content-sendbutton{height:calc(100% - (var(--chat-textarea-height) + var(--send-button-height) + 2 * var(--send-button-margin)))}#conversejs .chatbox .dropdown{background-color:var(--light-background-color)}#conversejs .chatbox .dropdown dd{margin:0;padding:0;position:relative}#conversejs .chatbox .sendXMPPMessage{-moz-background-clip:padding;-webkit-background-clip:padding-box;border-bottom-radius:var(--chatbox-border-radius);background-clip:padding-box;background-color:#fff;border:0;margin:0;padding:0}@media screen and (max-height:450px){#conversejs .chatbox .sendXMPPMessage{width:100%}}@media screen and (max-width:480px){#conversejs .chatbox .sendXMPPMessage{width:100%}}#conversejs .chatbox .sendXMPPMessage .suggestion-box__results:after{display:none}#conversejs .chatbox .sendXMPPMessage .spoiler-hint{width:100%}#conversejs .chatbox .sendXMPPMessage .chat-textarea:active,#conversejs .chatbox .sendXMPPMessage .chat-textarea:focus,#conversejs .chatbox .sendXMPPMessage input:active,#conversejs .chatbox .sendXMPPMessage input:focus{outline-color:var(--chat-head-color)}#conversejs .chatbox .sendXMPPMessage .chat-textarea.correcting,#conversejs .chatbox .sendXMPPMessage input.correcting{background-color:var(--chat-correcting-color)}#conversejs .chatbox .sendXMPPMessage .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);border-top-left-radius:0;border-top-right-radius:0;border-bottom-radius:var(--chatbox-border-radius);padding-left:.5em;padding-right:4.5em;padding-top:.5em;padding-bottom:.5em;width:100%;border:none;min-height:var(--chat-textarea-height);margin-bottom:-4px;resize:none}#conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler{height:42px}#conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}#conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}#conversejs .chatbox .dragresize-left,#conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}#conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}#conversejs.converse-embedded .controlbox-head,#conversejs.converse-overlayed .controlbox-head{padding:.5em}#conversejs.converse-embedded .chat-head,#conversejs.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}#conversejs.converse-embedded .chatbox,#conversejs.converse-overlayed .chatbox{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}#conversejs.converse-embedded .chatbox .box-flyout,#conversejs.converse-overlayed .chatbox .box-flyout{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}#conversejs.converse-overlayed .box-flyout,#conversejs.converse-overlayed .chat-head{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius)}@media screen and (max-height:450px){#conversejs.converse-overlayed .box-flyout,#conversejs.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}@media screen and (max-width:480px){#conversejs.converse-overlayed .box-flyout,#conversejs.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}#conversejs.converse-overlayed .flyout{bottom:var(--overlayed-chatbox-hover-height)}#conversejs.converse-overlayed .box-flyout{height:var(--overlayed-chat-height);min-height:calc(var(--overlayed-chat-height)/ 2)}#conversejs.converse-overlayed .chat-head{min-height:var(--overlayed-chat-head-height)}#conversejs.converse-overlayed .minimized-chats-flyout .chat-head{cursor:default}#conversejs.converse-overlayed .chat-textarea{max-height:var(--overlayed-max-chat-textarea-height)}#conversejs.converse-overlayed .chatbox .chat-body{height:calc(100% - var(--overlayed-chat-head-height))}#conversejs.converse-overlayed .chatbox .chatbox-title{padding:.5rem .75rem 0 .75rem}#conversejs.converse-overlayed .chatbox .chatbox-title--no-desc{padding:.5rem .75rem}#conversejs.converse-overlayed .chatbox converse-dropdown .btn--standalone{padding:0 .2em;margin:0 0 0 .5em}@media (max-width:767.98px){#conversejs.converse-overlayed>.row{flex-direction:column}#conversejs.converse-overlayed>.row.no-gutters{margin:-1em}}#conversejs.converse-embedded .flyout,#conversejs.converse-fullscreen .flyout{border-radius:0;border:none;bottom:0}#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{margin:0;position:relative;width:100%;padding-right:15px;padding-left:15px}#conversejs.converse-embedded .chatbox .box-flyout,#conversejs.converse-fullscreen .chatbox .box-flyout{box-shadow:none;overflow:hidden}@media (min-width:768px){#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{flex:0 0 66.66667%;max-width:66.66667%}}@media (min-width:992px){#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{flex:0 0 75%;max-width:75%}}@media (min-width:1200px){#conversejs.converse-embedded .chatbox,#conversejs.converse-fullscreen .chatbox{flex:0 0 83.33333%;max-width:83.33333%}}#conversejs.converse-embedded.converse-singleton .flyout,#conversejs.converse-fullscreen.converse-singleton .flyout{border:none!important}#conversejs.converse-embedded.converse-singleton .chat-head,#conversejs.converse-fullscreen.converse-singleton .chat-head{padding:.5em}#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{margin:0;position:relative;width:100%;padding-right:15px;padding-left:15px}@media (min-width:768px){#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media (min-width:992px){#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media (min-width:1200px){#conversejs.converse-embedded.converse-singleton .chatbox,#conversejs.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}#conversejs.converse-embedded .chat-head{font-size:var(--font-size-huge)}#conversejs.converse-embedded .converse-chatboxes{z-index:1031;position:inherit;flex-wrap:nowrap;bottom:auto;height:100%;width:100%;margin-left:-15px}#conversejs.converse-embedded .chatbox .box-flyout{bottom:0;height:100%;min-width:auto;width:100%}#conversejs.converse-embedded .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}#conversejs.converse-fullscreen .chatbox-btn{font-size:var(--fullpage-chatbox-button-size);margin:0 .3em}#conversejs.converse-fullscreen .chat-head{font-size:var(--font-size-huge)}#conversejs.converse-fullscreen .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}#conversejs.converse-fullscreen .chatbox .box-flyout{box-shadow:none;height:var(--fullpage-chat-height);min-height:calc(var(--fullpage-chat-height)/ 2);width:var(--fullpage-chat-width);overflow:hidden}#conversejs.converse-fullscreen .chatbox .chat-body{height:inherit;overflow:hidden;background-color:var(--chat-head-color)}#conversejs.converse-fullscreen .chatbox .chat-title{font-size:var(--font-size-huge);line-height:var(--line-height-huge)}#conversejs.converse-fullscreen .chatbox .sendXMPPMessage ul{width:100%}@media (max-width:767.98px){#conversejs:not(.converse-embedded)>.row{flex-direction:row-reverse}#conversejs:not(.converse-embedded) #converse-login-panel .converse-form{padding:3em 2em 3em}#conversejs:not(.converse-embedded) .chatbox{width:calc(100% - 50px)}#conversejs:not(.converse-embedded) .chatbox .row .box-flyout{left:50px;bottom:0;height:var(--fullpage-chat-height);box-shadow:none}#conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback,#conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback,#conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback{margin:auto 0;margin-right:1em;display:flex}#conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,#conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,#conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before{color:#fff}}#conversejs .oauth-providers{text-align:center}#conversejs .oauth-providers .oauth-provider{margin:1em 0}#conversejs .oauth-providers .oauth-provider .oauth-login{margin-left:0;color:var(--link-color);font-size:var(--font-size-large)}#conversejs .oauth-providers .oauth-provider .oauth-login:hover{color:var(--link-hover-color)}#conversejs .oauth-providers .oauth-provider .oauth-login i{color:var(--link-color);font-size:var(--font-size-huge);margin-right:.5em}#conversejs .set-xmpp-status .chat-status--online,#conversejs .xmpp-status .chat-status--online{color:var(--chat-status-online)}#conversejs .set-xmpp-status .chat-status--busy,#conversejs .xmpp-status .chat-status--busy{color:var(--chat-status-busy)}#conversejs .set-xmpp-status .chat-status--away,#conversejs .xmpp-status .chat-status--away{color:var(--chat-status-away)}#conversejs .set-xmpp-status .fa-times-circle,#conversejs .set-xmpp-status .far.fa-circle,#conversejs .xmpp-status .fa-times-circle,#conversejs .xmpp-status .far.fa-circle{color:var(--subdued-color)}#conversejs .set-xmpp-status .chat-status{padding-right:.5em}#conversejs .room-info{font-size:var(--font-size-small);font-style:normal;font-weight:400}#conversejs .room-info li.room-info{display:block;margin-left:5px}#conversejs .room-info p.room-info{line-height:var(--line-height);margin:0;display:block;white-space:normal}#conversejs div.room-info{padding:.3em 0;clear:left;width:100%}#conversejs #controlbox{order:-1;color:var(--controlbox-text-color);margin-right:calc(3 * var(--chat-gutter))}#conversejs #controlbox converse-brand-heading{width:100%;display:block}#conversejs #controlbox .brand-name-wrapper{font-size:200%}#conversejs #controlbox .brand-name-wrapper--fullscreen{font-size:100%}#conversejs #controlbox .open-rooms-toggle,#conversejs #controlbox .open-rooms-toggle .fa{color:var(--groupchats-header-color)!important}#conversejs #controlbox .open-rooms-toggle .fa:hover,#conversejs #controlbox .open-rooms-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}#conversejs #controlbox .box-flyout{background-color:var(--controlbox-pane-background-color)}#conversejs #controlbox.logged-out .box-flyout .controlbox-pane{overflow-y:auto}#conversejs #controlbox form.search-xmpp-contact{margin:0;padding-left:5px;padding:0 0 5px 5px}#conversejs #controlbox form.search-xmpp-contact input{width:8em}#conversejs #controlbox .msgs-indicator{margin-right:.5em}#conversejs #controlbox a.subscribe-to-user{padding-left:2em;font-weight:700}#conversejs #controlbox #converse-register{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-timing-function:ease;animation-timing-function:ease;background-color:var(--controlbox-pane-background-color)}#conversejs #controlbox #converse-register .title{font-weight:700}#conversejs #controlbox #converse-register .info{color:green;font-size:90%;margin:1.5em 0}#conversejs #controlbox #converse-register .form-errors{color:var(--error-color);margin:1em 0}#conversejs #controlbox #converse-register .provider-title{font-size:var(--font-size-huge);margin:0}#conversejs #controlbox #converse-register .provider-score{width:178px;margin-bottom:8px}#conversejs #controlbox #converse-register .form-help .url{font-weight:700;color:var(--link-color)}#conversejs #controlbox #converse-register .input-group{display:table;margin:auto;width:100%}#conversejs #controlbox #converse-register .input-group span{overflow-x:hidden;text-overflow:ellipsis;max-width:110px}#conversejs #controlbox #converse-register .input-group input[name=username],#conversejs #controlbox #converse-register .input-group span{display:table-cell;text-align:left}#conversejs #controlbox #converse-register .instructions{color:gray;font-size:85%}#conversejs #controlbox #converse-register .instructions:hover{color:var(--controlbox-text-color)}#conversejs #controlbox .conn-feedback{color:var(--controlbox-head-color)}#conversejs #controlbox .conn-feedback.error{color:var(--error-color)}#conversejs #controlbox .conn-feedback p{padding-bottom:1em}#conversejs #controlbox .conn-feedback p.feedback-subject.error{font-weight:700}#conversejs #controlbox #converse-login-panel,#conversejs #controlbox #converse-register-panel{padding-top:0;padding-bottom:0}#conversejs #controlbox #converse-login-panel{flex-direction:row}#conversejs #controlbox .toggle-register-login{font-weight:700}#conversejs #controlbox .controlbox-pane .userinfo{padding-bottom:1em}#conversejs #controlbox .controlbox-pane .userinfo .username{margin-left:.5em;overflow:hidden;text-overflow:ellipsis}#conversejs #controlbox .controlbox-pane .userinfo .profile{margin-bottom:.75em}#conversejs #controlbox #chatrooms{padding:0}#conversejs #controlbox #chatrooms .add-chatroom{margin:0;padding:0}#conversejs #controlbox #chatrooms .add-chatroom input[type=button],#conversejs #controlbox #chatrooms .add-chatroom input[type=submit],#conversejs #controlbox #chatrooms .add-chatroom input[type=text]{width:100%}#conversejs #controlbox .controlbox-section .controlbox-heading{font-family:var(--heading-font);color:var(--controlbox-heading-color);font-weight:var(--controlbox-heading-font-weight);padding:0;font-size:1.1em;line-height:1.1em;text-transform:uppercase}#conversejs #controlbox .controlbox-section .controlbox-heading--groupchats{color:var(--groupchats-header-color)}#conversejs #controlbox .controlbox-section .controlbox-heading--contacts{color:var(--chat-head-color-dark)}#conversejs #controlbox .controlbox-section .controlbox-heading--headline{color:var(--headline-head-color)}#conversejs #controlbox .controlbox-section .controlbox-heading__btn{cursor:pointer;font-size:1em;padding:0;margin:var(--controlbox-heading-top-margin) 0 var(--inline-action-margin) 0;min-width:25px;text-align:center}#conversejs #controlbox .controlbox-section .controlbox-heading__btn.fa-vcard{margin-top:1em}#conversejs #controlbox .dropdown a{width:143px;display:inline-block}#conversejs #controlbox .dropdown li{list-style:none;padding-left:0}#conversejs #controlbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;width:100%;z-index:21;background-color:var(--light-background-color)}#conversejs #controlbox .dropdown dd ul li:hover{background-color:var(--highlight-color)}#conversejs #controlbox .dropdown dd.search-xmpp{height:0}#conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container{position:absolute;z-index:22}#conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container form{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4);background-color:#fff}#conversejs #controlbox .dropdown dd.search-xmpp li:hover{background-color:var(--light-background-color)}#conversejs #controlbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}#conversejs #controlbox .controlbox-panes{background-color:var(--controlbox-pane-background-color);border-right:.2143rem solid var(--panel-divider-color);height:100%;overflow-y:auto}#conversejs #controlbox .controlbox-subtitle{font-size:90%;padding:.5em;text-align:right}#conversejs #controlbox .controlbox-pane{background-color:var(--controlbox-pane-background-color);border:0;font-size:var(--font-size);left:0;text-align:left;overflow-x:hidden;padding:0 0 1em 0}#conversejs #controlbox .controlbox-pane .controlbox-padded{padding-left:1em;padding-right:1em;align-items:center;line-height:normal}#conversejs #controlbox .controlbox-pane .controlbox-padded .change-status{min-width:25px;text-align:center}#conversejs #controlbox .controlbox-pane .add-converse-contact{margin:0 0 .75em 0}#conversejs #controlbox .controlbox-pane .chatbox-btn{margin:0}#conversejs #controlbox .controlbox-pane .switch-form{text-align:center;padding:2em 0}#conversejs #controlbox .controlbox-pane .switch-form p{margin-top:.5em}#conversejs #controlbox .controlbox-pane dd{margin-left:0;margin-bottom:0}#conversejs #controlbox .controlbox-pane dd.odd{background-color:#dceac5}#conversejs #controlbox .add-xmpp-contact{padding:1em .5em}#conversejs #controlbox .add-xmpp-contact input{margin:0 0 1rem;width:100%}#conversejs #controlbox .add-xmpp-contact button{width:100%}#conversejs.converse-overlayed .toggle-controlbox{order:-1;text-align:center;background-color:var(--link-color);border-top-left-radius:var(--button-border-radius);border-top-right-radius:var(--button-border-radius);color:#0a0a0a;float:right;height:100%;margin:0 var(--chat-gutter);padding:1em}#conversejs.converse-overlayed .toggle-controlbox span{color:var(--inverse-link-color)}#conversejs.converse-overlayed #controlbox{min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}#conversejs.converse-overlayed #controlbox .box-flyout{min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}#conversejs.converse-overlayed #controlbox .login-trusted{white-space:nowrap;font-size:90%}#conversejs.converse-overlayed #controlbox #converse-login-trusted{margin-top:.5em}#conversejs.converse-overlayed #controlbox:not(.logged-out) .controlbox-head{height:15px}#conversejs.converse-overlayed #controlbox .controlbox-head{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;justify-content:space-between;min-height:0}#conversejs.converse-overlayed #controlbox .controlbox-head .brand-heading{color:var(--controlbox-text-color);font-size:2em}#conversejs.converse-overlayed #controlbox .controlbox-head .chatbox-btn{color:var(--controlbox-head-color);margin:0}#conversejs.converse-overlayed #controlbox #converse-login,#conversejs.converse-overlayed #controlbox #converse-register{flex:0 0 100%;max-width:100%;padding-bottom:0}#conversejs.converse-overlayed #controlbox #converse-register .button-cancel{font-size:90%}#conversejs.converse-overlayed #controlbox .controlbox-panes{border-radius:var(--chatbox-border-radius)}#conversejs.converse-embedded .toggle-controlbox,#conversejs.converse-fullscreen .toggle-controlbox{display:none}#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{position:relative;width:100%;padding-right:15px;padding-left:15px;margin:0}@media (min-width:768px){#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{flex:0 0 33.33333%;max-width:33.33333%}}@media (min-width:992px){#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{flex:0 0 25%;max-width:25%}}@media (min-width:1200px){#conversejs.converse-embedded #controlbox,#conversejs.converse-fullscreen #controlbox,#conversejs.converse-mobile #controlbox{flex:0 0 16.66667%;max-width:16.66667%}}#conversejs.converse-embedded #controlbox.logged-out,#conversejs.converse-fullscreen #controlbox.logged-out,#conversejs.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%}#conversejs.converse-embedded #controlbox .controlbox-pane,#conversejs.converse-fullscreen #controlbox .controlbox-pane,#conversejs.converse-mobile #controlbox .controlbox-pane{border-radius:0}#conversejs.converse-embedded #controlbox .flyout,#conversejs.converse-fullscreen #controlbox .flyout,#conversejs.converse-mobile #controlbox .flyout{border-radius:0}#conversejs.converse-embedded #controlbox #converse-login-panel,#conversejs.converse-fullscreen #controlbox #converse-login-panel,#conversejs.converse-mobile #controlbox #converse-login-panel{border-radius:0}#conversejs.converse-embedded #controlbox #converse-login-panel .converse-form,#conversejs.converse-fullscreen #controlbox #converse-login-panel .converse-form,#conversejs.converse-mobile #controlbox #converse-login-panel .converse-form{padding:3em 2em 3em}#conversejs.converse-embedded #controlbox .toggle-register-login,#conversejs.converse-fullscreen #controlbox .toggle-register-login,#conversejs.converse-mobile #controlbox .toggle-register-login{line-height:var(--line-height-huge)}#conversejs.converse-embedded #controlbox converse-brand-heading,#conversejs.converse-fullscreen #controlbox converse-brand-heading,#conversejs.converse-mobile #controlbox converse-brand-heading{flex:0 0 100%;max-width:100%;margin-top:5em;margin-bottom:1em}#conversejs.converse-embedded #controlbox converse-brand-heading .brand-heading,#conversejs.converse-fullscreen #controlbox converse-brand-heading .brand-heading,#conversejs.converse-mobile #controlbox converse-brand-heading .brand-heading{font-size:500%;padding:.7em 0 0 0;opacity:.8;color:var(--brand-heading-color)}#conversejs.converse-embedded #controlbox converse-brand-heading .brand-subtitle,#conversejs.converse-fullscreen #controlbox converse-brand-heading .brand-subtitle,#conversejs.converse-mobile #controlbox converse-brand-heading .brand-subtitle{font-size:90%;padding:.5em}@media screen and (max-width:480px){#conversejs.converse-embedded #controlbox converse-brand-heading .brand-heading,#conversejs.converse-fullscreen #controlbox converse-brand-heading .brand-heading,#conversejs.converse-mobile #controlbox converse-brand-heading .brand-heading{font-size:300%}}#conversejs.converse-embedded #controlbox.logged-out,#conversejs.converse-fullscreen #controlbox.logged-out,#conversejs.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%;opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-timing-function:ease;animation-timing-function:ease;width:100%}#conversejs.converse-embedded #controlbox.logged-out .box-flyout,#conversejs.converse-fullscreen #controlbox.logged-out .box-flyout,#conversejs.converse-mobile #controlbox.logged-out .box-flyout{width:100%}#conversejs.converse-embedded #controlbox .box-flyout,#conversejs.converse-fullscreen #controlbox .box-flyout,#conversejs.converse-mobile #controlbox .box-flyout{border:0;width:100%;z-index:1;background-color:var(--controlbox-head-color)}#conversejs.converse-embedded #controlbox .box-flyout .controlbox-head,#conversejs.converse-fullscreen #controlbox .box-flyout .controlbox-head,#conversejs.converse-mobile #controlbox .box-flyout .controlbox-head{display:none}#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{position:relative;width:100%;padding-right:15px;padding-left:15px;flex:0 0 66.66667%;max-width:66.66667%;margin-left:16.66667%}@media (min-width:576px){#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{flex:0 0 66.66667%;max-width:66.66667%;margin-left:16.66667%}}@media (min-width:768px){#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{flex:0 0 66.66667%;max-width:66.66667%;margin-left:16.66667%}}@media (min-width:992px){#conversejs.converse-embedded #controlbox #converse-login,#conversejs.converse-embedded #controlbox #converse-register,#conversejs.converse-fullscreen #controlbox #converse-login,#conversejs.converse-fullscreen #controlbox #converse-register,#conversejs.converse-mobile #controlbox #converse-login,#conversejs.converse-mobile #controlbox #converse-register{flex:0 0 50%;max-width:50%;margin-left:25%}}#conversejs.converse-embedded #controlbox #converse-login .instructions,#conversejs.converse-embedded #controlbox #converse-login .title,#conversejs.converse-embedded #controlbox #converse-register .instructions,#conversejs.converse-embedded #controlbox #converse-register .title,#conversejs.converse-fullscreen #controlbox #converse-login .instructions,#conversejs.converse-fullscreen #controlbox #converse-login .title,#conversejs.converse-fullscreen #controlbox #converse-register .instructions,#conversejs.converse-fullscreen #controlbox #converse-register .title,#conversejs.converse-mobile #controlbox #converse-login .instructions,#conversejs.converse-mobile #controlbox #converse-login .title,#conversejs.converse-mobile #controlbox #converse-register .instructions,#conversejs.converse-mobile #controlbox #converse-register .title{margin:1em 0}#conversejs.converse-embedded #controlbox #converse-login input[type=button],#conversejs.converse-embedded #controlbox #converse-login input[type=submit],#conversejs.converse-embedded #controlbox #converse-register input[type=button],#conversejs.converse-embedded #controlbox #converse-register input[type=submit],#conversejs.converse-fullscreen #controlbox #converse-login input[type=button],#conversejs.converse-fullscreen #controlbox #converse-login input[type=submit],#conversejs.converse-fullscreen #controlbox #converse-register input[type=button],#conversejs.converse-fullscreen #controlbox #converse-register input[type=submit],#conversejs.converse-mobile #controlbox #converse-login input[type=button],#conversejs.converse-mobile #controlbox #converse-login input[type=submit],#conversejs.converse-mobile #controlbox #converse-register input[type=button],#conversejs.converse-mobile #controlbox #converse-register input[type=submit]{width:auto}@media (max-width:767.98px){#conversejs{left:0;right:0;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}#conversejs .converse-chatboxes{margin:0!important;flex-direction:row!important;justify-content:space-between}#conversejs .converse-chatboxes .converse-chatroom{font-size:14px}#conversejs .converse-chatboxes .chatbox .box-flyout{margin-left:15px;left:0;bottom:0;border-radius:0;width:100vw!important;height:var(--fullpage-chat-height)}#conversejs .converse-chatboxes #controlbox{width:100vw!important}#conversejs .converse-chatboxes #controlbox .box-flyout{width:100vw!important;height:var(--fullpage-chat-height);margin-right:-15px}#conversejs .converse-chatboxes #controlbox .sidebar{display:block}#conversejs .converse-chatboxes.sidebar-open .chatbox:not(#controlbox){display:none}#conversejs .converse-chatboxes.sidebar-open #controlbox .controlbox-pane{display:block}}#conversejs.converse-fullscreen .controlbox-panes{padding-top:1em}#conversejs.converse-overlayed .brand-heading{padding-top:.8rem;padding-left:.8rem;width:100%}#conversejs.converse-overlayed .converse-svg-logo{height:1em}#conversejs.converse-overlayed #controlbox #converse-login-panel{height:100%}#conversejs.converse-overlayed #controlbox .controlbox-panes{margin-top:.5em}#conversejs #converse-modals .modal{background-color:rgba(0,0,0,.4)}#conversejs #converse-modals .modal .modal-body{overflow-y:auto;max-height:75vh;margin-bottom:2em}#conversejs #converse-modals .modal .modal-body p{padding:.25rem 0}#conversejs #converse-modals .modal .modal-body .confirm .form-group p:first-child{font-size:110%;font-weight:700}#conversejs #converse-modals .modal .modal-body.fit-content{box-sizing:content-box}#conversejs #converse-modals .modal .modal-body.fit-content img{max-width:90vw}#conversejs #converse-modals .modal .modal-body--image .chat-image{max-height:99%;max-width:100%}#conversejs #converse-modals .modal .modal-footer{justify-content:flex-start}#conversejs #converse-modals .modal .roomid-policy-error{color:var(--error-color);font-size:var(--font-size-small);float:right}#conversejs #converse-modals .scrollable-container{max-height:45vh;overflow-y:auto}#conversejs #converse-modals .affiliation-form,#conversejs #converse-modals .role-form{padding:2em 0 1em 0}#conversejs #converse-modals .set-xmpp-status{margin:1em}#conversejs #converse-modals .set-xmpp-status .custom-control-label{padding-top:.25em}#conversejs #converse-modals #omemo-tabpanel{margin-top:1em}#conversejs #converse-modals .btn{font-weight:400}#conversejs #converse-modals #user-profile-modal .profile-form label{font-weight:700}#conversejs #converse-modals #user-profile-modal .fingerprint-removal label{display:flex;padding:.75rem 1.25rem}#conversejs #converse-modals #user-profile-modal .list-group-item{display:flex;justify-content:left;font-size:95%}#conversejs #converse-modals #user-profile-modal .list-group-item input[type=checkbox]{margin-right:1em}#conversejs #converse-modals .fingerprints{width:100%;margin-bottom:1em}#conversejs #converse-modals .fingerprint-trust{display:flex;justify-content:space-between;font-size:95%}#conversejs #converse-modals .fingerprint-trust .fingerprint{margin-left:1em}#conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:0;height:var(--roster-height);padding:0;overflow:hidden;height:calc(100% - 70px)}#conversejs #converse-roster #online-count{display:none}#conversejs #converse-roster .search-xmpp ul li.chat-info{padding-left:10px}#conversejs #converse-roster .roster-filter-form{width:100%}#conversejs #converse-roster .roster-filter-form .button-group{padding:.2em}#conversejs #converse-roster .roster-filter-form span{padding:.3em;cursor:pointer;min-width:25px;text-align:center}#conversejs #converse-roster .roster-filter-form .roster-filter{width:100%;margin:.2em;font-size:calc(var(--font-size) - 2px)}#conversejs #converse-roster .roster-filter-form .state-type{font-size:calc(var(--font-size) - 2px);width:100%}#conversejs #converse-roster .roster-contacts{padding:0;margin:0 0 .2em 0;height:100%;overflow-x:hidden;overflow-y:auto}#conversejs #converse-roster .roster-contacts .roster-group{border:none;color:var(--text-color);font-weight:400;text-shadow:0 1px 0 var(--text-shadow-color);margin:.75em 0 .75em 0}#conversejs #converse-roster .roster-contacts .roster-group .group-toggle{font-family:var(--heading-font);display:block;width:100%;padding-top:0;padding-bottom:.3rem}#conversejs #converse-roster .roster-contacts .roster-group .group-toggle,#conversejs #converse-roster .roster-contacts .roster-group .group-toggle .fa{color:var(--chat-head-color-dark)!important}#conversejs #converse-roster .roster-contacts .roster-group .group-toggle .fa:hover,#conversejs #converse-roster .roster-contacts .roster-group .group-toggle:hover{color:var(--chat-head-color-darker)!important}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact{margin:.25em 0}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status{vertical-align:middle;font-size:.6em;margin-right:0;margin-left:-.7em;margin-bottom:-1.5em;border-radius:50%;border:2px solid var(--occupants-background-color)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--offline{margin-right:.8em}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--online{color:var(--chat-status-online)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--busy{color:var(--chat-status-busy)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--away{color:var(--chat-status-away)}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .chat-status--offline{display:none}#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .fa-times-circle,#conversejs #converse-roster .roster-contacts .roster-group .current-xmpp-contact .far.fa-circle{color:var(--subdued-color)}#conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a{line-height:var(--line-height)}#conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact .req-contact-name{padding:0 .2em 0 0}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat{margin:0;padding:0}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs{font-weight:700}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs .contact-name{width:70%}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .msgs-indicator{color:#fff;background-color:var(--chat-head-color);opacity:1;border-radius:10%;padding:.2em .4em;font-size:var(--font-size-small)}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding:0;margin:0;max-width:85%;float:none;height:100%}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name.unread-msgs{max-width:60%}#conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name.contact-name--offline{margin-left:.7em}#conversejs #converse-roster .roster-contacts .roster-group li.odd{background-color:#dceac5}#conversejs #converse-roster .roster-contacts .roster-group li a,#conversejs #converse-roster .roster-contacts .roster-group li span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#conversejs #converse-roster .roster-contacts .roster-group li .span{display:inline-block}#conversejs #converse-roster .roster-contacts .roster-group li .decline-xmpp-request{margin-left:5px}#conversejs #converse-roster .roster-contacts .roster-group li:hover{background-color:var(controlbox-pane-bg-hover-color)}#conversejs #converse-roster span.pending-contact-name{line-height:var(--line-height);width:100%}#conversejs .list-container{text-align:left;padding:.3em 0}#conversejs .list-container .list-toggle{font-family:var(--heading-font);font-weight:var(--list-toggle-font-weight);display:block;color:var(--list-toggle-color);padding:0 0 .5rem 0}#conversejs .list-container .list-toggle:hover{color:var(--list-toggle-hover-color)}#conversejs .items-list{text-align:left}#conversejs .items-list .list-item{border:none;clear:both;color:var(--text-color);overflow:hidden;padding:.5em 0;text-shadow:0 1px 0 var(--text-shadow-color);word-wrap:break-word;height:2.5em}#conversejs .items-list .list-item.unread-msgs{font-weight:700}#conversejs .items-list .list-item .list-item-link{color:var(--list-item-link-color);margin:auto;font-size:var(--font-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;vertical-align:baseline}#conversejs .items-list .list-item .list-item-link:hover{color:var(--list-item-link-hover-color)}#conversejs .items-list .list-item .list-item-badge{opacity:1;border-radius:25%;color:#fff;font-size:var(--font-size-small);line-height:var(--font-size-small)}#conversejs .items-list .list-item .list-item-action{opacity:0;font-size:var(--font-size-tiny);padding:.3em 0 0 0;margin:0 0 0 var(--inline-action-margin);width:2em;height:2em;color:var(--subdued-color)}#conversejs .items-list .list-item .list-item-action:before{font-size:var(--font-size)}#conversejs .items-list .list-item .list-item-action.button-on{color:var(--list-item-link-color)}#conversejs .items-list .list-item .list-item-action.button-on:hover{color:var(--list-item-link-hover-color)}#conversejs .items-list .list-item .list-item-action:hover{color:var(--list-toggle-hover-color);opacity:1}#conversejs .items-list .list-item .list-item-action--visible{opacity:1!important}#conversejs .items-list .list-item.open{background-color:var(--list-item-open-color)}#conversejs .items-list .list-item.open:hover{background-color:var(--list-item-open-hover-color)!important}#conversejs .items-list .list-item.open a{color:#fff}#conversejs .items-list .list-item.open .list-item-link:hover{color:#fff}#conversejs .items-list .list-item.open .list-item-action{color:var(--list-item-action-color)}#conversejs .items-list .list-item.open .list-item-action:hover{color:#fff}#conversejs .items-list .list-item:hover{background-color:var(--controlbox-pane-bg-hover-color)}#conversejs .items-list .list-item:hover .fa,#conversejs .items-list .list-item:hover .far,#conversejs .items-list .list-item:hover .fas{opacity:1}#conversejs .badge--muc,#conversejs.converse-embedded .badge--muc{background-color:var(--groupchats-header-color)}#conversejs .add-chatroom input[type=button],#conversejs .add-chatroom input[type=submit],#conversejs.converse-embedded .add-chatroom input[type=button],#conversejs.converse-embedded .add-chatroom input[type=submit]{margin:.3em 0}#conversejs #room-details-modal .features-list,#conversejs.converse-embedded #room-details-modal .features-list{margin-left:1em}#conversejs .chatroom-features,#conversejs.converse-embedded .chatroom-features{width:100%}#conversejs .chatroom-features .features-list,#conversejs.converse-embedded .chatroom-features .features-list{padding-top:0}#conversejs .chatroom-features .features-list .feature,#conversejs.converse-embedded .chatroom-features .features-list .feature{width:100%;margin-right:.5em;padding-right:0;font-size:1em;cursor:help}#conversejs .chatroom-features .features-list .feature .fa,#conversejs.converse-embedded .chatroom-features .features-list .feature .fa{margin-right:.5em;color:var(--text-color)}#conversejs .chat-head-chatroom,#conversejs.converse-embedded .chat-head-chatroom{color:var(--chatroom-head-color);background-color:var(--chatroom-head-bg-color);border-bottom:var(--chatroom-head-border-bottom)}#conversejs .chat-head-chatroom .chat-head__desc,#conversejs.converse-embedded .chat-head-chatroom .chat-head__desc{color:var(--chatroom-head-color);display:var(--chatroom-head-description-display)}#conversejs .chat-head-chatroom .chat-head__desc a,#conversejs.converse-embedded .chat-head-chatroom .chat-head__desc a{color:var(--chatroom-head-description-link-color)}#conversejs .chat-head-chatroom .chat-head__desc:hover button,#conversejs.converse-embedded .chat-head-chatroom .chat-head__desc:hover button{display:inline-block}#conversejs .chat-head-chatroom .chatbox-title .btn--transparent i,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title .btn--transparent i{color:var(--chatroom-head-color)}#conversejs .chat-head-chatroom .chatbox-title .chatbox-title__text--bookmarked,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title .chatbox-title__text--bookmarked{margin-left:.5em;color:var(--chatroom-head-color)}#conversejs .chat-head-chatroom .chatbox-title__buttons,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title__buttons{background-color:var(--chatroom-head-bg-color)}#conversejs .chat-head-chatroom a.chatbox-btn.fa,#conversejs .chat-head-chatroom a:hover.chatbox-btn.fa,#conversejs .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa,#conversejs .chat-head-chatroom a:visited.chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a:hover.chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa,#conversejs.converse-embedded .chat-head-chatroom a:visited.chatbox-btn.fa{color:var(--chat-head-text-color)}#conversejs .chat-head-chatroom a.chatbox-btn.fa.button-on:before,#conversejs .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before,#conversejs .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,#conversejs .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,#conversejs.converse-embedded .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before{color:var(--chatroom-head-button-color)}#conversejs .chat-head-chatroom .chatbox-btn.button-on:before,#conversejs.converse-embedded .chat-head-chatroom .chatbox-btn.button-on:before{color:var(--chatroom-head-button-color)}#conversejs .chat-head-chatroom .chatbox-title__text,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title__text{display:var(--heading-display);font-weight:var(--chatroom-head-title-font-weight);margin:auto 0;padding-right:var(--chatroom-head-title-padding-right);white-space:nowrap}#conversejs .chat-head-chatroom .chatbox-title__text .chatroom-jid,#conversejs.converse-embedded .chat-head-chatroom .chatbox-title__text .chatroom-jid{font-size:var(--font-size-small)}#conversejs .empty-history-feedback,#conversejs.converse-embedded .empty-history-feedback{position:relative}#conversejs .empty-history-feedback span,#conversejs.converse-embedded .empty-history-feedback span{width:100%;text-align:center;position:absolute;margin-top:50%}#conversejs .chatroom,#conversejs.converse-embedded .chatroom{width:var(--chatroom-width)}@media screen and (max-height:450px){#conversejs .chatroom,#conversejs.converse-embedded .chatroom{width:var(--mobile-chat-width)}}@media screen and (max-width:480px){#conversejs .chatroom,#conversejs.converse-embedded .chatroom{width:var(--mobile-chat-width)}}#conversejs .chatroom .box-flyout,#conversejs.converse-embedded .chatroom .box-flyout{overflow-y:hidden;background-color:var(--chatroom-head-bg-color);width:100%}@media screen and (max-height:450px){#conversejs .chatroom .box-flyout,#conversejs.converse-embedded .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){#conversejs .chatroom .box-flyout,#conversejs.converse-embedded .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}#conversejs .chatroom .box-flyout .chatroom-body,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body{flex-direction:row;flex-flow:nowrap;background-color:#fff;border-top:0;width:100%;overflow:hidden}#conversejs .chatroom .box-flyout .chatroom-body .row,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .row{flex-direction:row}#conversejs .chatroom .box-flyout .chatroom-body .chat-topic,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-topic{font-weight:700;color:var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-info,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info{color:var(--chat-info-color);line-height:normal}#conversejs .chatroom .box-flyout .chatroom-body .chat-info.badge,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info.badge{color:var(--chat-head-text-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-info.chat-msg--retracted,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info.chat-msg--retracted{color:var(--subdued-color)}#conversejs .chatroom .box-flyout .chatroom-body .disconnect-container,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-container{margin:1em;width:100%}#conversejs .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg{padding-bottom:1em}#conversejs .chatroom .box-flyout .chatroom-body .chat-area,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area{display:flex;flex-direction:column;flex:0 1 100%;justify-content:flex-end;min-width:25%;word-wrap:break-word}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator{background-color:var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content{height:100%}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help{border-top:1px solid var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help .close-chat-help svg,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help .close-chat-help svg{fill:var(--chatroom-head-bg-color)}#conversejs .chatroom .box-flyout .chatroom-body .occupants,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants{display:flex;flex-direction:column;justify-content:space-between;overflow-x:hidden;overflow-y:hidden;vertical-align:top;background-color:var(--occupants-background-color);border-left:var(--occupants-border-left);padding:.5em;max-width:75%;min-width:20%;flex:0 0 25%}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header{display:flex;flex-direction:column}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants{align-self:flex-end;cursor:pointer;font-size:var(--font-size-small)}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header--title,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header--title{margin-top:.5em;margin-bottom:.5em;display:flex;flex-direction:row}#conversejs .chatroom .box-flyout .chatroom-body .occupants .fa-user-plus,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .fa-user-plus{margin-right:.25em}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{font-family:var(--heading-font);color:var(--groupchats-header-color-dark);padding-left:0;margin-right:1em}#conversejs .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul{padding:0}#conversejs .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul li,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .suggestion-box ul li{padding:.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul{padding:0;margin-bottom:.5em;overflow-x:hidden;overflow-y:auto;list-style:none}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list{overflow-y:auto;flex-basis:0;flex-grow:1}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li{cursor:default;display:block;font-size:var(--font-size-small);overflow:hidden;padding:.25em .25em .25em 0;text-overflow:ellipsis}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa{margin-right:.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.feature,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.feature{font-size:var(--font-size-tiny)}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant{cursor:pointer}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge{display:flex;justify-content:space-between;flex-wrap:wrap}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges{display:flex;justify-content:flex-end;flex-wrap:wrap;flex-direction:row}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges span,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-nick-badge .occupant-badges span{margin-right:.25rem}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters{flex-wrap:nowrap;min-height:1.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge{margin-bottom:.125rem}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status{display:inline-block;margin:0 .5em .125em 0;width:.5em;height:.5em}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online{background-color:#1a9707}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd{background-color:red}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away{background-color:#ff8c00}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa{background-color:orange}#conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline{background-color:#a9a9a9}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container{background-color:#fff;border:0;color:var(--text-color);font-size:var(--font-size);height:100%;width:100%;overflow-y:auto}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message{font-size:90%;color:var(--error-color)}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit],#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit]{margin:0 .5em}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary{background-color:var(--chatroom-head-button-color)}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form,#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form{display:flex;flex-direction:column;justify-content:center;padding:2em}#conversejs .chatroom .muc-bottom-panel,#conversejs.converse-embedded .chatroom .muc-bottom-panel{height:3em;padding:.5em;text-align:center;font-size:var(--font-size-small);background-color:var(--chatroom-head-bg-color);color:#fff}#conversejs .chatroom .muc-bottom-panel.muc-bottom-panel--nickname,#conversejs.converse-embedded .chatroom .muc-bottom-panel.muc-bottom-panel--nickname{padding:0;height:16em}#conversejs .chatroom .muc-bottom-panel.muc-bottom-panel--nickname .chatroom-form-container .chatroom-form,#conversejs.converse-embedded .chatroom .muc-bottom-panel.muc-bottom-panel--nickname .chatroom-form-container .chatroom-form{padding-top:2em;padding-bottom:0}#conversejs .chatroom .sendXMPPMessage .suggestion-box__results--above,#conversejs.converse-embedded .chatroom .sendXMPPMessage .suggestion-box__results--above{bottom:4.5em}#conversejs .chatroom .sendXMPPMessage .chat-textarea:active,#conversejs .chatroom .sendXMPPMessage .chat-textarea:focus,#conversejs .chatroom .sendXMPPMessage input:active,#conversejs .chatroom .sendXMPPMessage input:focus,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea:active,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea:focus,#conversejs.converse-embedded .chatroom .sendXMPPMessage input:active,#conversejs.converse-embedded .chatroom .sendXMPPMessage input:focus{outline-color:var(--chatroom-head-bg-color)}#conversejs .chatroom .sendXMPPMessage .chat-textarea.correcting,#conversejs .chatroom .sendXMPPMessage input.correcting,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea.correcting,#conversejs.converse-embedded .chatroom .sendXMPPMessage input.correcting{background-color:var(--chatroom-correcting-color)}#conversejs .chatroom .sendXMPPMessage .chat-textarea,#conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea{border-bottom-right-radius:0}#conversejs .chatroom .room-invite .invited-contact,#conversejs.converse-embedded .chatroom .room-invite .invited-contact{margin:-1px 0 0 -1px;width:100%;border:1px solid #999}#conversejs.converse-overlayed .chatbox.chatroom{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}#conversejs.converse-overlayed .chatbox.chatroom .box-flyout{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}#conversejs.converse-overlayed .chatbox.chatroom .chatbox-title__text{flex:0 0 58.33333%;max-width:58.33333%}#conversejs.converse-overlayed .chatbox.chatroom .chatbox-title__buttons{flex:0 0 41.66667%;max-width:41.66667%}#conversejs.converse-overlayed .chatbox.chatroom .chat-head__desc{font-size:80%;margin-bottom:1em}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupants-heading{padding:0}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupant-list{border-bottom:none}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-nick-badge .occupant-badges{display:none}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-status{margin-top:6px}#conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .chat-area{min-width:var(--overlayed-chat-width)}#conversejs.converse-embedded .chatroom .box-flyout,#conversejs.converse-fullscreen .chatroom .box-flyout,#conversejs.converse-mobile .chatroom .box-flyout{width:100%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator{max-width:100%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants{padding:var(--occupants-padding)}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{font-size:var(--font-size-large)}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,#conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,#conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li{font-size:var(--font-size-small)}#conversejs.converse-embedded .chatroom .room-invite span .invited-contact,#conversejs.converse-fullscreen .chatroom .room-invite span .invited-contact,#conversejs.converse-mobile .chatroom .room-invite span .invited-contact{margin:0 0 .5em -1px}#conversejs.converse-embedded .chatroom{margin:0;width:100%}#conversejs.converse-embedded .chatroom .box-flyout .occupants-heading{font-size:120%}#conversejs.converse-embedded .chatroom .box-flyout .chat-content .chat-message{margin:.5em;font-size:120%}#conversejs.converse-embedded .chatroom .box-flyout .sendXMPPMessage .chat-textarea{padding:.5em;font-size:110%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body{height:100%}#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container{height:100%;position:relative}#conversejs.converse-embedded .chatroom .box-flyout .occupants .occupant-list{padding-left:.3em}@media (max-width:767.98px){#conversejs.converse-fullscreen .chatbox .box-flyout .chat-head-chatroom .chatbox-navback,#conversejs.converse-mobile .chatbox .box-flyout .chat-head-chatroom .chatbox-navback,#conversejs.converse-overlayed .chatbox .box-flyout .chat-head-chatroom .chatbox-navback{margin-right:0!important}#conversejs.converse-fullscreen .chatbox .box-flyout .chat-head-chatroom .chatbox-navback .fa-arrow-left:before,#conversejs.converse-mobile .chatbox .box-flyout .chat-head-chatroom .chatbox-navback .fa-arrow-left:before,#conversejs.converse-overlayed .chatbox .box-flyout .chat-head-chatroom .chatbox-navback .fa-arrow-left:before{color:var(--chatroom-head-color)}}#conversejs .chat-head-headline{background-color:var(--headline-head-color)}#conversejs .chatbox.headlines .chat-head.chat-head-chatbox{background-color:var(--headline-head-color)}#conversejs .chatbox.headlines .chat-body{background-color:var(--headline-head-color)}#conversejs .chatbox.headlines .chat-body .chat-message{color:var(--headline-message-color)}#conversejs .chatbox.headlines .chat-content{height:100%}#conversejs .message.chat-msg.headline .chat-msg__body{margin-left:0}#conversejs.converse-fullscreen .chatbox.headlines .box-flyout{background-color:var(--headline-head-color)}#conversejs.converse-fullscreen .chatbox.headlines .chat-head.chat-head-chatbox{background-color:var(--headline-head-color)}#conversejs.converse-fullscreen .chatbox.headlines .flyout{border-color:var(--headline-head-color)}#conversejs .styling-directive{color:var(--subdued-color)}#conversejs .older-msg time{font-weight:700}#conversejs .message blockquote{margin-left:.5em;margin-bottom:.25em;padding-right:1em;color:var(--subdued-color);border-left:.3em solid var(--subdued-color);padding-left:.5em}#conversejs .message code{font-family:monospace}#conversejs .message .mention{font-weight:700}#conversejs .message .mention--self{font-weight:400}#conversejs .message.date-separator,#conversejs .message.separator{height:2em;margin:0;position:relative;text-align:center;z-index:0}#conversejs .message.date-separator .separator,#conversejs .message.separator .separator{border-top:0;border-bottom:var(--chat-separator-border-bottom);margin:0 1em;position:relative;top:1em;z-index:5}#conversejs .message.date-separator .separator-text,#conversejs .message.separator .separator-text{background:#fff;bottom:1px;color:var(--separator-text-color);display:inline-block;line-height:2em;padding:0 1em;position:relative;z-index:5}#conversejs .message.chat-msg--retracted .chat-msg__message{color:var(--subdued-color)}#conversejs .message.chat-info{color:var(--chat-head-color);font-size:var(--message-font-size);line-height:var(--line-height-small);font-size:90%;padding:.17rem 1rem}#conversejs .message.chat-info.badge{color:var(--chat-head-text-color)}#conversejs .message.chat-info.chat-state-notification{font-style:italic}#conversejs .message.chat-info.chat-event{clear:left;font-style:italic}#conversejs .message.chat-info.chat-error{color:var(--error-color);font-weight:700}#conversejs .message.chat-info .q{font-style:italic}#conversejs .message .chat-image{height:auto;width:auto;max-height:15em;max-width:100%}#conversejs .message.chat-msg--action{font-style:italic}#conversejs .message.chat-msg--action .chat-msg__author{padding-right:.2em}#conversejs .message.chat-msg{display:inline-flex;width:100%;flex-direction:row;padding:.125rem 1rem}#conversejs .message.chat-msg.onload{animation:colorchange-chatmessage 1s;-webkit-animation:colorchange-chatmessage 1s}#conversejs .message.chat-msg:hover{background-color:var(--list-item-hover-color)}#conversejs .message.chat-msg.correcting.groupchat{background-color:var(--chatroom-correcting-color)}#conversejs .message.chat-msg.correcting:not(.groupchat){background-color:var(--chat-correcting-color)}#conversejs .message.chat-msg .spoiler{margin-top:.5em}#conversejs .message.chat-msg .spoiler-hint{margin-bottom:.5em}#conversejs .message.chat-msg .spoiler-toggle{color:#fff}#conversejs .message.chat-msg .spoiler-toggle i{color:#fff;padding-right:.5em}#conversejs .message.chat-msg .spoiler-toggle:before{padding-right:.25em;whitespace:nowrap}#conversejs .message.chat-msg .chat-msg__content{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-left:.5rem;width:calc(100% - var(--message-avatar-width))}#conversejs .message.chat-msg .chat-msg__content:hover .btn--standalone{opacity:1}#conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat .chat-msg__text{color:var(--subdued-color)}#conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--delayed .chat-msg__text,#conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--received .chat-msg__text{color:var(--message-text-color)}#conversejs .message.chat-msg .chat-msg__content--action{width:100%;margin-left:0}#conversejs .message.chat-msg .chat-msg__body{display:flex;flex-direction:row;justify-content:space-between}#conversejs .message.chat-msg converse-chat-message-body{display:inline}#conversejs .message.chat-msg .chat-msg__message{line-height:1.5em;display:inline-flex;flex-direction:column;width:100%;overflow-wrap:break-word}#conversejs .message.chat-msg .chat-msg__edit-modal{cursor:pointer;padding-right:.5em}#conversejs .message.chat-msg .chat-msg__subject{font-weight:700;clear:right}#conversejs .message.chat-msg .chat-msg__text{color:var(--message-text-color);padding:0;white-space:pre-wrap;word-wrap:break-word;word-break:break-word}#conversejs .message.chat-msg .chat-msg__text a{word-wrap:break-word;word-break:break-all;display:inline}#conversejs .message.chat-msg .chat-msg__text a.chat-image__link{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:block}#conversejs .message.chat-msg .chat-msg__text img.emoji{height:1.5em;width:1.5em;margin:0 .05em 0 .1em;vertical-align:-.1em}#conversejs .message.chat-msg .chat-msg__text .emojione{margin-bottom:-6px}#conversejs .message.chat-msg .chat-msg__text--larger{font-size:1.6em;padding-top:.25em;padding-bottom:.25em}#conversejs .message.chat-msg .chat-msg__error{color:var(--error-color)}#conversejs .message.chat-msg .chat-msg__media{margin-top:.25rem;word-break:break-all}#conversejs .message.chat-msg .chat-msg__media a{word-wrap:break-word}#conversejs .message.chat-msg .chat-msg__media audio{width:100%}#conversejs .message.chat-msg converse-message-actions{margin-left:.5em}#conversejs .message.chat-msg .chat-msg__actions .dropdown-menu{min-width:5rem}#conversejs .message.chat-msg .chat-msg__actions i{color:var(--text-color-lighten-15-percent);font-size:70%}#conversejs .message.chat-msg .chat-msg__actions button{border:none;background:0 0;color:var(--text-color-lighten-15-percent);padding:0 .25em}#conversejs .message.chat-msg .chat-msg__actions .btn--standalone{opacity:0;margin-top:-.2em}#conversejs .message.chat-msg .chat-msg__actions .chat-msg__action{width:100%;padding:.5em 1em;text-align:left;white-space:nowrap}#conversejs .message.chat-msg .chat-msg__actions .chat-msg__action converse-icon{margin-right:.25em}#conversejs .message.chat-msg .chat-msg__actions .chat-msg__action:hover{color:var(--text-color);background-color:var(--list-item-hover-color)}#conversejs .message.chat-msg .chat-msg__avatar{margin-top:.5em;vertical-align:middle;height:var(--message-avatar-height);width:var(--message-avatar-width);min-height:var(--message-avatar-height);min-width:var(--message-avatar-width)}#conversejs .message.chat-msg .chat-msg__author{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--heading-font);font-size:115%;font-weight:700;padding-bottom:1px}#conversejs .message.chat-msg .chat-msg__heading{width:100%;margin-top:.5em;padding-right:.25rem;padding-bottom:.25rem}#conversejs .message.chat-msg .chat-msg__heading .badge{margin-left:.5em;font-family:var(--normal_font)}#conversejs .message.chat-msg .chat-msg__heading .chat-msg__time{padding-left:.25em;padding-right:.25em;color:var(--text-color-lighten-15-percent)}#conversejs .message.chat-msg.chat-msg--action .chat-msg__message{flex-direction:row}#conversejs .message.chat-msg.chat-msg--action .chat-msg__text{width:auto}#conversejs .message.chat-msg.chat-msg--action .chat-msg__heading{margin-top:0;padding-bottom:0;width:auto}#conversejs .message.chat-msg.chat-msg--action .chat-msg__heading .fa{margin-left:.5em}#conversejs .message.chat-msg.chat-msg--action .chat-msg__author{font-size:var(--message-font-size)}#conversejs .message.chat-msg.chat-msg--action .chat-msg__time{margin-left:0}#conversejs .message.chat-msg.chat-msg--followup .chat-msg__avatar,#conversejs .message.chat-msg.chat-msg--followup .chat-msg__heading{display:none}#conversejs .message.chat-msg.chat-msg--followup.chat-msg--with-avatar .chat-msg__content{margin-left:2.75rem;width:100%}#conversejs .message.chat-msg .chat-msg__receipt{margin-left:.5em;margin-right:.5em;color:var(--message-receipt-color)}#conversejs .chatroom-body .message.onload{animation:colorchange-chatmessage-muc 1s;-webkit-animation:colorchange-chatmessage-muc 1s}#conversejs .chatroom-body .message .separator{border-top:0;border-bottom:var(--chatroom-separator-border-bottom)}#conversejs.converse-overlayed .message.chat-msg.chat-msg--followup .chat-msg__content{margin-left:0}@media screen and (max-width:767px){#conversejs:not(.converse-embedded) .message.chat-msg .chat-msg__author{white-space:normal}}#conversejs.converse-overlayed #minimized-chats{order:100;width:var(--minimized-chats-width);margin-bottom:0;border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);color:var(--inverse-link-color);margin-right:var(--chat-gutter);padding:0}#conversejs.converse-overlayed #minimized-chats .badge{bottom:8px;border:1px solid var(--overlayed-badge-color)}#conversejs.converse-overlayed #minimized-chats #toggle-minimized-chats{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);background-color:var(--link-color);padding:1em 0 0 0;text-align:center;color:#fff;white-space:nowrap;overflow-y:hidden;text-overflow:ellipsis;display:block;height:45px;width:9em}#conversejs.converse-overlayed #minimized-chats a.restore-chat{cursor:pointer;padding:1px 0 1px 5px;color:var(--chat-head-text-color);line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs.converse-overlayed #minimized-chats a.restore-chat:hover{text-decoration:none}#conversejs.converse-overlayed #minimized-chats a.restore-chat:visited{color:var(--chat-head-text-color)}#conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout{flex-direction:column-reverse;bottom:45px;width:var(--minimized-chats-width)}#conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head{min-height:0;padding:.3em;border-radius:var(--chatbox-border-radius);height:35px;margin-bottom:.2em;width:100%;max-width:9em;flex-wrap:nowrap}#conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout.minimized{height:auto}#conversejs.converse-overlayed #minimized-chats .unread-message-count{font-weight:700;background-color:#fff;border:1px solid;text-shadow:1px 1px 0 var(--text-shadow-color);color:var(--warning-color);border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}#conversejs.converse-overlayed #minimized-chats .chat-head-message-count-hidden,#conversejs.converse-overlayed #minimized-chats .unread-message-count-hidden{display:none}#conversejs #controlbox .bookmarks-toggle,#conversejs #controlbox .bookmarks-toggle .fa{color:var(--groupchats-header-color)!important}#conversejs #controlbox .bookmarks-toggle .fa:hover,#conversejs #controlbox .bookmarks-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}#conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room{width:80%}#conversejs [hidden]{display:none}#conversejs .visually-hidden{position:absolute;clip:rect(0,0,0,0)}#conversejs .form-group .suggestion-box{width:100%}#conversejs .suggestion-box{position:relative}#conversejs .suggestion-box mark{background:var(--completion-light-color)}#conversejs .suggestion-box>input{display:block}#conversejs .suggestion-box .suggestion-box__results,#conversejs .suggestion-box>ul{position:absolute;left:0;right:0;z-index:2;min-width:100%;box-sizing:border-box;list-style:none;padding:0;border-radius:.3em;margin:.2em 0 0;background:rgba(255,255,255,.9);background:linear-gradient(to bottom right,#fff,rgba(255,255,255,.9));border:1px solid rgba(0,0,0,.3);box-shadow:.05em .2em .6em rgba(0,0,0,.1);text-shadow:none}#conversejs .suggestion-box .suggestion-box__results:before,#conversejs .suggestion-box>ul:before{content:\"\";position:absolute;top:-.43em;left:1em;width:0;height:0;padding:.4em;background:#fff;border:inherit;border-right:0;border-bottom:0;transform:rotate(45deg);z-index:-1}#conversejs .suggestion-box .suggestion-box__results>li,#conversejs .suggestion-box>ul>li{text-overflow:ellipsis;overflow-x:hidden;position:relative;cursor:pointer;padding:1em}#conversejs .suggestion-box .suggestion-box__results--below{top:2em}#conversejs .suggestion-box .suggestion-box__results--above{bottom:4.5em}#conversejs .suggestion-box .suggestion-box__results--above:before{display:none}#conversejs .suggestion-box .suggestion-box__results--above:after{z-index:-1;content:\"\";position:absolute;bottom:-.43em;left:1em;width:0;height:0;padding:.4em;background:#fff;border:inherit;border-left:0;border-top:0;transform:rotate(45deg)}#conversejs .suggestion-box>ul:empty,#conversejs .suggestion-box>ul[hidden]{display:none}@supports (transform:scale(0)){#conversejs .suggestion-box>ul{transition:.3s cubic-bezier(.4,.2,.5,1.4);transform-origin:1.43em -.43em}#conversejs .suggestion-box>ul:empty,#conversejs .suggestion-box>ul[hidden]{opacity:0;transform:scale(0);display:block;transition-timing-function:ease}}#conversejs .suggestion-box>ul>li[aria-selected=true]{background:var(--completion-dark-color);color:var(--inverse-link-color)}#conversejs .suggestion-box li:hover mark{background:var(--completion-light-color);color:var(--inverse-link-color)}#conversejs .suggestion-box li[aria-selected=true] mark{background:var(--completion-normal-color);color:inherit}#conversejs.converse-fullscreen .suggestion-box__results--above{bottom:4.5em}#conversejs.converse-overlayed .suggestion-box__results--above{bottom:3.5em}#conversejs .chatbox img.emoji{height:1.2em;width:1.2em;margin:0 .05em 0 .1em;vertical-align:-.1em}#conversejs .chatbox .sendXMPPMessage .toggle-smiley a.toggle-smiley{padding:0}#conversejs .chatbox converse-emoji-dropdown{display:inline-block}#conversejs .chatbox converse-emoji-dropdown .dropdown-menu{padding:0}#conversejs .chatbox converse-emoji-picker{width:100%;padding-top:0;padding-bottom:0;background-color:var(--chat-head-color);overflow-y:hidden;background:#fff}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists{height:8em;overflow-y:auto;display:flex;flex-direction:column}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-category__heading{clear:both;color:var(--subdued-color);cursor:auto;display:block;font-size:var(--font-size);margin:0;padding:.75em 0 0 .5em}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-lists__container{overflow-x:hidden}#conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-picker li{float:left}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker{display:flex;padding:.5em 0;background-color:var(--chat-head-color);width:auto;font-size:var(--font-size)}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker label{margin:0;padding:0 .5em;white-space:nowrap;font-size:var(--font-size-small);color:var(--heading-color)}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul li{padding:0 .25em}#conversejs .chatbox converse-emoji-picker .emoji-picker{background-color:#fff;padding:.5em 0 0 .5em}#conversejs .chatbox converse-emoji-picker .emoji-picker:last-child{padding-bottom:.5em}#conversejs .chatbox converse-emoji-picker .emoji-picker li{display:inline-block;height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden;margin-left:0;list-style:none;position:relative}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji{padding:0 .2em;height:auto;width:auto;margin:0;display:block;text-align:center}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji.selected a{background-color:var(--highlight-color-darker)}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji img{margin:0 auto;height:var(--font-size-huge);width:var(--font-size-huge);display:inline-block;vertical-align:baseline}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a{padding:3px;display:inline-block;font-size:var(--font-size-huge);line-height:calc(var(--font-size-huge) * 1.5);height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden}#conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a:hover{background-color:var(--highlight-color-darker)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header{display:flex;flex-direction:column;padding:.1em 0;background-color:var(--chat-head-color)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header .emoji-search{width:auto;margin:.25em;height:2em;font-size:var(--font-size-small)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category{padding:.25em 0;font-size:var(--font-size-huge)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{background-color:#fff;border:1px var(--chat-head-color) solid;border-bottom:none}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.selected a,#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category:hover a{background-color:var(--highlight-color-darker)}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category a{padding:.25em;display:inline-block}#conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category img{height:var(--font-size-huge);width:var(--font-size-huge)}#conversejs .chatroom converse-emoji-picker{background-color:var(--chatroom-head-bg-color);background:#fff}#conversejs .chatroom converse-emoji-picker .emoji-skintone-picker{background-color:var(--chatroom-head-bg-color)}#conversejs .chatroom converse-emoji-picker .emoji-picker__header{background-color:var(--chatroom-head-bg-color)}#conversejs .chatroom converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{border:1px var(--chatroom-head-bg-color) solid;border-bottom:none}#conversejs.converse-overlayed converse-emoji-dropdown .dropdown-menu{min-width:18em}#conversejs.converse-overlayed .chatbox .emoji-picker__header .emoji-category img{height:var(--font-size)!important;width:var(--font-size)!important}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji a{font-size:var(--font-size);line-height:calc(var(--font-size) * 1.5);padding:0;height:calc(var(--font-size) * 1.5);width:calc(var(--font-size) * 1.5)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji img{height:var(--font-size);width:var(--font-size)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-skintone-picker{font-size:var(--font-size-small)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__header .emoji-category{font-size:var(--font-size-small)}#conversejs.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__lists{height:7em}#conversejs.converse-embedded converse-emoji-dropdown .dropdown-menu{min-width:20em}#conversejs.converse-fullscreen converse-emoji-dropdown .dropdown-menu{min-width:22em}#conversejs.converse-fullscreen .chatbox converse-emoji-picker .emoji-picker__lists{height:12em}#conversejs .chatbox converse-emoji-picker{max-width:40em}#conversejs.theme-redpill{--green:#25DB77;--orange:#E19823;--light-blue:#4E9CFE;--pink:#BD23E1;--beet:#360101;--beet-green:rgb(25, 68, 71);--beet-light-green:#8EB726;--beet-orig:#50162D;--blue:#4E9CFE;--darkest-grey:#232323;--red:#d33b2b;--dark-link-color:#3a3a3a;--occupants-background-color:#333;--form-background:#3b3b3b;--global-background-color:var(--darkest-grey);--redder-orange:var(--beet);--primary-color:var(--beet-orig);--primary-color-dark:var(--beet);--highlight-color-darker:var(--beet-light-green);--highlight-color:var(--beet);--headline-head-color:var(--beet-green);--text-color:#c5c5c5;--text-color-lighten-15-percent:#e9e9e9;--message-text-color:#FFFFFF;--text-controlbox-color:#d9d9d9;--message-receipt-color:var(--darkest-grey);--link-color:var(--beet-light-green);--chat-textarea-color:var(--font-hover-head-color);--chat-textarea-background-color:#2c2c2c;--chat-content-background-color:#2c2c2c;--controlbox-heading-top-margin:0.75em;--inline-action-margin:0.75em;--chat-head-color:var(--beet-green);--chat-head-color-dark:#b9b9ac;--chat-head-color-darker:#e8e8e3;--chat-correcting-color:var(--beet);--chatbox-border-radius:0px;--controlbox-head-color-lighten-45-percent:#0e0e0e;--controlbox-pane-background-color:var(--darkest-grey);--font-head-color:#777;--font-hover-head-color:#c5c5c5;--chatroom-width:100%;--chatroom-correcting-color:var(--beet);--font-size-tiny:8px;--font-size-small:10px;--font-size-occupants:100%;--font-size:12px;--font-size-large:14px;--font-size-huge:18px;--chat-separator-border-bottom:2px solid var(--blue);--chatroom-separator-border-bottom:2px solid var(--blue);--message-background-color:#303030;--message-input-border-top:4px solid var(--blue);--message-mention-color:#404040;--message-mention-self-color:#AB3131;--message-separator-background-color:#2E1520;--embedded-emoji-picker-height:200px;--avatar-border-radius:50%;--fullpage-emoji-picker-height:200px;--overlayed-emoji-picker-height:100px;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--chat-content-background-color);--list-item-open-hover-color:var(--beet);--list-dot-circle-color:#f6dec1;scrollbar-color:var(--red) var(--occupants-background-color);scrollbar-width:thin}#conversejs.theme-redpill ::-webkit-scrollbar{width:5px;height:5px;background-color:vat(--darkest-grey)}#conversejs.theme-redpill ::-webkit-scrollbar-track-piece{background-color:var(--daskest-grey)}#conversejs.theme-redpill ::-webkit-scrollbar-thumb:vertical{height:15px;background-color:#fff}#conversejs.theme-redpill .scroller{width:300px;height:100px;overflow-y:scroll;scrollbar-color:#663399 green}#conversejs.theme-redpill #controlbox .bookmarks-toggle,#conversejs.theme-redpill #controlbox .bookmarks-toggle .fa{color:var(--orange)!important}#conversejs.theme-redpill #controlbox .bookmarks-toggle .fa:hover,#conversejs.theme-redpill #controlbox .bookmarks-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}#conversejs.theme-redpill .chatbox .chatroom .sendXMPPMessage{background-color:var(--message-background-color)}#conversejs.theme-redpill .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:red;color:#00f;padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);resize:none;border-radius:1em;border-width:.2em;margin-top:10px;padding-left:1em;width:70%;margin-left:10%}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea:active,#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea:focus{outline-color:unset!important;outline:unset!important}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea.spoiler{height:42px}#conversejs.theme-redpill .chatbox .sendXMPPMessage .chat-textarea.correcting{background-color:var(--chat-textarea-background-color)}#conversejs.theme-redpill .chatroom .sendXMPPMessage{background-color:var(--message-background-color)}#conversejs.theme-redpill .chatroom .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);resize:none;border-radius:1em;border-width:.2em;padding-left:1em;width:70%;margin-left:10%}#conversejs.theme-redpill .chatroom .chat-textarea.correcting{background-color:var(--chat-textarea-background-color);border-radius:1em;border-style:dotted;border-color:var(--red);padding-left:3em;width:70%;margin-left:10%}#conversejs.theme-redpill .chatroom .chat-textarea .chat-textarea:active,#conversejs.theme-redpill .chatroom .chat-textarea .chat-textarea:focus{outline-color:red!important}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .chat-info{color:var(--red)}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .occupants{border-left:unset}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .chatroom-form-container{backgorund-color:var(--dark-link-color)}#conversejs.theme-redpill .chatroom .box-flyout .chatroom-body .chatroom-form{background-color:var(--dark-link-color)}#conversejs.theme-redpill #controlbox .open-rooms-toggle,#conversejs.theme-redpill #controlbox .open-rooms-toggle .fa{color:var(--chatroom-head-bg-color-dark)!important}#conversejs.theme-redpill #controlbox .open-rooms-toggle .fa:hover,#conversejs.theme-redpill #controlbox .open-rooms-toggle:hover{color:var(--orange)!important}#conversejs.theme-redpill #controlbox .controlbox-section .controlbox-heading--groupchats{color:var(--orange)}#conversejs.theme-redpill #controlbox .controlbox-pane dd{background-color:var(--beet)}#conversejs.theme-redpill #controlbox .controlbox-panes{border-right:unset}#conversejs.theme-redpill .avatar{border-radius:var(--avatar-border-radius);border:none;background-color:unset}#conversejs.theme-redpill .dropdown-menu{color:#fff;background-color:var(--darkest-grey)}#conversejs.theme-redpill .dropdown-menu.selected,#conversejs.theme-redpill .dropdown-menu:active{color:red!important;background-color:var(--occupants-background-color)}#conversejs.theme-redpill .dropdown-item{color:#fff}#conversejs.theme-redpill .dropdown-item.selected,#conversejs.theme-redpill .dropdown-item:active{color:red!important;background-color:#00f}#conversejs.theme-redpill ::-webkit-scrollbar-thumb{background:red;border-radius:10px}#conversejs.theme-redpill ::-webkit-scrollbar-track{background:var(--beet)}#conversejs.theme-redpill .chatbox img.emoji{height:1.2em;width:1.2em;margin:0 .05em 0 .1em;vertical-align:-.1em}#conversejs.theme-redpill .chatbox .sendXMPPMessage .toggle-smiley a.toggle-smiley{padding:0}#conversejs.theme-redpill .chatbox converse-emoji-dropdown{display:inline-block}#conversejs.theme-redpill .chatbox converse-emoji-dropdown .dropdown-menu{padding:0}#conversejs.theme-redpill .chatbox converse-emoji-picker{width:100%;padding-top:0;padding-bottom:0;background-color:var(--occupants-background-color);overflow-y:hidden;background:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists{height:8em;overflow-y:auto;display:flex;flex-direction:column}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists .emoji-category__heading{clear:both;color:var(--subdued-color);cursor:auto;display:block;font-size:var(--font-size);margin:0;padding:.75em 0 0 .5em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists .emoji-lists__container{overflow-x:hidden}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__lists .emoji-picker li{float:left}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker{display:flex;padding:.5em 0;background-color:var(--occupants-background-color);width:auto;font-size:var(--font-size)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker label{margin:0;padding:0 .5em;white-space:nowrap;font-size:var(--font-size-small);color:var(--heading-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-skintone-picker ul li{padding:0 .25em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker{background-color:var(--occupants-background-color);padding:.5em 0 0 .5em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker:last-child{padding-bottom:.5em}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li{display:inline-block;height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden;margin-left:0;list-style:none;position:relative}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji{padding:0 .2em;height:auto;width:auto;margin:0;display:block;text-align:center}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji.selected a{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji img{margin:0 auto;height:var(--font-size-huge);width:var(--font-size-huge);display:inline-block;vertical-align:baseline}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a{padding:3px;display:inline-block;font-size:var(--font-size-huge);line-height:calc(var(--font-size-huge) * 1.5);height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a:hover{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header{display:flex;flex-direction:column;padding:.1em 0;background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header .emoji-search{width:auto;margin:.25em;height:2em;font-size:var(--font-size-small)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul{display:flex;flex-direction:row;flex-wrap:wrap}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category{padding:.25em 0;font-size:var(--font-size-huge)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{background-color:var(--occupants-background-color);border:1px var(--chat-head-color) solid;border-bottom:none}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.selected a,#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category:hover a{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category a{padding:.25em;display:inline-block}#conversejs.theme-redpill .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category img{height:var(--font-size-huge);width:var(--font-size-huge)}#conversejs.theme-redpill .chatroom converse-emoji-picker{background-color:var(--occupants-background-color);background:#fff}#conversejs.theme-redpill .chatroom converse-emoji-picker .emoji-skintone-picker{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatroom converse-emoji-picker .emoji-picker__header{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .chatroom converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{border:1px var(--chatroom-head-bg-color) solid;border-bottom:none}#conversejs.theme-redpill .items-list .list-item:hover{color:var(--text-color);background-color:var(--beet)}#conversejs.theme-redpill .items-list .list-item:hover .fa,#conversejs.theme-redpill .items-list .list-item:hover .far,#conversejs.theme-redpill .items-list .list-item:hover .fas{opacity:1}#conversejs.theme-redpill .items-list .list-item.open{border-left:4px solid var(--red);background-color:var(--list-item-open-color)}#conversejs.theme-redpill .items-list .list-item.open:hover{color:var(--text-color);background-color:var(--list-item-open-hover-color)!important}#conversejs.theme-redpill .items-list .list-item-badge{color:#fff;float:right;text-align:center;width:22px;background-color:var(--red);border-radius:50%;padding:.5em;font-size:var(--font-size-small)}#conversejs.theme-redpill .message .mention{font-weight:700;border-style:solid;border-width:0;border-radius:25px;background-color:var(--message-mention-color);color:#fff;padding:.2em}#conversejs.theme-redpill .message .mention--self{font-weight:700;border-radius:15px;background:var(--message-mention-self-color);color:var(--redder-orange)}#conversejs.theme-redpill .message.correcting.groupchat{background-color:unset;border-style:dotted;border-radius:1em;border-color:var(--red);border-width:.2em}#conversejs.theme-redpill .message.correcting:not(.groupchat){background-color:unset;border-style:solid;border-radius:1em;border-color:var(--red)}#conversejs.theme-redpill .message .chat-msg__heading .chat-msg__author{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--orange);font-family:var(--heading-font);font-size:115%;font-weight:700;padding-bottom:1px}#conversejs.theme-redpill .chat-msg__text{display:inline;color:var(--message-text-color);padding:10px;white-space:pre-wrap;word-wrap:break-word;word-break:break-word;line-height:1.7em}#conversejs.theme-redpill .chat-msg__message{display:inline-flex;flex-direction:column;width:unset;overflow-wrap:break-word}#conversejs.theme-redpill .chat-msg__avatar{height:var(--message-avatar-height);width:var(--message-avatar-width);display:block;margin-left:auto;margin-right:auto;background-size:cover}#conversejs.theme-redpill .message .mention{font-weight:700}#conversejs.theme-redpill .message .mention--self{font-weight:400}#conversejs.theme-redpill .message.date-separator{height:2em;margin:0;position:relative;text-align:center;z-index:0}#conversejs.theme-redpill .message.date-separator .separator{border-top:0;border-bottom:var(--global-background-color);border-style:solid}#conversejs.theme-redpill .message.date-separator .separator-text{background:var(--global-background-color);bottom:1px;color:var(--chatbox-separator-text);display:inline-block;line-height:2em;padding:0 1em;position:relative;z-index:5;border-style:solid;border-radius:2em;border-width:0}#conversejs.theme-redpill .chat-image{border-radius:2em;max-height:25em;transition:.5s;border:0;margin-left:5em;margin-top:2em}#conversejs.theme-redpill .chat-image:hover{-webkit-filter:grayscale(1);filter:grayscale(1)}#conversejs.theme-redpill .img-thumbnail{background-color:unset}#conversejs.theme-redpill .message.chat-msg .chat-msg__media{margin-top:.25rem;word-break:break-all}#conversejs.theme-redpill .message.chat-msg .chat-msg__media a{word-wrap:break-word}#conversejs.theme-redpill .message.chat-msg .chat-msg__media audio{width:50%;background-color:unset;color:var(--beet)}#conversejs.theme-redpill #converse-modals .modal-header{background-color:var(--beet);border-bottom:none}#conversejs.theme-redpill #converse-modals .modal-header .close{color:#fff;background-color:var(--red)}#conversejs.theme-redpill #converse-modals .modal-body{background-color:var(--chat-content-background-color)}#conversejs.theme-redpill #converse-modals .form-control{color:#fff;background-color:var(--darkest-grey);border:1px solid var(--darkest-grey)}#conversejs.theme-redpill #converse-modals .modal-content{background-color:var(--darkest-grey)}#conversejs.theme-redpill #converse-modals .modal-footer{border-top:none}#conversejs.theme-redpill #converse-modals .list-group-item{background-color:var(--darkest-grey)}#conversejs.theme-redpill #converse-roster .roster-contacts .current-xmpp-contact .chat-status{vertical-align:middle;font-size:1em;margin-right:0;margin-left:-.8em;margin-bottom:-1.5em;border-radius:50%;border:2px solid var(--occupants-background-color)}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle,#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle .fa{color:var(--beet-light-green)!important}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle .fa:hover,#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group .group-toggle:hover{color:var(--beet-green)!important}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group li .open-chat .msgs-indicator{float:right;color:#fff;text-align:center;width:22px;background-color:var(--red);border-radius:50%;padding:.5em;font-size:var(--font-size-small)}#conversejs.theme-redpill #converse-roster .roster-contacts .roster-group li .open-chat:hover{background-color:var(--beet)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar{background-color:var(--chat-content-background-color);box-sizing:border-box;color:var(--text-color);display:flex;justify-content:space-between;margin:0;width:100%}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa:hover,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far:hover,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas:hover{color:var(--font-head-color);font-size:var(--font-size-huge)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fa:hover svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .far:hover svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas svg,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .fas:hover svg{fill:var(--text-color)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted a{color:var(--text-color)}#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted .toolbar-menu a,#conversejs.theme-redpill .chat-toolbar converse-chat-toolbar .unencrypted a .toolbar-menu a{color:var(--link-color)}#conversejs.theme-redpill .chat-toolbar .toolbar-buttons{width:100%;display:inline-block}#conversejs.theme-redpill .chat-toolbar .toolbar-buttons .message-limit{padding:.5em;font-weight:700}#conversejs.theme-redpill .chat-toolbar button{margin-top:.4em;border:1px transparent solid;background-color:transparent}#conversejs.theme-redpill .chat-toolbar button:disabled .fa{color:grey}#conversejs.theme-redpill .chat-toolbar button:disabled .fa:hover{color:grey}#conversejs.theme-redpill .chat-toolbar button:disabled .fa svg,#conversejs.theme-redpill .chat-toolbar button:disabled .fa svg:hover{fill:grey}#conversejs.theme-redpill .chat-toolbar button.send-button{padding-top:.2em;padding-bottom:.2em;margin:0;margin-top:-1px}#conversejs.theme-redpill .chat-toolbar .unverified,#conversejs.theme-redpill .chat-toolbar .unverified a{color:#cf5300}#conversejs.theme-redpill .chat-toolbar .private,#conversejs.theme-redpill .chat-toolbar .private a{color:#4b7003}#conversejs.theme-redpill .chat-toolbar li{cursor:pointer;display:inline-block;list-style:none;padding:0 .5em}#conversejs.theme-redpill .chat-toolbar li:hover{cursor:pointer}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu{background-color:var(--chat-content-background-color);bottom:1.7rem;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);height:auto;margin-bottom:0;min-width:21rem;position:absolute;right:0;top:auto;z-index:1000}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu.otr-menu{left:-6em;min-width:15rem}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu.otr-menu.show{display:flex;flex-direction:column}#conversejs.theme-redpill .chat-toolbar li .toolbar-menu a{color:var(--link-color)}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul{z-index:99}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul li{display:block;padding:7px}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul li:hover{background-color:var(--highlight-color)}#conversejs.theme-redpill .chat-toolbar li.toggle-otr ul li a{display:block}#conversejs.theme-redpill .chatbox converse-chat-toolbar{border-top:var(--red);color:var(--text-color);background-color:var(--chat-content-background-color)}#conversejs.theme-redpill .chatbox converse-chat-toolbar .fa,#conversejs.theme-redpill .chatbox converse-chat-toolbar .fa:hover,#conversejs.theme-redpill .chatbox converse-chat-toolbar .far,#conversejs.theme-redpill .chatbox converse-chat-toolbar .far:hover,#conversejs.theme-redpill .chatbox converse-chat-toolbar .fas,#conversejs.theme-redpill .chatbox converse-chat-toolbar .fas:hover{color:var(--dark-link-color)}#conversejs.theme-redpill .chatbox converse-chat-toolbar button:focus{outline-color:unset!important;color:var(--red)}#conversejs.theme-redpill .chatroom converse-chat-toolbar{border-top:var(--chatroom-message-input-border-top);color:var(--text-color)}#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa:hover,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far:hover,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas:hover{color:var(--dark-link-color);font-size:var(--font-size-huge)}#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fa:hover svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .far:hover svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas svg,#conversejs.theme-redpill .chatroom converse-chat-toolbar .fas:hover svg{fill:var(--text-color)}#conversejs.theme-redpill .chatroom converse-chat-toolbar button:focus{outline-color:unset!important}#conversejs.theme-redpill .suggestion-box{background-color:var(--occupants-background-color)}#conversejs.theme-redpill .suggestion-box .suggestion-box__results,#conversejs.theme-redpill .suggestion-box>ul{position:absolute;left:0;right:0;z-index:2;min-width:100%;box-sizing:border-box;list-style:none;padding:0;border-radius:.3em;margin:.2em 0 0;background:rgba(37,36,36,.9);border:1px solid rgba(0,0,0,.3);box-shadow:.05em .2em .6em rgba(0,0,0,.1);text-shadow:none}#conversejs.theme-redpill .suggestion-box .suggestion-box__results:before,#conversejs.theme-redpill .suggestion-box>ul:before{content:\"\";position:absolute;top:-.43em;left:1em;width:0;height:0;padding:.4em;background:var(--red);border:inherit;border-right:0;border-bottom:0;transform:rotate(45deg);z-index:-1}#conversejs.theme-redpill .suggestion-box .suggestion-box__results>li,#conversejs.theme-redpill .suggestion-box>ul>li{text-overflow:ellipsis;overflow-x:hidden;position:relative;cursor:pointer;padding:1em}"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/converse.js b/dist/converse.js new file mode 100644 index 0000000..7084e4c --- /dev/null +++ b/dist/converse.js @@ -0,0 +1,110249 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ function webpackJsonpCallback(data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ +/******/ +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(data); +/******/ +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ }; +/******/ +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 178: 0 +/******/ }; +/******/ +/******/ +/******/ +/******/ // script path function +/******/ function jsonpScriptSrc(chunkId) { +/******/ return __webpack_require__.p + "" + ({"0":"locales/dayjs/af","1":"locales/dayjs/ar","2":"locales/dayjs/ar-dz","3":"locales/dayjs/ar-kw","4":"locales/dayjs/ar-ly","5":"locales/dayjs/ar-ma","6":"locales/dayjs/ar-sa","7":"locales/dayjs/ar-tn","8":"locales/dayjs/az","9":"locales/dayjs/be","10":"locales/dayjs/bg","11":"locales/dayjs/bi","12":"locales/dayjs/bm","13":"locales/dayjs/bn","14":"locales/dayjs/bo","15":"locales/dayjs/br","16":"locales/dayjs/bs","17":"locales/dayjs/ca","18":"locales/dayjs/cs","19":"locales/dayjs/cv","20":"locales/dayjs/cy","21":"locales/dayjs/da","22":"locales/dayjs/de","23":"locales/dayjs/de-at","24":"locales/dayjs/de-ch","25":"locales/dayjs/dv","26":"locales/dayjs/el","27":"locales/dayjs/en","28":"locales/dayjs/en-SG","29":"locales/dayjs/en-au","30":"locales/dayjs/en-ca","31":"locales/dayjs/en-gb","32":"locales/dayjs/en-ie","33":"locales/dayjs/en-il","34":"locales/dayjs/en-in","35":"locales/dayjs/en-nz","36":"locales/dayjs/en-tt","37":"locales/dayjs/eo","38":"locales/dayjs/es","39":"locales/dayjs/es-do","40":"locales/dayjs/es-pr","41":"locales/dayjs/es-us","42":"locales/dayjs/et","43":"locales/dayjs/eu","44":"locales/dayjs/fa","45":"locales/dayjs/fi","46":"locales/dayjs/fo","47":"locales/dayjs/fr","48":"locales/dayjs/fr-ca","49":"locales/dayjs/fr-ch","50":"locales/dayjs/fy","51":"locales/dayjs/ga","52":"locales/dayjs/gd","53":"locales/dayjs/gl","54":"locales/dayjs/gom-latn","55":"locales/dayjs/gu","56":"locales/dayjs/he","57":"locales/dayjs/hi","58":"locales/dayjs/hr","59":"locales/dayjs/ht","60":"locales/dayjs/hu","61":"locales/dayjs/hy-am","62":"locales/dayjs/id","63":"locales/dayjs/is","64":"locales/dayjs/it","65":"locales/dayjs/it-ch","66":"locales/dayjs/ja","67":"locales/dayjs/jv","68":"locales/dayjs/ka","69":"locales/dayjs/kk","70":"locales/dayjs/km","71":"locales/dayjs/kn","72":"locales/dayjs/ko","73":"locales/dayjs/ku","74":"locales/dayjs/ky","75":"locales/dayjs/lb","76":"locales/dayjs/lo","77":"locales/dayjs/lt","78":"locales/dayjs/lv","79":"locales/dayjs/me","80":"locales/dayjs/mi","81":"locales/dayjs/mk","82":"locales/dayjs/ml","83":"locales/dayjs/mn","84":"locales/dayjs/mr","85":"locales/dayjs/ms","86":"locales/dayjs/ms-my","87":"locales/dayjs/mt","88":"locales/dayjs/my","89":"locales/dayjs/nb","90":"locales/dayjs/ne","91":"locales/dayjs/nl","92":"locales/dayjs/nl-be","93":"locales/dayjs/nn","94":"locales/dayjs/oc-lnc","95":"locales/dayjs/pa-in","96":"locales/dayjs/pl","97":"locales/dayjs/pt","98":"locales/dayjs/pt-br","99":"locales/dayjs/ro","100":"locales/dayjs/ru","101":"locales/dayjs/rw","102":"locales/dayjs/sd","103":"locales/dayjs/se","104":"locales/dayjs/si","105":"locales/dayjs/sk","106":"locales/dayjs/sl","107":"locales/dayjs/sq","108":"locales/dayjs/sr","109":"locales/dayjs/sr-cyrl","110":"locales/dayjs/ss","111":"locales/dayjs/sv","112":"locales/dayjs/sw","113":"locales/dayjs/ta","114":"locales/dayjs/te","115":"locales/dayjs/tet","116":"locales/dayjs/tg","117":"locales/dayjs/th","118":"locales/dayjs/tk","119":"locales/dayjs/tl-ph","120":"locales/dayjs/tlh","121":"locales/dayjs/tr","122":"locales/dayjs/tzl","123":"locales/dayjs/tzm","124":"locales/dayjs/tzm-latn","125":"locales/dayjs/ug-cn","126":"locales/dayjs/uk","127":"locales/dayjs/ur","128":"locales/dayjs/uz","129":"locales/dayjs/uz-latn","130":"locales/dayjs/vi","131":"locales/dayjs/x-pseudo","132":"locales/dayjs/yo","133":"locales/dayjs/zh","134":"locales/dayjs/zh-cn","135":"locales/dayjs/zh-hk","136":"locales/dayjs/zh-tw","137":"emojis","138":"icons","139":"locales/af-LC_MESSAGES-converse-po","140":"locales/ar-LC_MESSAGES-converse-po","141":"locales/bg-LC_MESSAGES-converse-po","142":"locales/ca-LC_MESSAGES-converse-po","143":"locales/cs-LC_MESSAGES-converse-po","144":"locales/da-LC_MESSAGES-converse-po","145":"locales/dayjs/index-d-ts","146":"locales/dayjs/types-d-ts","147":"locales/de-LC_MESSAGES-converse-po","148":"locales/eo-LC_MESSAGES-converse-po","149":"locales/es-LC_MESSAGES-converse-po","150":"locales/eu-LC_MESSAGES-converse-po","151":"locales/fi-LC_MESSAGES-converse-po","152":"locales/fr-LC_MESSAGES-converse-po","153":"locales/gl-LC_MESSAGES-converse-po","154":"locales/he-LC_MESSAGES-converse-po","155":"locales/hi-LC_MESSAGES-converse-po","156":"locales/hu-LC_MESSAGES-converse-po","157":"locales/id-LC_MESSAGES-converse-po","158":"locales/it-LC_MESSAGES-converse-po","159":"locales/ja-LC_MESSAGES-converse-po","160":"locales/lt-LC_MESSAGES-converse-po","161":"locales/mr-LC_MESSAGES-converse-po","162":"locales/nb-LC_MESSAGES-converse-po","163":"locales/nl-LC_MESSAGES-converse-po","164":"locales/nl_BE-LC_MESSAGES-converse-po","165":"locales/oc-LC_MESSAGES-converse-po","166":"locales/pl-LC_MESSAGES-converse-po","167":"locales/pt-LC_MESSAGES-converse-po","168":"locales/pt_BR-LC_MESSAGES-converse-po","169":"locales/ro-LC_MESSAGES-converse-po","170":"locales/ru-LC_MESSAGES-converse-po","171":"locales/sv-LC_MESSAGES-converse-po","172":"locales/th-LC_MESSAGES-converse-po","173":"locales/tr-LC_MESSAGES-converse-po","174":"locales/uk-LC_MESSAGES-converse-po","175":"locales/vi-LC_MESSAGES-converse-po","176":"locales/zh_CN-LC_MESSAGES-converse-po","177":"locales/zh_TW-LC_MESSAGES-converse-po"}[chunkId]||chunkId) + ".js" +/******/ } +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = function requireEnsure(chunkId) { +/******/ var promises = []; +/******/ +/******/ +/******/ // JSONP chunk loading for javascript +/******/ +/******/ var installedChunkData = installedChunks[chunkId]; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[2]); +/******/ } else { +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise(function(resolve, reject) { +/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; +/******/ }); +/******/ promises.push(installedChunkData[2] = promise); +/******/ +/******/ // start chunk loading +/******/ var script = document.createElement('script'); +/******/ var onScriptComplete; +/******/ +/******/ script.charset = 'utf-8'; +/******/ script.timeout = 120; +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.src = jsonpScriptSrc(chunkId); +/******/ +/******/ // create error before stack unwound to get useful stacktrace later +/******/ var error = new Error(); +/******/ onScriptComplete = function (event) { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var chunk = installedChunks[chunkId]; +/******/ if(chunk !== 0) { +/******/ if(chunk) { +/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); +/******/ var realSrc = event && event.target && event.target.src; +/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; +/******/ error.name = 'ChunkLoadError'; +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ chunk[1](error); +/******/ } +/******/ installedChunks[chunkId] = undefined; +/******/ } +/******/ }; +/******/ var timeout = setTimeout(function(){ +/******/ onScriptComplete({ type: 'timeout', target: script }); +/******/ }, 120000); +/******/ script.onerror = script.onload = onScriptComplete; +/******/ document.head.appendChild(script); +/******/ } +/******/ } +/******/ return Promise.all(promises); +/******/ }; +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "/dist/"; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ +/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; +/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); +/******/ jsonpArray.push = webpackJsonpCallback; +/******/ jsonpArray = jsonpArray.slice(); +/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); +/******/ var parentJsonpFunction = oldJsonpFunction; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 326); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, "a", function() { return /* binding */ $build; }); +__webpack_require__.d(__webpack_exports__, "c", function() { return /* binding */ $msg; }); +__webpack_require__.d(__webpack_exports__, "b", function() { return /* binding */ $iq; }); +__webpack_require__.d(__webpack_exports__, "d", function() { return /* binding */ $pres; }); +__webpack_require__.d(__webpack_exports__, "e", function() { return /* binding */ Strophe; }); + +// UNUSED EXPORTS: SHA1, MD5 + +// EXTERNAL MODULE: ./src/headless/node_modules/strophe.js/src/shims.js +var shims = __webpack_require__(15); + +// CONCATENATED MODULE: ./src/headless/node_modules/strophe.js/src/md5.js +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/* + * Everything that isn't used by Strophe has been stripped here! + */ + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +const safe_add = function safe_add(x, y) { + const lsw = (x & 0xFFFF) + (y & 0xFFFF); + const msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return msw << 16 | lsw & 0xFFFF; +}; +/* + * Bitwise rotate a 32-bit number to the left. + */ + + +const bit_rol = function bit_rol(num, cnt) { + return num << cnt | num >>> 32 - cnt; +}; +/* + * Convert a string to an array of little-endian words + */ + + +const str2binl = function str2binl(str) { + if (typeof str !== "string") { + throw new Error("str2binl was passed a non-string"); + } + + const bin = []; + + for (let i = 0; i < str.length * 8; i += 8) { + bin[i >> 5] |= (str.charCodeAt(i / 8) & 255) << i % 32; + } + + return bin; +}; +/* + * Convert an array of little-endian words to a string + */ + + +const binl2str = function binl2str(bin) { + let str = ""; + + for (let i = 0; i < bin.length * 32; i += 8) { + str += String.fromCharCode(bin[i >> 5] >>> i % 32 & 255); + } + + return str; +}; +/* + * Convert an array of little-endian words to a hex string. + */ + + +const binl2hex = function binl2hex(binarray) { + const hex_tab = "0123456789abcdef"; + let str = ""; + + for (let i = 0; i < binarray.length * 4; i++) { + str += hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 + 4 & 0xF) + hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 & 0xF); + } + + return str; +}; +/* + * These functions implement the four basic operations the algorithm uses. + */ + + +const md5_cmn = function md5_cmn(q, a, b, x, s, t) { + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); +}; + +const md5_ff = function md5_ff(a, b, c, d, x, s, t) { + return md5_cmn(b & c | ~b & d, a, b, x, s, t); +}; + +const md5_gg = function md5_gg(a, b, c, d, x, s, t) { + return md5_cmn(b & d | c & ~d, a, b, x, s, t); +}; + +const md5_hh = function md5_hh(a, b, c, d, x, s, t) { + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +}; + +const md5_ii = function md5_ii(a, b, c, d, x, s, t) { + return md5_cmn(c ^ (b | ~d), a, b, x, s, t); +}; +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ + + +const core_md5 = function core_md5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[(len + 64 >>> 9 << 4) + 14] = len; + let a = 1732584193; + let b = -271733879; + let c = -1732584194; + let d = 271733878; + let olda, oldb, oldc, oldd; + + for (let i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936); + d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); + a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); + a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); + a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844); + d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + + return [a, b, c, d]; +}; +/* + * These are the functions you'll usually want to call. + * They take string arguments and return either hex or base-64 encoded + * strings. + */ + + +const MD5 = { + hexdigest: function hexdigest(s) { + return binl2hex(core_md5(str2binl(s), s.length * 8)); + }, + hash: function hash(s) { + return binl2str(core_md5(str2binl(s), s.length * 8)); + } +}; + +// EXTERNAL MODULE: ./src/headless/node_modules/strophe.js/src/sha1.js +var sha1 = __webpack_require__(7); + +// CONCATENATED MODULE: ./src/headless/node_modules/strophe.js/src/utils.js +const utils = { + utf16to8: function utf16to8(str) { + var i, c; + var out = ""; + var len = str.length; + + for (i = 0; i < len; i++) { + c = str.charCodeAt(i); + + if (c >= 0x0000 && c <= 0x007F) { + out += str.charAt(i); + } else if (c > 0x07FF) { + out += String.fromCharCode(0xE0 | c >> 12 & 0x0F); + out += String.fromCharCode(0x80 | c >> 6 & 0x3F); + out += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } else { + out += String.fromCharCode(0xC0 | c >> 6 & 0x1F); + out += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } + } + + return out; + }, + addCookies: function addCookies(cookies) { + /* Parameters: + * (Object) cookies - either a map of cookie names + * to string values or to maps of cookie values. + * + * For example: + * { "myCookie": "1234" } + * + * or: + * { "myCookie": { + * "value": "1234", + * "domain": ".example.org", + * "path": "/", + * "expires": expirationDate + * } + * } + * + * These values get passed to Strophe.Connection via + * options.cookies + */ + cookies = cookies || {}; + + for (const cookieName in cookies) { + if (Object.prototype.hasOwnProperty.call(cookies, cookieName)) { + let expires = ''; + let domain = ''; + let path = ''; + const cookieObj = cookies[cookieName]; + const isObj = typeof cookieObj === "object"; + const cookieValue = escape(unescape(isObj ? cookieObj.value : cookieObj)); + + if (isObj) { + expires = cookieObj.expires ? ";expires=" + cookieObj.expires : ''; + domain = cookieObj.domain ? ";domain=" + cookieObj.domain : ''; + path = cookieObj.path ? ";path=" + cookieObj.path : ''; + } + + document.cookie = cookieName + '=' + cookieValue + expires + domain + path; + } + } + } +}; + +// EXTERNAL MODULE: ./node_modules/abab/index.js +var abab = __webpack_require__(10); + +// CONCATENATED MODULE: ./src/headless/node_modules/strophe.js/src/core.js +/* + This program is distributed under the terms of the MIT license. + Please see the LICENSE file for details. + + Copyright 2006-2018, OGG, LLC +*/ + +/*global define, document, sessionStorage, setTimeout, clearTimeout, ActiveXObject, DOMParser, btoa, atob */ + + + + + +/** Function: $build + * Create a Strophe.Builder. + * This is an alias for 'new Strophe.Builder(name, attrs)'. + * + * Parameters: + * (String) name - The root element name. + * (Object) attrs - The attributes for the root element in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $build(name, attrs) { + return new Strophe.Builder(name, attrs); +} +/** Function: $msg + * Create a Strophe.Builder with a element as the root. + * + * Parameters: + * (Object) attrs - The element attributes in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $msg(attrs) { + return new Strophe.Builder("message", attrs); +} +/** Function: $iq + * Create a Strophe.Builder with an element as the root. + * + * Parameters: + * (Object) attrs - The element attributes in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $iq(attrs) { + return new Strophe.Builder("iq", attrs); +} +/** Function: $pres + * Create a Strophe.Builder with a element as the root. + * + * Parameters: + * (Object) attrs - The element attributes in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $pres(attrs) { + return new Strophe.Builder("presence", attrs); +} +/** Class: Strophe + * An object container for all Strophe library functions. + * + * This class is just a container for all the objects and constants + * used in the library. It is not meant to be instantiated, but to + * provide a namespace for library objects, constants, and functions. + */ + +const Strophe = { + /** Constant: VERSION */ + VERSION: "1.3.6", + + /** Constants: XMPP Namespace Constants + * Common namespace constants from the XMPP RFCs and XEPs. + * + * NS.HTTPBIND - HTTP BIND namespace from XEP 124. + * NS.BOSH - BOSH namespace from XEP 206. + * NS.CLIENT - Main XMPP client namespace. + * NS.AUTH - Legacy authentication namespace. + * NS.ROSTER - Roster operations namespace. + * NS.PROFILE - Profile namespace. + * NS.DISCO_INFO - Service discovery info namespace from XEP 30. + * NS.DISCO_ITEMS - Service discovery items namespace from XEP 30. + * NS.MUC - Multi-User Chat namespace from XEP 45. + * NS.SASL - XMPP SASL namespace from RFC 3920. + * NS.STREAM - XMPP Streams namespace from RFC 3920. + * NS.BIND - XMPP Binding namespace from RFC 3920 and RFC 6120. + * NS.SESSION - XMPP Session namespace from RFC 3920. + * NS.XHTML_IM - XHTML-IM namespace from XEP 71. + * NS.XHTML - XHTML body namespace from XEP 71. + */ + NS: { + HTTPBIND: "http://jabber.org/protocol/httpbind", + BOSH: "urn:xmpp:xbosh", + CLIENT: "jabber:client", + AUTH: "jabber:iq:auth", + ROSTER: "jabber:iq:roster", + PROFILE: "jabber:iq:profile", + DISCO_INFO: "http://jabber.org/protocol/disco#info", + DISCO_ITEMS: "http://jabber.org/protocol/disco#items", + MUC: "http://jabber.org/protocol/muc", + SASL: "urn:ietf:params:xml:ns:xmpp-sasl", + STREAM: "http://etherx.jabber.org/streams", + FRAMING: "urn:ietf:params:xml:ns:xmpp-framing", + BIND: "urn:ietf:params:xml:ns:xmpp-bind", + SESSION: "urn:ietf:params:xml:ns:xmpp-session", + VERSION: "jabber:iq:version", + STANZAS: "urn:ietf:params:xml:ns:xmpp-stanzas", + XHTML_IM: "http://jabber.org/protocol/xhtml-im", + XHTML: "http://www.w3.org/1999/xhtml" + }, + + /** Constants: XHTML_IM Namespace + * contains allowed tags, tag attributes, and css properties. + * Used in the createHtml function to filter incoming html into the allowed XHTML-IM subset. + * See http://xmpp.org/extensions/xep-0071.html#profile-summary for the list of recommended + * allowed tags and their attributes. + */ + XHTML: { + tags: ['a', 'blockquote', 'br', 'cite', 'em', 'img', 'li', 'ol', 'p', 'span', 'strong', 'ul', 'body'], + attributes: { + 'a': ['href'], + 'blockquote': ['style'], + 'br': [], + 'cite': ['style'], + 'em': [], + 'img': ['src', 'alt', 'style', 'height', 'width'], + 'li': ['style'], + 'ol': ['style'], + 'p': ['style'], + 'span': ['style'], + 'strong': [], + 'ul': ['style'], + 'body': [] + }, + css: ['background-color', 'color', 'font-family', 'font-size', 'font-style', 'font-weight', 'margin-left', 'margin-right', 'text-align', 'text-decoration'], + + /** Function: XHTML.validTag + * + * Utility method to determine whether a tag is allowed + * in the XHTML_IM namespace. + * + * XHTML tag names are case sensitive and must be lower case. + */ + validTag(tag) { + for (let i = 0; i < Strophe.XHTML.tags.length; i++) { + if (tag === Strophe.XHTML.tags[i]) { + return true; + } + } + + return false; + }, + + /** Function: XHTML.validAttribute + * + * Utility method to determine whether an attribute is allowed + * as recommended per XEP-0071 + * + * XHTML attribute names are case sensitive and must be lower case. + */ + validAttribute(tag, attribute) { + if (typeof Strophe.XHTML.attributes[tag] !== 'undefined' && Strophe.XHTML.attributes[tag].length > 0) { + for (let i = 0; i < Strophe.XHTML.attributes[tag].length; i++) { + if (attribute === Strophe.XHTML.attributes[tag][i]) { + return true; + } + } + } + + return false; + }, + + validCSS(style) { + for (let i = 0; i < Strophe.XHTML.css.length; i++) { + if (style === Strophe.XHTML.css[i]) { + return true; + } + } + + return false; + } + + }, + + /** Constants: Connection Status Constants + * Connection status constants for use by the connection handler + * callback. + * + * Status.ERROR - An error has occurred + * Status.CONNECTING - The connection is currently being made + * Status.CONNFAIL - The connection attempt failed + * Status.AUTHENTICATING - The connection is authenticating + * Status.AUTHFAIL - The authentication attempt failed + * Status.CONNECTED - The connection has succeeded + * Status.DISCONNECTED - The connection has been terminated + * Status.DISCONNECTING - The connection is currently being terminated + * Status.ATTACHED - The connection has been attached + * Status.REDIRECT - The connection has been redirected + * Status.CONNTIMEOUT - The connection has timed out + */ + Status: { + ERROR: 0, + CONNECTING: 1, + CONNFAIL: 2, + AUTHENTICATING: 3, + AUTHFAIL: 4, + CONNECTED: 5, + DISCONNECTED: 6, + DISCONNECTING: 7, + ATTACHED: 8, + REDIRECT: 9, + CONNTIMEOUT: 10, + BINDREQUIRED: 11, + ATTACHFAIL: 12 + }, + ErrorCondition: { + BAD_FORMAT: "bad-format", + CONFLICT: "conflict", + MISSING_JID_NODE: "x-strophe-bad-non-anon-jid", + NO_AUTH_MECH: "no-auth-mech", + UNKNOWN_REASON: "unknown" + }, + + /** Constants: Log Level Constants + * Logging level indicators. + * + * LogLevel.DEBUG - Debug output + * LogLevel.INFO - Informational output + * LogLevel.WARN - Warnings + * LogLevel.ERROR - Errors + * LogLevel.FATAL - Fatal errors + */ + LogLevel: { + DEBUG: 0, + INFO: 1, + WARN: 2, + ERROR: 3, + FATAL: 4 + }, + + /** PrivateConstants: DOM Element Type Constants + * DOM element types. + * + * ElementType.NORMAL - Normal element. + * ElementType.TEXT - Text data element. + * ElementType.FRAGMENT - XHTML fragment element. + */ + ElementType: { + NORMAL: 1, + TEXT: 3, + CDATA: 4, + FRAGMENT: 11 + }, + + /** PrivateConstants: Timeout Values + * Timeout values for error states. These values are in seconds. + * These should not be changed unless you know exactly what you are + * doing. + * + * TIMEOUT - Timeout multiplier. A waiting request will be considered + * failed after Math.floor(TIMEOUT * wait) seconds have elapsed. + * This defaults to 1.1, and with default wait, 66 seconds. + * SECONDARY_TIMEOUT - Secondary timeout multiplier. In cases where + * Strophe can detect early failure, it will consider the request + * failed if it doesn't return after + * Math.floor(SECONDARY_TIMEOUT * wait) seconds have elapsed. + * This defaults to 0.1, and with default wait, 6 seconds. + */ + TIMEOUT: 1.1, + SECONDARY_TIMEOUT: 0.1, + + /** Function: addNamespace + * This function is used to extend the current namespaces in + * Strophe.NS. It takes a key and a value with the key being the + * name of the new namespace, with its actual value. + * For example: + * Strophe.addNamespace('PUBSUB', "http://jabber.org/protocol/pubsub"); + * + * Parameters: + * (String) name - The name under which the namespace will be + * referenced under Strophe.NS + * (String) value - The actual namespace. + */ + addNamespace(name, value) { + Strophe.NS[name] = value; + }, + + /** Function: forEachChild + * Map a function over some or all child elements of a given element. + * + * This is a small convenience function for mapping a function over + * some or all of the children of an element. If elemName is null, all + * children will be passed to the function, otherwise only children + * whose tag names match elemName will be passed. + * + * Parameters: + * (XMLElement) elem - The element to operate on. + * (String) elemName - The child element tag name filter. + * (Function) func - The function to apply to each child. This + * function should take a single argument, a DOM element. + */ + forEachChild(elem, elemName, func) { + for (let i = 0; i < elem.childNodes.length; i++) { + const childNode = elem.childNodes[i]; + + if (childNode.nodeType === Strophe.ElementType.NORMAL && (!elemName || this.isTagEqual(childNode, elemName))) { + func(childNode); + } + } + }, + + /** Function: isTagEqual + * Compare an element's tag name with a string. + * + * This function is case sensitive. + * + * Parameters: + * (XMLElement) el - A DOM element. + * (String) name - The element name. + * + * Returns: + * true if the element's tag name matches _el_, and false + * otherwise. + */ + isTagEqual(el, name) { + return el.tagName === name; + }, + + /** PrivateVariable: _xmlGenerator + * _Private_ variable that caches a DOM document to + * generate elements. + */ + _xmlGenerator: null, + + /** Function: xmlGenerator + * Get the DOM document to generate elements. + * + * Returns: + * The currently used DOM document. + */ + xmlGenerator() { + if (!Strophe._xmlGenerator) { + Strophe._xmlGenerator = shims["b" /* getDummyXMLDOMDocument */](); + } + + return Strophe._xmlGenerator; + }, + + /** Function: xmlElement + * Create an XML DOM element. + * + * This function creates an XML DOM element correctly across all + * implementations. Note that these are not HTML DOM elements, which + * aren't appropriate for XMPP stanzas. + * + * Parameters: + * (String) name - The name for the element. + * (Array|Object) attrs - An optional array or object containing + * key/value pairs to use as element attributes. The object should + * be in the format {'key': 'value'} or {key: 'value'}. The array + * should have the format [['key1', 'value1'], ['key2', 'value2']]. + * (String) text - The text child data for the element. + * + * Returns: + * A new XML DOM element. + */ + xmlElement(name) { + if (!name) { + return null; + } + + const node = Strophe.xmlGenerator().createElement(name); // FIXME: this should throw errors if args are the wrong type or + // there are more than two optional args + + for (let a = 1; a < arguments.length; a++) { + const arg = arguments[a]; + + if (!arg) { + continue; + } + + if (typeof arg === "string" || typeof arg === "number") { + node.appendChild(Strophe.xmlTextNode(arg)); + } else if (typeof arg === "object" && typeof arg.sort === "function") { + for (let i = 0; i < arg.length; i++) { + const attr = arg[i]; + + if (typeof attr === "object" && typeof attr.sort === "function" && attr[1] !== undefined && attr[1] !== null) { + node.setAttribute(attr[0], attr[1]); + } + } + } else if (typeof arg === "object") { + for (const k in arg) { + if (Object.prototype.hasOwnProperty.call(arg, k) && arg[k] !== undefined && arg[k] !== null) { + node.setAttribute(k, arg[k]); + } + } + } + } + + return node; + }, + + /* Function: xmlescape + * Excapes invalid xml characters. + * + * Parameters: + * (String) text - text to escape. + * + * Returns: + * Escaped text. + */ + xmlescape(text) { + text = text.replace(/\&/g, "&"); + text = text.replace(//g, ">"); + text = text.replace(/'/g, "'"); + text = text.replace(/"/g, """); + return text; + }, + + /* Function: xmlunescape + * Unexcapes invalid xml characters. + * + * Parameters: + * (String) text - text to unescape. + * + * Returns: + * Unescaped text. + */ + xmlunescape(text) { + text = text.replace(/\&/g, "&"); + text = text.replace(/</g, "<"); + text = text.replace(/>/g, ">"); + text = text.replace(/'/g, "'"); + text = text.replace(/"/g, "\""); + return text; + }, + + /** Function: xmlTextNode + * Creates an XML DOM text node. + * + * Provides a cross implementation version of document.createTextNode. + * + * Parameters: + * (String) text - The content of the text node. + * + * Returns: + * A new XML DOM text node. + */ + xmlTextNode(text) { + return Strophe.xmlGenerator().createTextNode(text); + }, + + /** Function: xmlHtmlNode + * Creates an XML DOM html node. + * + * Parameters: + * (String) html - The content of the html node. + * + * Returns: + * A new XML DOM text node. + */ + xmlHtmlNode(html) { + let node; //ensure text is escaped + + if (shims["a" /* DOMParser */]) { + const parser = new shims["a" /* DOMParser */](); + node = parser.parseFromString(html, "text/xml"); + } else { + node = new ActiveXObject("Microsoft.XMLDOM"); + node.async = "false"; + node.loadXML(html); + } + + return node; + }, + + /** Function: getText + * Get the concatenation of all text children of an element. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * A String with the concatenated text of all text element children. + */ + getText(elem) { + if (!elem) { + return null; + } + + let str = ""; + + if (elem.childNodes.length === 0 && elem.nodeType === Strophe.ElementType.TEXT) { + str += elem.nodeValue; + } + + for (let i = 0; i < elem.childNodes.length; i++) { + if (elem.childNodes[i].nodeType === Strophe.ElementType.TEXT) { + str += elem.childNodes[i].nodeValue; + } + } + + return Strophe.xmlescape(str); + }, + + /** Function: copyElement + * Copy an XML DOM element. + * + * This function copies a DOM element and all its descendants and returns + * the new copy. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * A new, copied DOM element tree. + */ + copyElement(elem) { + let el; + + if (elem.nodeType === Strophe.ElementType.NORMAL) { + el = Strophe.xmlElement(elem.tagName); + + for (let i = 0; i < elem.attributes.length; i++) { + el.setAttribute(elem.attributes[i].nodeName, elem.attributes[i].value); + } + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.copyElement(elem.childNodes[i])); + } + } else if (elem.nodeType === Strophe.ElementType.TEXT) { + el = Strophe.xmlGenerator().createTextNode(elem.nodeValue); + } + + return el; + }, + + /** Function: createHtml + * Copy an HTML DOM element into an XML DOM. + * + * This function copies a DOM element and all its descendants and returns + * the new copy. + * + * Parameters: + * (HTMLElement) elem - A DOM element. + * + * Returns: + * A new, copied DOM element tree. + */ + createHtml(elem) { + let el; + + if (elem.nodeType === Strophe.ElementType.NORMAL) { + const tag = elem.nodeName.toLowerCase(); // XHTML tags must be lower case. + + if (Strophe.XHTML.validTag(tag)) { + try { + el = Strophe.xmlElement(tag); + + for (let i = 0; i < Strophe.XHTML.attributes[tag].length; i++) { + const attribute = Strophe.XHTML.attributes[tag][i]; + let value = elem.getAttribute(attribute); + + if (typeof value === 'undefined' || value === null || value === '' || value === false || value === 0) { + continue; + } + + if (attribute === 'style' && typeof value === 'object' && typeof value.cssText !== 'undefined') { + value = value.cssText; // we're dealing with IE, need to get CSS out + } // filter out invalid css styles + + + if (attribute === 'style') { + const css = []; + const cssAttrs = value.split(';'); + + for (let j = 0; j < cssAttrs.length; j++) { + const attr = cssAttrs[j].split(':'); + const cssName = attr[0].replace(/^\s*/, "").replace(/\s*$/, "").toLowerCase(); + + if (Strophe.XHTML.validCSS(cssName)) { + const cssValue = attr[1].replace(/^\s*/, "").replace(/\s*$/, ""); + css.push(cssName + ': ' + cssValue); + } + } + + if (css.length > 0) { + value = css.join('; '); + el.setAttribute(attribute, value); + } + } else { + el.setAttribute(attribute, value); + } + } + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.createHtml(elem.childNodes[i])); + } + } catch (e) { + // invalid elements + el = Strophe.xmlTextNode(''); + } + } else { + el = Strophe.xmlGenerator().createDocumentFragment(); + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.createHtml(elem.childNodes[i])); + } + } + } else if (elem.nodeType === Strophe.ElementType.FRAGMENT) { + el = Strophe.xmlGenerator().createDocumentFragment(); + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.createHtml(elem.childNodes[i])); + } + } else if (elem.nodeType === Strophe.ElementType.TEXT) { + el = Strophe.xmlTextNode(elem.nodeValue); + } + + return el; + }, + + /** Function: escapeNode + * Escape the node part (also called local part) of a JID. + * + * Parameters: + * (String) node - A node (or local part). + * + * Returns: + * An escaped node (or local part). + */ + escapeNode(node) { + if (typeof node !== "string") { + return node; + } + + return node.replace(/^\s+|\s+$/g, '').replace(/\\/g, "\\5c").replace(/ /g, "\\20").replace(/\"/g, "\\22").replace(/\&/g, "\\26").replace(/\'/g, "\\27").replace(/\//g, "\\2f").replace(/:/g, "\\3a").replace(//g, "\\3e").replace(/@/g, "\\40"); + }, + + /** Function: unescapeNode + * Unescape a node part (also called local part) of a JID. + * + * Parameters: + * (String) node - A node (or local part). + * + * Returns: + * An unescaped node (or local part). + */ + unescapeNode(node) { + if (typeof node !== "string") { + return node; + } + + return node.replace(/\\20/g, " ").replace(/\\22/g, '"').replace(/\\26/g, "&").replace(/\\27/g, "'").replace(/\\2f/g, "/").replace(/\\3a/g, ":").replace(/\\3c/g, "<").replace(/\\3e/g, ">").replace(/\\40/g, "@").replace(/\\5c/g, "\\"); + }, + + /** Function: getNodeFromJid + * Get the node portion of a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the node. + */ + getNodeFromJid(jid) { + if (jid.indexOf("@") < 0) { + return null; + } + + return jid.split("@")[0]; + }, + + /** Function: getDomainFromJid + * Get the domain portion of a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the domain. + */ + getDomainFromJid(jid) { + const bare = Strophe.getBareJidFromJid(jid); + + if (bare.indexOf("@") < 0) { + return bare; + } else { + const parts = bare.split("@"); + parts.splice(0, 1); + return parts.join('@'); + } + }, + + /** Function: getResourceFromJid + * Get the resource portion of a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the resource. + */ + getResourceFromJid(jid) { + if (!jid) { + return null; + } + + const s = jid.split("/"); + + if (s.length < 2) { + return null; + } + + s.splice(0, 1); + return s.join('/'); + }, + + /** Function: getBareJidFromJid + * Get the bare JID from a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the bare JID. + */ + getBareJidFromJid(jid) { + return jid ? jid.split("/")[0] : null; + }, + + /** PrivateFunction: _handleError + * _Private_ function that properly logs an error to the console + */ + _handleError(e) { + if (typeof e.stack !== "undefined") { + Strophe.fatal(e.stack); + } + + if (e.sourceURL) { + Strophe.fatal("error: " + this.handler + " " + e.sourceURL + ":" + e.line + " - " + e.name + ": " + e.message); + } else if (e.fileName) { + Strophe.fatal("error: " + this.handler + " " + e.fileName + ":" + e.lineNumber + " - " + e.name + ": " + e.message); + } else { + Strophe.fatal("error: " + e.message); + } + }, + + /** Function: log + * User overrideable logging function. + * + * This function is called whenever the Strophe library calls any + * of the logging functions. The default implementation of this + * function logs only fatal errors. If client code wishes to handle the logging + * messages, it should override this with + * > Strophe.log = function (level, msg) { + * > (user code here) + * > }; + * + * Please note that data sent and received over the wire is logged + * via Strophe.Connection.rawInput() and Strophe.Connection.rawOutput(). + * + * The different levels and their meanings are + * + * DEBUG - Messages useful for debugging purposes. + * INFO - Informational messages. This is mostly information like + * 'disconnect was called' or 'SASL auth succeeded'. + * WARN - Warnings about potential problems. This is mostly used + * to report transient connection errors like request timeouts. + * ERROR - Some error occurred. + * FATAL - A non-recoverable fatal error occurred. + * + * Parameters: + * (Integer) level - The log level of the log message. This will + * be one of the values in Strophe.LogLevel. + * (String) msg - The log message. + */ + log(level, msg) { + if (level === this.LogLevel.FATAL && typeof window.console === 'object' && typeof window.console.error === 'function') { + window.console.error(msg); + } + }, + + /** Function: debug + * Log a message at the Strophe.LogLevel.DEBUG level. + * + * Parameters: + * (String) msg - The log message. + */ + debug(msg) { + this.log(this.LogLevel.DEBUG, msg); + }, + + /** Function: info + * Log a message at the Strophe.LogLevel.INFO level. + * + * Parameters: + * (String) msg - The log message. + */ + info(msg) { + this.log(this.LogLevel.INFO, msg); + }, + + /** Function: warn + * Log a message at the Strophe.LogLevel.WARN level. + * + * Parameters: + * (String) msg - The log message. + */ + warn(msg) { + this.log(this.LogLevel.WARN, msg); + }, + + /** Function: error + * Log a message at the Strophe.LogLevel.ERROR level. + * + * Parameters: + * (String) msg - The log message. + */ + error(msg) { + this.log(this.LogLevel.ERROR, msg); + }, + + /** Function: fatal + * Log a message at the Strophe.LogLevel.FATAL level. + * + * Parameters: + * (String) msg - The log message. + */ + fatal(msg) { + this.log(this.LogLevel.FATAL, msg); + }, + + /** Function: serialize + * Render a DOM element and all descendants to a String. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * The serialized element tree as a String. + */ + serialize(elem) { + if (!elem) { + return null; + } + + if (typeof elem.tree === "function") { + elem = elem.tree(); + } + + const names = [...Array(elem.attributes.length).keys()].map(i => elem.attributes[i].nodeName); + names.sort(); + let result = names.reduce((a, n) => "".concat(a, " ").concat(n, "=\"").concat(Strophe.xmlescape(elem.attributes.getNamedItem(n).value), "\""), "<".concat(elem.nodeName)); + + if (elem.childNodes.length > 0) { + result += ">"; + + for (let i = 0; i < elem.childNodes.length; i++) { + const child = elem.childNodes[i]; + + switch (child.nodeType) { + case Strophe.ElementType.NORMAL: + // normal element, so recurse + result += Strophe.serialize(child); + break; + + case Strophe.ElementType.TEXT: + // text element to escape values + result += Strophe.xmlescape(child.nodeValue); + break; + + case Strophe.ElementType.CDATA: + // cdata section so don't escape values + result += ""; + } + } + + result += ""; + } else { + result += "/>"; + } + + return result; + }, + + /** PrivateVariable: _requestId + * _Private_ variable that keeps track of the request ids for + * connections. + */ + _requestId: 0, + + /** PrivateVariable: Strophe.connectionPlugins + * _Private_ variable Used to store plugin names that need + * initialization on Strophe.Connection construction. + */ + _connectionPlugins: {}, + + /** Function: addConnectionPlugin + * Extends the Strophe.Connection object with the given plugin. + * + * Parameters: + * (String) name - The name of the extension. + * (Object) ptype - The plugin's prototype. + */ + addConnectionPlugin(name, ptype) { + Strophe._connectionPlugins[name] = ptype; + } + +}; +/** Class: Strophe.Builder + * XML DOM builder. + * + * This object provides an interface similar to JQuery but for building + * DOM elements easily and rapidly. All the functions except for toString() + * and tree() return the object, so calls can be chained. Here's an + * example using the $iq() builder helper. + * > $iq({to: 'you', from: 'me', type: 'get', id: '1'}) + * > .c('query', {xmlns: 'strophe:example'}) + * > .c('example') + * > .toString() + * + * The above generates this XML fragment + * > + * > + * > + * > + * > + * The corresponding DOM manipulations to get a similar fragment would be + * a lot more tedious and probably involve several helper variables. + * + * Since adding children makes new operations operate on the child, up() + * is provided to traverse up the tree. To add two children, do + * > builder.c('child1', ...).up().c('child2', ...) + * The next operation on the Builder will be relative to the second child. + */ + +/** Constructor: Strophe.Builder + * Create a Strophe.Builder object. + * + * The attributes should be passed in object notation. For example + * > let b = new Builder('message', {to: 'you', from: 'me'}); + * or + * > let b = new Builder('messsage', {'xml:lang': 'en'}); + * + * Parameters: + * (String) name - The name of the root element. + * (Object) attrs - The attributes for the root element in object notation. + * + * Returns: + * A new Strophe.Builder. + */ + +Strophe.Builder = class Builder { + constructor(name, attrs) { + // Set correct namespace for jabber:client elements + if (name === "presence" || name === "message" || name === "iq") { + if (attrs && !attrs.xmlns) { + attrs.xmlns = Strophe.NS.CLIENT; + } else if (!attrs) { + attrs = { + xmlns: Strophe.NS.CLIENT + }; + } + } // Holds the tree being built. + + + this.nodeTree = Strophe.xmlElement(name, attrs); // Points to the current operation node. + + this.node = this.nodeTree; + } + /** Function: tree + * Return the DOM tree. + * + * This function returns the current DOM tree as an element object. This + * is suitable for passing to functions like Strophe.Connection.send(). + * + * Returns: + * The DOM tree as a element object. + */ + + + tree() { + return this.nodeTree; + } + /** Function: toString + * Serialize the DOM tree to a String. + * + * This function returns a string serialization of the current DOM + * tree. It is often used internally to pass data to a + * Strophe.Request object. + * + * Returns: + * The serialized DOM tree in a String. + */ + + + toString() { + return Strophe.serialize(this.nodeTree); + } + /** Function: up + * Make the current parent element the new current element. + * + * This function is often used after c() to traverse back up the tree. + * For example, to add two children to the same element + * > builder.c('child1', {}).up().c('child2', {}); + * + * Returns: + * The Stophe.Builder object. + */ + + + up() { + this.node = this.node.parentNode; + return this; + } + /** Function: root + * Make the root element the new current element. + * + * When at a deeply nested element in the tree, this function can be used + * to jump back to the root of the tree, instead of having to repeatedly + * call up(). + * + * Returns: + * The Stophe.Builder object. + */ + + + root() { + this.node = this.nodeTree; + return this; + } + /** Function: attrs + * Add or modify attributes of the current element. + * + * The attributes should be passed in object notation. This function + * does not move the current element pointer. + * + * Parameters: + * (Object) moreattrs - The attributes to add/modify in object notation. + * + * Returns: + * The Strophe.Builder object. + */ + + + attrs(moreattrs) { + for (const k in moreattrs) { + if (Object.prototype.hasOwnProperty.call(moreattrs, k)) { + if (moreattrs[k] === undefined) { + this.node.removeAttribute(k); + } else { + this.node.setAttribute(k, moreattrs[k]); + } + } + } + + return this; + } + /** Function: c + * Add a child to the current element and make it the new current + * element. + * + * This function moves the current element pointer to the child, + * unless text is provided. If you need to add another child, it + * is necessary to use up() to go back to the parent in the tree. + * + * Parameters: + * (String) name - The name of the child. + * (Object) attrs - The attributes of the child in object notation. + * (String) text - The text to add to the child. + * + * Returns: + * The Strophe.Builder object. + */ + + + c(name, attrs, text) { + const child = Strophe.xmlElement(name, attrs, text); + this.node.appendChild(child); + + if (typeof text !== "string" && typeof text !== "number") { + this.node = child; + } + + return this; + } + /** Function: cnode + * Add a child to the current element and make it the new current + * element. + * + * This function is the same as c() except that instead of using a + * name and an attributes object to create the child it uses an + * existing DOM element object. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * The Strophe.Builder object. + */ + + + cnode(elem) { + let impNode; + const xmlGen = Strophe.xmlGenerator(); + + try { + impNode = xmlGen.importNode !== undefined; + } catch (e) { + impNode = false; + } + + const newElem = impNode ? xmlGen.importNode(elem, true) : Strophe.copyElement(elem); + this.node.appendChild(newElem); + this.node = newElem; + return this; + } + /** Function: t + * Add a child text element. + * + * This *does not* make the child the new current element since there + * are no children of text elements. + * + * Parameters: + * (String) text - The text data to append to the current element. + * + * Returns: + * The Strophe.Builder object. + */ + + + t(text) { + const child = Strophe.xmlTextNode(text); + this.node.appendChild(child); + return this; + } + /** Function: h + * Replace current element contents with the HTML passed in. + * + * This *does not* make the child the new current element + * + * Parameters: + * (String) html - The html to insert as contents of current element. + * + * Returns: + * The Strophe.Builder object. + */ + + + h(html) { + const fragment = Strophe.xmlGenerator().createElement('body'); // force the browser to try and fix any invalid HTML tags + + fragment.innerHTML = html; // copy cleaned html into an xml dom + + const xhtml = Strophe.createHtml(fragment); + + while (xhtml.childNodes.length > 0) { + this.node.appendChild(xhtml.childNodes[0]); + } + + return this; + } + +}; +/** PrivateClass: Strophe.Handler + * _Private_ helper class for managing stanza handlers. + * + * A Strophe.Handler encapsulates a user provided callback function to be + * executed when matching stanzas are received by the connection. + * Handlers can be either one-off or persistant depending on their + * return value. Returning true will cause a Handler to remain active, and + * returning false will remove the Handler. + * + * Users will not use Strophe.Handler objects directly, but instead they + * will use Strophe.Connection.addHandler() and + * Strophe.Connection.deleteHandler(). + */ + +/** PrivateConstructor: Strophe.Handler + * Create and initialize a new Strophe.Handler. + * + * Parameters: + * (Function) handler - A function to be executed when the handler is run. + * (String) ns - The namespace to match. + * (String) name - The element name to match. + * (String) type - The element type to match. + * (String) id - The element id attribute to match. + * (String) from - The element from attribute to match. + * (Object) options - Handler options + * + * Returns: + * A new Strophe.Handler object. + */ + +Strophe.Handler = function (handler, ns, name, type, id, from, options) { + this.handler = handler; + this.ns = ns; + this.name = name; + this.type = type; + this.id = id; + this.options = options || { + 'matchBareFromJid': false, + 'ignoreNamespaceFragment': false + }; // BBB: Maintain backward compatibility with old `matchBare` option + + if (this.options.matchBare) { + Strophe.warn('The "matchBare" option is deprecated, use "matchBareFromJid" instead.'); + this.options.matchBareFromJid = this.options.matchBare; + delete this.options.matchBare; + } + + if (this.options.matchBareFromJid) { + this.from = from ? Strophe.getBareJidFromJid(from) : null; + } else { + this.from = from; + } // whether the handler is a user handler or a system handler + + + this.user = true; +}; + +Strophe.Handler.prototype = { + /** PrivateFunction: getNamespace + * Returns the XML namespace attribute on an element. + * If `ignoreNamespaceFragment` was passed in for this handler, then the + * URL fragment will be stripped. + * + * Parameters: + * (XMLElement) elem - The XML element with the namespace. + * + * Returns: + * The namespace, with optionally the fragment stripped. + */ + getNamespace(elem) { + let elNamespace = elem.getAttribute("xmlns"); + + if (elNamespace && this.options.ignoreNamespaceFragment) { + elNamespace = elNamespace.split('#')[0]; + } + + return elNamespace; + }, + + /** PrivateFunction: namespaceMatch + * Tests if a stanza matches the namespace set for this Strophe.Handler. + * + * Parameters: + * (XMLElement) elem - The XML element to test. + * + * Returns: + * true if the stanza matches and false otherwise. + */ + namespaceMatch(elem) { + let nsMatch = false; + + if (!this.ns) { + return true; + } else { + Strophe.forEachChild(elem, null, elem => { + if (this.getNamespace(elem) === this.ns) { + nsMatch = true; + } + }); + return nsMatch || this.getNamespace(elem) === this.ns; + } + }, + + /** PrivateFunction: isMatch + * Tests if a stanza matches the Strophe.Handler. + * + * Parameters: + * (XMLElement) elem - The XML element to test. + * + * Returns: + * true if the stanza matches and false otherwise. + */ + isMatch(elem) { + let from = elem.getAttribute('from'); + + if (this.options.matchBareFromJid) { + from = Strophe.getBareJidFromJid(from); + } + + const elem_type = elem.getAttribute("type"); + + if (this.namespaceMatch(elem) && (!this.name || Strophe.isTagEqual(elem, this.name)) && (!this.type || (Array.isArray(this.type) ? this.type.indexOf(elem_type) !== -1 : elem_type === this.type)) && (!this.id || elem.getAttribute("id") === this.id) && (!this.from || from === this.from)) { + return true; + } + + return false; + }, + + /** PrivateFunction: run + * Run the callback on a matching stanza. + * + * Parameters: + * (XMLElement) elem - The DOM element that triggered the + * Strophe.Handler. + * + * Returns: + * A boolean indicating if the handler should remain active. + */ + run(elem) { + let result = null; + + try { + result = this.handler(elem); + } catch (e) { + Strophe._handleError(e); + + throw e; + } + + return result; + }, + + /** PrivateFunction: toString + * Get a String representation of the Strophe.Handler object. + * + * Returns: + * A String. + */ + toString() { + return "{Handler: " + this.handler + "(" + this.name + "," + this.id + "," + this.ns + ")}"; + } + +}; +/** PrivateClass: Strophe.TimedHandler + * _Private_ helper class for managing timed handlers. + * + * A Strophe.TimedHandler encapsulates a user provided callback that + * should be called after a certain period of time or at regular + * intervals. The return value of the callback determines whether the + * Strophe.TimedHandler will continue to fire. + * + * Users will not use Strophe.TimedHandler objects directly, but instead + * they will use Strophe.Connection.addTimedHandler() and + * Strophe.Connection.deleteTimedHandler(). + */ + +Strophe.TimedHandler = class TimedHandler { + /** PrivateConstructor: Strophe.TimedHandler + * Create and initialize a new Strophe.TimedHandler object. + * + * Parameters: + * (Integer) period - The number of milliseconds to wait before the + * handler is called. + * (Function) handler - The callback to run when the handler fires. This + * function should take no arguments. + * + * Returns: + * A new Strophe.TimedHandler object. + */ + constructor(period, handler) { + this.period = period; + this.handler = handler; + this.lastCalled = new Date().getTime(); + this.user = true; + } + /** PrivateFunction: run + * Run the callback for the Strophe.TimedHandler. + * + * Returns: + * true if the Strophe.TimedHandler should be called again, and false + * otherwise. + */ + + + run() { + this.lastCalled = new Date().getTime(); + return this.handler(); + } + /** PrivateFunction: reset + * Reset the last called time for the Strophe.TimedHandler. + */ + + + reset() { + this.lastCalled = new Date().getTime(); + } + /** PrivateFunction: toString + * Get a string representation of the Strophe.TimedHandler object. + * + * Returns: + * The string representation. + */ + + + toString() { + return "{TimedHandler: " + this.handler + "(" + this.period + ")}"; + } + +}; +/** Class: Strophe.Connection + * XMPP Connection manager. + * + * This class is the main part of Strophe. It manages a BOSH or websocket + * connection to an XMPP server and dispatches events to the user callbacks + * as data arrives. It supports SASL PLAIN, SASL SCRAM-SHA-1 + * and legacy authentication. + * + * After creating a Strophe.Connection object, the user will typically + * call connect() with a user supplied callback to handle connection level + * events like authentication failure, disconnection, or connection + * complete. + * + * The user will also have several event handlers defined by using + * addHandler() and addTimedHandler(). These will allow the user code to + * respond to interesting stanzas or do something periodically with the + * connection. These handlers will be active once authentication is + * finished. + * + * To send data to the connection, use send(). + */ + +/** Constructor: Strophe.Connection + * Create and initialize a Strophe.Connection object. + * + * The transport-protocol for this connection will be chosen automatically + * based on the given service parameter. URLs starting with "ws://" or + * "wss://" will use WebSockets, URLs starting with "http://", "https://" + * or without a protocol will use BOSH. + * + * To make Strophe connect to the current host you can leave out the protocol + * and host part and just pass the path, e.g. + * + * > let conn = new Strophe.Connection("/http-bind/"); + * + * Options common to both Websocket and BOSH: + * ------------------------------------------ + * + * cookies: + * + * The *cookies* option allows you to pass in cookies to be added to the + * document. These cookies will then be included in the BOSH XMLHttpRequest + * or in the websocket connection. + * + * The passed in value must be a map of cookie names and string values. + * + * > { "myCookie": { + * > "value": "1234", + * > "domain": ".example.org", + * > "path": "/", + * > "expires": expirationDate + * > } + * > } + * + * Note that cookies can't be set in this way for other domains (i.e. cross-domain). + * Those cookies need to be set under those domains, for example they can be + * set server-side by making a XHR call to that domain to ask it to set any + * necessary cookies. + * + * mechanisms: + * + * The *mechanisms* option allows you to specify the SASL mechanisms that this + * instance of Strophe.Connection (and therefore your XMPP client) will + * support. + * + * The value must be an array of objects with Strophe.SASLMechanism + * prototypes. + * + * If nothing is specified, then the following mechanisms (and their + * priorities) are registered: + * + * SCRAM-SHA-1 - 60 + * PLAIN - 50 + * OAUTHBEARER - 40 + * X-OAUTH2 - 30 + * ANONYMOUS - 20 + * EXTERNAL - 10 + * + * explicitResourceBinding: + * + * If `explicitResourceBinding` is set to a truthy value, then the XMPP client + * needs to explicitly call `Strophe.Connection.prototype.bind` once the XMPP + * server has advertised the "urn:ietf:params:xml:ns:xmpp-bind" feature. + * + * Making this step explicit allows client authors to first finish other + * stream related tasks, such as setting up an XEP-0198 Stream Management + * session, before binding the JID resource for this session. + * + * WebSocket options: + * ------------------ + * + * protocol: + * + * If you want to connect to the current host with a WebSocket connection you + * can tell Strophe to use WebSockets through a "protocol" attribute in the + * optional options parameter. Valid values are "ws" for WebSocket and "wss" + * for Secure WebSocket. + * So to connect to "wss://CURRENT_HOSTNAME/xmpp-websocket" you would call + * + * > let conn = new Strophe.Connection("/xmpp-websocket/", {protocol: "wss"}); + * + * Note that relative URLs _NOT_ starting with a "/" will also include the path + * of the current site. + * + * Also because downgrading security is not permitted by browsers, when using + * relative URLs both BOSH and WebSocket connections will use their secure + * variants if the current connection to the site is also secure (https). + * + * worker: + * + * Set this option to URL from where the shared worker script should be loaded. + * + * To run the websocket connection inside a shared worker. + * This allows you to share a single websocket-based connection between + * multiple Strophe.Connection instances, for example one per browser tab. + * + * The script to use is the one in `src/shared-connection-worker.js`. + * + * BOSH options: + * ------------- + * + * By adding "sync" to the options, you can control if requests will + * be made synchronously or not. The default behaviour is asynchronous. + * If you want to make requests synchronous, make "sync" evaluate to true. + * > let conn = new Strophe.Connection("/http-bind/", {sync: true}); + * + * You can also toggle this on an already established connection. + * > conn.options.sync = true; + * + * The *customHeaders* option can be used to provide custom HTTP headers to be + * included in the XMLHttpRequests made. + * + * The *keepalive* option can be used to instruct Strophe to maintain the + * current BOSH session across interruptions such as webpage reloads. + * + * It will do this by caching the sessions tokens in sessionStorage, and when + * "restore" is called it will check whether there are cached tokens with + * which it can resume an existing session. + * + * The *withCredentials* option should receive a Boolean value and is used to + * indicate wether cookies should be included in ajax requests (by default + * they're not). + * Set this value to true if you are connecting to a BOSH service + * and for some reason need to send cookies to it. + * In order for this to work cross-domain, the server must also enable + * credentials by setting the Access-Control-Allow-Credentials response header + * to "true". For most usecases however this setting should be false (which + * is the default). + * Additionally, when using Access-Control-Allow-Credentials, the + * Access-Control-Allow-Origin header can't be set to the wildcard "*", but + * instead must be restricted to actual domains. + * + * The *contentType* option can be set to change the default Content-Type + * of "text/xml; charset=utf-8", which can be useful to reduce the amount of + * CORS preflight requests that are sent to the server. + * + * Parameters: + * (String) service - The BOSH or WebSocket service URL. + * (Object) options - A hash of configuration options + * + * Returns: + * A new Strophe.Connection object. + */ + +Strophe.Connection = class Connection { + constructor(service, options) { + // The service URL + this.service = service; // Configuration options + + this.options = options || {}; + const proto = this.options.protocol || ""; // Select protocal based on service or options + + if (this.options.worker) { + this._proto = new Strophe.WorkerWebsocket(this); + } else if (service.indexOf("ws:") === 0 || service.indexOf("wss:") === 0 || proto.indexOf("ws") === 0) { + this._proto = new Strophe.Websocket(this); + } else { + this._proto = new Strophe.Bosh(this); + } + /* The connected JID. */ + + + this.jid = ""; + /* the JIDs domain */ + + this.domain = null; + /* stream:features */ + + this.features = null; // SASL + + this._sasl_data = {}; + this.do_bind = false; + this.do_session = false; + this.mechanisms = {}; // handler lists + + this.timedHandlers = []; + this.handlers = []; + this.removeTimeds = []; + this.removeHandlers = []; + this.addTimeds = []; + this.addHandlers = []; + this.protocolErrorHandlers = { + 'HTTP': {}, + 'websocket': {} + }; + this._idleTimeout = null; + this._disconnectTimeout = null; + this.authenticated = false; + this.connected = false; + this.disconnecting = false; + this.do_authentication = true; + this.paused = false; + this.restored = false; + this._data = []; + this._uniqueId = 0; + this._sasl_success_handler = null; + this._sasl_failure_handler = null; + this._sasl_challenge_handler = null; // Max retries before disconnecting + + this.maxRetries = 5; // Call onIdle callback every 1/10th of a second + + this._idleTimeout = setTimeout(() => this._onIdle(), 100); + utils.addCookies(this.options.cookies); + this.registerSASLMechanisms(this.options.mechanisms); // initialize plugins + + for (const k in Strophe._connectionPlugins) { + if (Object.prototype.hasOwnProperty.call(Strophe._connectionPlugins, k)) { + const F = function F() {}; + + F.prototype = Strophe._connectionPlugins[k]; + this[k] = new F(); + this[k].init(this); + } + } + } + /** Function: reset + * Reset the connection. + * + * This function should be called after a connection is disconnected + * before that connection is reused. + */ + + + reset() { + this._proto._reset(); // SASL + + + this.do_session = false; + this.do_bind = false; // handler lists + + this.timedHandlers = []; + this.handlers = []; + this.removeTimeds = []; + this.removeHandlers = []; + this.addTimeds = []; + this.addHandlers = []; + this.authenticated = false; + this.connected = false; + this.disconnecting = false; + this.restored = false; + this._data = []; + this._requests = []; + this._uniqueId = 0; + } + /** Function: pause + * Pause the request manager. + * + * This will prevent Strophe from sending any more requests to the + * server. This is very useful for temporarily pausing + * BOSH-Connections while a lot of send() calls are happening quickly. + * This causes Strophe to send the data in a single request, saving + * many request trips. + */ + + + pause() { + this.paused = true; + } + /** Function: resume + * Resume the request manager. + * + * This resumes after pause() has been called. + */ + + + resume() { + this.paused = false; + } + /** Function: getUniqueId + * Generate a unique ID for use in elements. + * + * All stanzas are required to have unique id attributes. This + * function makes creating these easy. Each connection instance has + * a counter which starts from zero, and the value of this counter + * plus a colon followed by the suffix becomes the unique id. If no + * suffix is supplied, the counter is used as the unique id. + * + * Suffixes are used to make debugging easier when reading the stream + * data, and their use is recommended. The counter resets to 0 for + * every new connection for the same reason. For connections to the + * same server that authenticate the same way, all the ids should be + * the same, which makes it easy to see changes. This is useful for + * automated testing as well. + * + * Parameters: + * (String) suffix - A optional suffix to append to the id. + * + * Returns: + * A unique string to be used for the id attribute. + */ + + + getUniqueId(suffix) { + // eslint-disable-line class-methods-use-this + const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + const r = Math.random() * 16 | 0, + v = c === 'x' ? r : r & 0x3 | 0x8; + return v.toString(16); + }); + + if (typeof suffix === "string" || typeof suffix === "number") { + return uuid + ":" + suffix; + } else { + return uuid + ""; + } + } + /** Function: addProtocolErrorHandler + * Register a handler function for when a protocol (websocker or HTTP) + * error occurs. + * + * NOTE: Currently only HTTP errors for BOSH requests are handled. + * Patches that handle websocket errors would be very welcome. + * + * Parameters: + * (String) protocol - 'HTTP' or 'websocket' + * (Integer) status_code - Error status code (e.g 500, 400 or 404) + * (Function) callback - Function that will fire on Http error + * + * Example: + * function onError(err_code){ + * //do stuff + * } + * + * let conn = Strophe.connect('http://example.com/http-bind'); + * conn.addProtocolErrorHandler('HTTP', 500, onError); + * // Triggers HTTP 500 error and onError handler will be called + * conn.connect('user_jid@incorrect_jabber_host', 'secret', onConnect); + */ + + + addProtocolErrorHandler(protocol, status_code, callback) { + this.protocolErrorHandlers[protocol][status_code] = callback; + } + /** Function: connect + * Starts the connection process. + * + * As the connection process proceeds, the user supplied callback will + * be triggered multiple times with status updates. The callback + * should take two arguments - the status code and the error condition. + * + * The status code will be one of the values in the Strophe.Status + * constants. The error condition will be one of the conditions + * defined in RFC 3920 or the condition 'strophe-parsererror'. + * + * The Parameters _wait_, _hold_ and _route_ are optional and only relevant + * for BOSH connections. Please see XEP 124 for a more detailed explanation + * of the optional parameters. + * + * Parameters: + * (String) jid - The user's JID. This may be a bare JID, + * or a full JID. If a node is not supplied, SASL OAUTHBEARER or + * SASL ANONYMOUS authentication will be attempted (OAUTHBEARER will + * process the provided password value as an access token). + * (String) pass - The user's password. + * (Function) callback - The connect callback function. + * (Integer) wait - The optional HTTPBIND wait value. This is the + * time the server will wait before returning an empty result for + * a request. The default setting of 60 seconds is recommended. + * (Integer) hold - The optional HTTPBIND hold value. This is the + * number of connections the server will hold at one time. This + * should almost always be set to 1 (the default). + * (String) route - The optional route value. + * (String) authcid - The optional alternative authentication identity + * (username) if intending to impersonate another user. + * When using the SASL-EXTERNAL authentication mechanism, for example + * with client certificates, then the authcid value is used to + * determine whether an authorization JID (authzid) should be sent to + * the server. The authzid should NOT be sent to the server if the + * authzid and authcid are the same. So to prevent it from being sent + * (for example when the JID is already contained in the client + * certificate), set authcid to that same JID. See XEP-178 for more + * details. + */ + + + connect(jid, pass, callback, wait, hold, route, authcid) { + this.jid = jid; + /** Variable: authzid + * Authorization identity. + */ + + this.authzid = Strophe.getBareJidFromJid(this.jid); + /** Variable: authcid + * Authentication identity (User name). + */ + + this.authcid = authcid || Strophe.getNodeFromJid(this.jid); + /** Variable: pass + * Authentication identity (User password). + */ + + this.pass = pass; + this.connect_callback = callback; + this.disconnecting = false; + this.connected = false; + this.authenticated = false; + this.restored = false; // parse jid for domain + + this.domain = Strophe.getDomainFromJid(this.jid); + + this._changeConnectStatus(Strophe.Status.CONNECTING, null); + + this._proto._connect(wait, hold, route); + } + /** Function: attach + * Attach to an already created and authenticated BOSH session. + * + * This function is provided to allow Strophe to attach to BOSH + * sessions which have been created externally, perhaps by a Web + * application. This is often used to support auto-login type features + * without putting user credentials into the page. + * + * Parameters: + * (String) jid - The full JID that is bound by the session. + * (String) sid - The SID of the BOSH session. + * (String) rid - The current RID of the BOSH session. This RID + * will be used by the next request. + * (Function) callback The connect callback function. + * (Integer) wait - The optional HTTPBIND wait value. This is the + * time the server will wait before returning an empty result for + * a request. The default setting of 60 seconds is recommended. + * Other settings will require tweaks to the Strophe.TIMEOUT value. + * (Integer) hold - The optional HTTPBIND hold value. This is the + * number of connections the server will hold at one time. This + * should almost always be set to 1 (the default). + * (Integer) wind - The optional HTTBIND window value. This is the + * allowed range of request ids that are valid. The default is 5. + */ + + + attach(jid, sid, rid, callback, wait, hold, wind) { + if (this._proto._attach) { + return this._proto._attach(jid, sid, rid, callback, wait, hold, wind); + } else { + const error = new Error('The "attach" method is not available for your connection protocol'); + error.name = 'StropheSessionError'; + throw error; + } + } + /** Function: restore + * Attempt to restore a cached BOSH session. + * + * This function is only useful in conjunction with providing the + * "keepalive":true option when instantiating a new Strophe.Connection. + * + * When "keepalive" is set to true, Strophe will cache the BOSH tokens + * RID (Request ID) and SID (Session ID) and then when this function is + * called, it will attempt to restore the session from those cached + * tokens. + * + * This function must therefore be called instead of connect or attach. + * + * For an example on how to use it, please see examples/restore.js + * + * Parameters: + * (String) jid - The user's JID. This may be a bare JID or a full JID. + * (Function) callback - The connect callback function. + * (Integer) wait - The optional HTTPBIND wait value. This is the + * time the server will wait before returning an empty result for + * a request. The default setting of 60 seconds is recommended. + * (Integer) hold - The optional HTTPBIND hold value. This is the + * number of connections the server will hold at one time. This + * should almost always be set to 1 (the default). + * (Integer) wind - The optional HTTBIND window value. This is the + * allowed range of request ids that are valid. The default is 5. + */ + + + restore(jid, callback, wait, hold, wind) { + if (this._sessionCachingSupported()) { + this._proto._restore(jid, callback, wait, hold, wind); + } else { + const error = new Error('The "restore" method can only be used with a BOSH connection.'); + error.name = 'StropheSessionError'; + throw error; + } + } + /** PrivateFunction: _sessionCachingSupported + * Checks whether sessionStorage and JSON are supported and whether we're + * using BOSH. + */ + + + _sessionCachingSupported() { + if (this._proto instanceof Strophe.Bosh) { + if (!JSON) { + return false; + } + + try { + sessionStorage.setItem('_strophe_', '_strophe_'); + sessionStorage.removeItem('_strophe_'); + } catch (e) { + return false; + } + + return true; + } + + return false; + } + /** Function: xmlInput + * User overrideable function that receives XML data coming into the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.xmlInput = function (elem) { + * > (user code) + * > }; + * + * Due to limitations of current Browsers' XML-Parsers the opening and closing + * tag for WebSocket-Connoctions will be passed as selfclosing here. + * + * BOSH-Connections will have all stanzas wrapped in a tag. See + * if you want to strip this tag. + * + * Parameters: + * (XMLElement) elem - The XML data received by the connection. + */ + + + xmlInput(elem) { + // eslint-disable-line + return; + } + /** Function: xmlOutput + * User overrideable function that receives XML data sent to the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.xmlOutput = function (elem) { + * > (user code) + * > }; + * + * Due to limitations of current Browsers' XML-Parsers the opening and closing + * tag for WebSocket-Connoctions will be passed as selfclosing here. + * + * BOSH-Connections will have all stanzas wrapped in a tag. See + * if you want to strip this tag. + * + * Parameters: + * (XMLElement) elem - The XMLdata sent by the connection. + */ + + + xmlOutput(elem) { + // eslint-disable-line + return; + } + /** Function: rawInput + * User overrideable function that receives raw data coming into the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.rawInput = function (data) { + * > (user code) + * > }; + * + * Parameters: + * (String) data - The data received by the connection. + */ + + + rawInput(data) { + // eslint-disable-line + return; + } + /** Function: rawOutput + * User overrideable function that receives raw data sent to the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.rawOutput = function (data) { + * > (user code) + * > }; + * + * Parameters: + * (String) data - The data sent by the connection. + */ + + + rawOutput(data) { + // eslint-disable-line + return; + } + /** Function: nextValidRid + * User overrideable function that receives the new valid rid. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.nextValidRid = function (rid) { + * > (user code) + * > }; + * + * Parameters: + * (Number) rid - The next valid rid + */ + + + nextValidRid(rid) { + // eslint-disable-line + return; + } + /** Function: send + * Send a stanza. + * + * This function is called to push data onto the send queue to + * go out over the wire. Whenever a request is sent to the BOSH + * server, all pending data is sent and the queue is flushed. + * + * Parameters: + * (XMLElement | + * [XMLElement] | + * Strophe.Builder) elem - The stanza to send. + */ + + + send(elem) { + if (elem === null) { + return; + } + + if (typeof elem.sort === "function") { + for (let i = 0; i < elem.length; i++) { + this._queueData(elem[i]); + } + } else if (typeof elem.tree === "function") { + this._queueData(elem.tree()); + } else { + this._queueData(elem); + } + + this._proto._send(); + } + /** Function: flush + * Immediately send any pending outgoing data. + * + * Normally send() queues outgoing data until the next idle period + * (100ms), which optimizes network use in the common cases when + * several send()s are called in succession. flush() can be used to + * immediately send all pending data. + */ + + + flush() { + // cancel the pending idle period and run the idle function + // immediately + clearTimeout(this._idleTimeout); + + this._onIdle(); + } + /** Function: sendPresence + * Helper function to send presence stanzas. The main benefit is for + * sending presence stanzas for which you expect a responding presence + * stanza with the same id (for example when leaving a chat room). + * + * Parameters: + * (XMLElement) elem - The stanza to send. + * (Function) callback - The callback function for a successful request. + * (Function) errback - The callback function for a failed or timed + * out request. On timeout, the stanza will be null. + * (Integer) timeout - The time specified in milliseconds for a + * timeout to occur. + * + * Returns: + * The id used to send the presence. + */ + + + sendPresence(elem, callback, errback, timeout) { + let timeoutHandler = null; + + if (typeof elem.tree === "function") { + elem = elem.tree(); + } + + let id = elem.getAttribute('id'); + + if (!id) { + // inject id if not found + id = this.getUniqueId("sendPresence"); + elem.setAttribute("id", id); + } + + if (typeof callback === "function" || typeof errback === "function") { + const handler = this.addHandler(stanza => { + // remove timeout handler if there is one + if (timeoutHandler) { + this.deleteTimedHandler(timeoutHandler); + } + + if (stanza.getAttribute('type') === 'error') { + if (errback) { + errback(stanza); + } + } else if (callback) { + callback(stanza); + } + }, null, 'presence', null, id); // if timeout specified, set up a timeout handler. + + if (timeout) { + timeoutHandler = this.addTimedHandler(timeout, () => { + // get rid of normal handler + this.deleteHandler(handler); // call errback on timeout with null stanza + + if (errback) { + errback(null); + } + + return false; + }); + } + } + + this.send(elem); + return id; + } + /** Function: sendIQ + * Helper function to send IQ stanzas. + * + * Parameters: + * (XMLElement) elem - The stanza to send. + * (Function) callback - The callback function for a successful request. + * (Function) errback - The callback function for a failed or timed + * out request. On timeout, the stanza will be null. + * (Integer) timeout - The time specified in milliseconds for a + * timeout to occur. + * + * Returns: + * The id used to send the IQ. + */ + + + sendIQ(elem, callback, errback, timeout) { + let timeoutHandler = null; + + if (typeof elem.tree === "function") { + elem = elem.tree(); + } + + let id = elem.getAttribute('id'); + + if (!id) { + // inject id if not found + id = this.getUniqueId("sendIQ"); + elem.setAttribute("id", id); + } + + if (typeof callback === "function" || typeof errback === "function") { + const handler = this.addHandler(stanza => { + // remove timeout handler if there is one + if (timeoutHandler) { + this.deleteTimedHandler(timeoutHandler); + } + + const iqtype = stanza.getAttribute('type'); + + if (iqtype === 'result') { + if (callback) { + callback(stanza); + } + } else if (iqtype === 'error') { + if (errback) { + errback(stanza); + } + } else { + const error = new Error("Got bad IQ type of ".concat(iqtype)); + error.name = "StropheError"; + throw error; + } + }, null, 'iq', ['error', 'result'], id); // if timeout specified, set up a timeout handler. + + if (timeout) { + timeoutHandler = this.addTimedHandler(timeout, () => { + // get rid of normal handler + this.deleteHandler(handler); // call errback on timeout with null stanza + + if (errback) { + errback(null); + } + + return false; + }); + } + } + + this.send(elem); + return id; + } + /** PrivateFunction: _queueData + * Queue outgoing data for later sending. Also ensures that the data + * is a DOMElement. + */ + + + _queueData(element) { + if (element === null || !element.tagName || !element.childNodes) { + const error = new Error("Cannot queue non-DOMElement."); + error.name = "StropheError"; + throw error; + } + + this._data.push(element); + } + /** PrivateFunction: _sendRestart + * Send an xmpp:restart stanza. + */ + + + _sendRestart() { + this._data.push("restart"); + + this._proto._sendRestart(); + + this._idleTimeout = setTimeout(() => this._onIdle(), 100); + } + /** Function: addTimedHandler + * Add a timed handler to the connection. + * + * This function adds a timed handler. The provided handler will + * be called every period milliseconds until it returns false, + * the connection is terminated, or the handler is removed. Handlers + * that wish to continue being invoked should return true. + * + * Because of method binding it is necessary to save the result of + * this function if you wish to remove a handler with + * deleteTimedHandler(). + * + * Note that user handlers are not active until authentication is + * successful. + * + * Parameters: + * (Integer) period - The period of the handler. + * (Function) handler - The callback function. + * + * Returns: + * A reference to the handler that can be used to remove it. + */ + + + addTimedHandler(period, handler) { + const thand = new Strophe.TimedHandler(period, handler); + this.addTimeds.push(thand); + return thand; + } + /** Function: deleteTimedHandler + * Delete a timed handler for a connection. + * + * This function removes a timed handler from the connection. The + * handRef parameter is *not* the function passed to addTimedHandler(), + * but is the reference returned from addTimedHandler(). + * + * Parameters: + * (Strophe.TimedHandler) handRef - The handler reference. + */ + + + deleteTimedHandler(handRef) { + // this must be done in the Idle loop so that we don't change + // the handlers during iteration + this.removeTimeds.push(handRef); + } + /** Function: addHandler + * Add a stanza handler for the connection. + * + * This function adds a stanza handler to the connection. The + * handler callback will be called for any stanza that matches + * the parameters. Note that if multiple parameters are supplied, + * they must all match for the handler to be invoked. + * + * The handler will receive the stanza that triggered it as its argument. + * *The handler should return true if it is to be invoked again; + * returning false will remove the handler after it returns.* + * + * As a convenience, the ns parameters applies to the top level element + * and also any of its immediate children. This is primarily to make + * matching /iq/query elements easy. + * + * Options + * ~~~~~~~ + * With the options argument, you can specify boolean flags that affect how + * matches are being done. + * + * Currently two flags exist: + * + * - matchBareFromJid: + * When set to true, the from parameter and the + * from attribute on the stanza will be matched as bare JIDs instead + * of full JIDs. To use this, pass {matchBareFromJid: true} as the + * value of options. The default value for matchBareFromJid is false. + * + * - ignoreNamespaceFragment: + * When set to true, a fragment specified on the stanza's namespace + * URL will be ignored when it's matched with the one configured for + * the handler. + * + * This means that if you register like this: + * > connection.addHandler( + * > handler, + * > 'http://jabber.org/protocol/muc', + * > null, null, null, null, + * > {'ignoreNamespaceFragment': true} + * > ); + * + * Then a stanza with XML namespace of + * 'http://jabber.org/protocol/muc#user' will also be matched. If + * 'ignoreNamespaceFragment' is false, then only stanzas with + * 'http://jabber.org/protocol/muc' will be matched. + * + * Deleting the handler + * ~~~~~~~~~~~~~~~~~~~~ + * The return value should be saved if you wish to remove the handler + * with deleteHandler(). + * + * Parameters: + * (Function) handler - The user callback. + * (String) ns - The namespace to match. + * (String) name - The stanza name to match. + * (String|Array) type - The stanza type (or types if an array) to match. + * (String) id - The stanza id attribute to match. + * (String) from - The stanza from attribute to match. + * (String) options - The handler options + * + * Returns: + * A reference to the handler that can be used to remove it. + */ + + + addHandler(handler, ns, name, type, id, from, options) { + const hand = new Strophe.Handler(handler, ns, name, type, id, from, options); + this.addHandlers.push(hand); + return hand; + } + /** Function: deleteHandler + * Delete a stanza handler for a connection. + * + * This function removes a stanza handler from the connection. The + * handRef parameter is *not* the function passed to addHandler(), + * but is the reference returned from addHandler(). + * + * Parameters: + * (Strophe.Handler) handRef - The handler reference. + */ + + + deleteHandler(handRef) { + // this must be done in the Idle loop so that we don't change + // the handlers during iteration + this.removeHandlers.push(handRef); // If a handler is being deleted while it is being added, + // prevent it from getting added + + const i = this.addHandlers.indexOf(handRef); + + if (i >= 0) { + this.addHandlers.splice(i, 1); + } + } + /** Function: registerSASLMechanisms + * + * Register the SASL mechanisms which will be supported by this instance of + * Strophe.Connection (i.e. which this XMPP client will support). + * + * Parameters: + * (Array) mechanisms - Array of objects with Strophe.SASLMechanism prototypes + * + */ + + + registerSASLMechanisms(mechanisms) { + this.mechanisms = {}; + mechanisms = mechanisms || [Strophe.SASLAnonymous, Strophe.SASLExternal, Strophe.SASLOAuthBearer, Strophe.SASLXOAuth2, Strophe.SASLPlain, Strophe.SASLSHA1]; + mechanisms.forEach(m => this.registerSASLMechanism(m)); + } + /** Function: registerSASLMechanism + * + * Register a single SASL mechanism, to be supported by this client. + * + * Parameters: + * (Object) mechanism - Object with a Strophe.SASLMechanism prototype + * + */ + + + registerSASLMechanism(mechanism) { + this.mechanisms[mechanism.name] = mechanism; + } + /** Function: disconnect + * Start the graceful disconnection process. + * + * This function starts the disconnection process. This process starts + * by sending unavailable presence and sending BOSH body of type + * terminate. A timeout handler makes sure that disconnection happens + * even if the BOSH server does not respond. + * If the Connection object isn't connected, at least tries to abort all pending requests + * so the connection object won't generate successful requests (which were already opened). + * + * The user supplied connection callback will be notified of the + * progress as this process happens. + * + * Parameters: + * (String) reason - The reason the disconnect is occuring. + */ + + + disconnect(reason) { + this._changeConnectStatus(Strophe.Status.DISCONNECTING, reason); + + if (reason) { + Strophe.warn("Disconnect was called because: " + reason); + } else { + Strophe.info("Disconnect was called"); + } + + if (this.connected) { + let pres = false; + this.disconnecting = true; + + if (this.authenticated) { + pres = $pres({ + 'xmlns': Strophe.NS.CLIENT, + 'type': 'unavailable' + }); + } // setup timeout handler + + + this._disconnectTimeout = this._addSysTimedHandler(3000, this._onDisconnectTimeout.bind(this)); + + this._proto._disconnect(pres); + } else { + Strophe.warn("Disconnect was called before Strophe connected to the server"); + + this._proto._abortAllRequests(); + + this._doDisconnect(); + } + } + /** PrivateFunction: _changeConnectStatus + * _Private_ helper function that makes sure plugins and the user's + * callback are notified of connection status changes. + * + * Parameters: + * (Integer) status - the new connection status, one of the values + * in Strophe.Status + * (String) condition - the error condition or null + * (XMLElement) elem - The triggering stanza. + */ + + + _changeConnectStatus(status, condition, elem) { + // notify all plugins listening for status changes + for (const k in Strophe._connectionPlugins) { + if (Object.prototype.hasOwnProperty.call(Strophe._connectionPlugins, k)) { + const plugin = this[k]; + + if (plugin.statusChanged) { + try { + plugin.statusChanged(status, condition); + } catch (err) { + Strophe.error("".concat(k, " plugin caused an exception changing status: ").concat(err)); + } + } + } + } // notify the user's callback + + + if (this.connect_callback) { + try { + this.connect_callback(status, condition, elem); + } catch (e) { + Strophe._handleError(e); + + Strophe.error("User connection callback caused an exception: ".concat(e)); + } + } + } + /** PrivateFunction: _doDisconnect + * _Private_ function to disconnect. + * + * This is the last piece of the disconnection logic. This resets the + * connection and alerts the user's connection callback. + */ + + + _doDisconnect(condition) { + if (typeof this._idleTimeout === "number") { + clearTimeout(this._idleTimeout); + } // Cancel Disconnect Timeout + + + if (this._disconnectTimeout !== null) { + this.deleteTimedHandler(this._disconnectTimeout); + this._disconnectTimeout = null; + } + + Strophe.debug("_doDisconnect was called"); + + this._proto._doDisconnect(); + + this.authenticated = false; + this.disconnecting = false; + this.restored = false; // delete handlers + + this.handlers = []; + this.timedHandlers = []; + this.removeTimeds = []; + this.removeHandlers = []; + this.addTimeds = []; + this.addHandlers = []; // tell the parent we disconnected + + this._changeConnectStatus(Strophe.Status.DISCONNECTED, condition); + + this.connected = false; + } + /** PrivateFunction: _dataRecv + * _Private_ handler to processes incoming data from the the connection. + * + * Except for _connect_cb handling the initial connection request, + * this function handles the incoming data for all requests. This + * function also fires stanza handlers that match each incoming + * stanza. + * + * Parameters: + * (Strophe.Request) req - The request that has data ready. + * (string) req - The stanza a raw string (optiona). + */ + + + _dataRecv(req, raw) { + const elem = this._proto._reqToData(req); + + if (elem === null) { + return; + } + + if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) { + if (elem.nodeName === this._proto.strip && elem.childNodes.length) { + this.xmlInput(elem.childNodes[0]); + } else { + this.xmlInput(elem); + } + } + + if (this.rawInput !== Strophe.Connection.prototype.rawInput) { + if (raw) { + this.rawInput(raw); + } else { + this.rawInput(Strophe.serialize(elem)); + } + } // remove handlers scheduled for deletion + + + while (this.removeHandlers.length > 0) { + const hand = this.removeHandlers.pop(); + const i = this.handlers.indexOf(hand); + + if (i >= 0) { + this.handlers.splice(i, 1); + } + } // add handlers scheduled for addition + + + while (this.addHandlers.length > 0) { + this.handlers.push(this.addHandlers.pop()); + } // handle graceful disconnect + + + if (this.disconnecting && this._proto._emptyQueue()) { + this._doDisconnect(); + + return; + } + + const type = elem.getAttribute("type"); + + if (type !== null && type === "terminate") { + // Don't process stanzas that come in after disconnect + if (this.disconnecting) { + return; + } // an error occurred + + + let cond = elem.getAttribute("condition"); + const conflict = elem.getElementsByTagName("conflict"); + + if (cond !== null) { + if (cond === "remote-stream-error" && conflict.length > 0) { + cond = "conflict"; + } + + this._changeConnectStatus(Strophe.Status.CONNFAIL, cond); + } else { + this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.UNKOWN_REASON); + } + + this._doDisconnect(cond); + + return; + } // send each incoming stanza through the handler chain + + + Strophe.forEachChild(elem, null, child => { + // process handlers + const newList = this.handlers; + this.handlers = []; + + for (let i = 0; i < newList.length; i++) { + const hand = newList[i]; // encapsulate 'handler.run' not to lose the whole handler list if + // one of the handlers throws an exception + + try { + if (hand.isMatch(child) && (this.authenticated || !hand.user)) { + if (hand.run(child)) { + this.handlers.push(hand); + } + } else { + this.handlers.push(hand); + } + } catch (e) { + // if the handler throws an exception, we consider it as false + Strophe.warn('Removing Strophe handlers due to uncaught exception: ' + e.message); + } + } + }); + } + /** PrivateFunction: _connect_cb + * _Private_ handler for initial connection request. + * + * This handler is used to process the initial connection request + * response from the BOSH server. It is used to set up authentication + * handlers and start the authentication process. + * + * SASL authentication will be attempted if available, otherwise + * the code will fall back to legacy authentication. + * + * Parameters: + * (Strophe.Request) req - The current request. + * (Function) _callback - low level (xmpp) connect callback function. + * Useful for plugins with their own xmpp connect callback (when they + * want to do something special). + */ + + + _connect_cb(req, _callback, raw) { + Strophe.debug("_connect_cb was called"); + this.connected = true; + let bodyWrap; + + try { + bodyWrap = this._proto._reqToData(req); + } catch (e) { + if (e.name !== Strophe.ErrorCondition.BAD_FORMAT) { + throw e; + } + + this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.BAD_FORMAT); + + this._doDisconnect(Strophe.ErrorCondition.BAD_FORMAT); + } + + if (!bodyWrap) { + return; + } + + if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) { + if (bodyWrap.nodeName === this._proto.strip && bodyWrap.childNodes.length) { + this.xmlInput(bodyWrap.childNodes[0]); + } else { + this.xmlInput(bodyWrap); + } + } + + if (this.rawInput !== Strophe.Connection.prototype.rawInput) { + if (raw) { + this.rawInput(raw); + } else { + this.rawInput(Strophe.serialize(bodyWrap)); + } + } + + const conncheck = this._proto._connect_cb(bodyWrap); + + if (conncheck === Strophe.Status.CONNFAIL) { + return; + } // Check for the stream:features tag + + + let hasFeatures; + + if (bodyWrap.getElementsByTagNameNS) { + hasFeatures = bodyWrap.getElementsByTagNameNS(Strophe.NS.STREAM, "features").length > 0; + } else { + hasFeatures = bodyWrap.getElementsByTagName("stream:features").length > 0 || bodyWrap.getElementsByTagName("features").length > 0; + } + + if (!hasFeatures) { + this._proto._no_auth_received(_callback); + + return; + } + + const matched = Array.from(bodyWrap.getElementsByTagName("mechanism")).map(m => this.mechanisms[m.textContent]).filter(m => m); + + if (matched.length === 0) { + if (bodyWrap.getElementsByTagName("auth").length === 0) { + // There are no matching SASL mechanisms and also no legacy + // auth available. + this._proto._no_auth_received(_callback); + + return; + } + } + + if (this.do_authentication !== false) { + this.authenticate(matched); + } + } + /** Function: sortMechanismsByPriority + * + * Sorts an array of objects with prototype SASLMechanism according to + * their priorities. + * + * Parameters: + * (Array) mechanisms - Array of SASL mechanisms. + * + */ + + + sortMechanismsByPriority(mechanisms) { + // eslint-disable-line class-methods-use-this + // Sorting mechanisms according to priority. + for (let i = 0; i < mechanisms.length - 1; ++i) { + let higher = i; + + for (let j = i + 1; j < mechanisms.length; ++j) { + if (mechanisms[j].priority > mechanisms[higher].priority) { + higher = j; + } + } + + if (higher !== i) { + const swap = mechanisms[i]; + mechanisms[i] = mechanisms[higher]; + mechanisms[higher] = swap; + } + } + + return mechanisms; + } + /** Function: authenticate + * Set up authentication + * + * Continues the initial connection request by setting up authentication + * handlers and starting the authentication process. + * + * SASL authentication will be attempted if available, otherwise + * the code will fall back to legacy authentication. + * + * Parameters: + * (Array) matched - Array of SASL mechanisms supported. + * + */ + + + authenticate(matched) { + if (!this._attemptSASLAuth(matched)) { + this._attemptLegacyAuth(); + } + } + /** PrivateFunction: _attemptSASLAuth + * + * Iterate through an array of SASL mechanisms and attempt authentication + * with the highest priority (enabled) mechanism. + * + * Parameters: + * (Array) mechanisms - Array of SASL mechanisms. + * + * Returns: + * (Boolean) mechanism_found - true or false, depending on whether a + * valid SASL mechanism was found with which authentication could be + * started. + */ + + + _attemptSASLAuth(mechanisms) { + mechanisms = this.sortMechanismsByPriority(mechanisms || []); + let mechanism_found = false; + + for (let i = 0; i < mechanisms.length; ++i) { + if (!mechanisms[i].test(this)) { + continue; + } + + this._sasl_success_handler = this._addSysHandler(this._sasl_success_cb.bind(this), null, "success", null, null); + this._sasl_failure_handler = this._addSysHandler(this._sasl_failure_cb.bind(this), null, "failure", null, null); + this._sasl_challenge_handler = this._addSysHandler(this._sasl_challenge_cb.bind(this), null, "challenge", null, null); + this._sasl_mechanism = new mechanisms[i](); + + this._sasl_mechanism.onStart(this); + + const request_auth_exchange = $build("auth", { + 'xmlns': Strophe.NS.SASL, + 'mechanism': this._sasl_mechanism.name + }); + + if (this._sasl_mechanism.isClientFirst) { + const response = this._sasl_mechanism.onChallenge(this, null); + + request_auth_exchange.t(Object(abab["btoa"])(response)); + } + + this.send(request_auth_exchange.tree()); + mechanism_found = true; + break; + } + + return mechanism_found; + } + /** PrivateFunction: _sasl_challenge_cb + * _Private_ handler for the SASL challenge + * + */ + + + _sasl_challenge_cb(elem) { + const challenge = Object(abab["atob"])(Strophe.getText(elem)); + + const response = this._sasl_mechanism.onChallenge(this, challenge); + + const stanza = $build('response', { + 'xmlns': Strophe.NS.SASL + }); + + if (response !== "") { + stanza.t(Object(abab["btoa"])(response)); + } + + this.send(stanza.tree()); + return true; + } + /** PrivateFunction: _attemptLegacyAuth + * + * Attempt legacy (i.e. non-SASL) authentication. + */ + + + _attemptLegacyAuth() { + if (Strophe.getNodeFromJid(this.jid) === null) { + // we don't have a node, which is required for non-anonymous + // client connections + this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.MISSING_JID_NODE); + + this.disconnect(Strophe.ErrorCondition.MISSING_JID_NODE); + } else { + // Fall back to legacy authentication + this._changeConnectStatus(Strophe.Status.AUTHENTICATING, null); + + this._addSysHandler(this._onLegacyAuthIQResult.bind(this), null, null, null, "_auth_1"); + + this.send($iq({ + 'type': "get", + 'to': this.domain, + 'id': "_auth_1" + }).c("query", { + xmlns: Strophe.NS.AUTH + }).c("username", {}).t(Strophe.getNodeFromJid(this.jid)).tree()); + } + } + /** PrivateFunction: _onLegacyAuthIQResult + * _Private_ handler for legacy authentication. + * + * This handler is called in response to the initial + * for legacy authentication. It builds an authentication and + * sends it, creating a handler (calling back to _auth2_cb()) to + * handle the result + * + * Parameters: + * (XMLElement) elem - The stanza that triggered the callback. + * + * Returns: + * false to remove the handler. + */ + + + _onLegacyAuthIQResult(elem) { + // eslint-disable-line no-unused-vars + // build plaintext auth iq + const iq = $iq({ + type: "set", + id: "_auth_2" + }).c('query', { + xmlns: Strophe.NS.AUTH + }).c('username', {}).t(Strophe.getNodeFromJid(this.jid)).up().c('password').t(this.pass); + + if (!Strophe.getResourceFromJid(this.jid)) { + // since the user has not supplied a resource, we pick + // a default one here. unlike other auth methods, the server + // cannot do this for us. + this.jid = Strophe.getBareJidFromJid(this.jid) + '/strophe'; + } + + iq.up().c('resource', {}).t(Strophe.getResourceFromJid(this.jid)); + + this._addSysHandler(this._auth2_cb.bind(this), null, null, null, "_auth_2"); + + this.send(iq.tree()); + return false; + } + /** PrivateFunction: _sasl_success_cb + * _Private_ handler for succesful SASL authentication. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _sasl_success_cb(elem) { + if (this._sasl_data["server-signature"]) { + let serverSignature; + const success = Object(abab["atob"])(Strophe.getText(elem)); + const attribMatch = /([a-z]+)=([^,]+)(,|$)/; + const matches = success.match(attribMatch); + + if (matches[1] === "v") { + serverSignature = matches[2]; + } + + if (serverSignature !== this._sasl_data["server-signature"]) { + // remove old handlers + this.deleteHandler(this._sasl_failure_handler); + this._sasl_failure_handler = null; + + if (this._sasl_challenge_handler) { + this.deleteHandler(this._sasl_challenge_handler); + this._sasl_challenge_handler = null; + } + + this._sasl_data = {}; + return this._sasl_failure_cb(null); + } + } + + Strophe.info("SASL authentication succeeded."); + + if (this._sasl_mechanism) { + this._sasl_mechanism.onSuccess(); + } // remove old handlers + + + this.deleteHandler(this._sasl_failure_handler); + this._sasl_failure_handler = null; + + if (this._sasl_challenge_handler) { + this.deleteHandler(this._sasl_challenge_handler); + this._sasl_challenge_handler = null; + } + + const streamfeature_handlers = []; + + const wrapper = (handlers, elem) => { + while (handlers.length) { + this.deleteHandler(handlers.pop()); + } + + this._onStreamFeaturesAfterSASL(elem); + + return false; + }; + + streamfeature_handlers.push(this._addSysHandler(elem => wrapper(streamfeature_handlers, elem), null, "stream:features", null, null)); + streamfeature_handlers.push(this._addSysHandler(elem => wrapper(streamfeature_handlers, elem), Strophe.NS.STREAM, "features", null, null)); // we must send an xmpp:restart now + + this._sendRestart(); + + return false; + } + /** PrivateFunction: _onStreamFeaturesAfterSASL + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _onStreamFeaturesAfterSASL(elem) { + // save stream:features for future usage + this.features = elem; + + for (let i = 0; i < elem.childNodes.length; i++) { + const child = elem.childNodes[i]; + + if (child.nodeName === 'bind') { + this.do_bind = true; + } + + if (child.nodeName === 'session') { + this.do_session = true; + } + } + + if (!this.do_bind) { + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null); + + return false; + } else if (!this.options.explicitResourceBinding) { + this.bind(); + } else { + this._changeConnectStatus(Strophe.Status.BINDREQUIRED, null); + } + + return false; + } + /** Function: bind + * + * Sends an IQ to the XMPP server to bind a JID resource for this session. + * + * https://tools.ietf.org/html/rfc6120#section-7.5 + * + * If `explicitResourceBinding` was set to a truthy value in the options + * passed to the Strophe.Connection constructor, then this function needs + * to be called explicitly by the client author. + * + * Otherwise it'll be called automatically as soon as the XMPP server + * advertises the "urn:ietf:params:xml:ns:xmpp-bind" stream feature. + */ + + + bind() { + if (!this.do_bind) { + Strophe.log(Strophe.LogLevel.INFO, "Strophe.Connection.prototype.bind called but \"do_bind\" is false"); + return; + } + + this._addSysHandler(this._onResourceBindResultIQ.bind(this), null, null, null, "_bind_auth_2"); + + const resource = Strophe.getResourceFromJid(this.jid); + + if (resource) { + this.send($iq({ + type: "set", + id: "_bind_auth_2" + }).c('bind', { + xmlns: Strophe.NS.BIND + }).c('resource', {}).t(resource).tree()); + } else { + this.send($iq({ + type: "set", + id: "_bind_auth_2" + }).c('bind', { + xmlns: Strophe.NS.BIND + }).tree()); + } + } + /** PrivateFunction: _onResourceBindIQ + * _Private_ handler for binding result and session start. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _onResourceBindResultIQ(elem) { + if (elem.getAttribute("type") === "error") { + Strophe.warn("Resource binding failed."); + const conflict = elem.getElementsByTagName("conflict"); + let condition; + + if (conflict.length > 0) { + condition = Strophe.ErrorCondition.CONFLICT; + } + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, condition, elem); + + return false; + } // TODO - need to grab errors + + + const bind = elem.getElementsByTagName("bind"); + + if (bind.length > 0) { + const jidNode = bind[0].getElementsByTagName("jid"); + + if (jidNode.length > 0) { + this.jid = Strophe.getText(jidNode[0]); + + if (this.do_session) { + this._establishSession(); + } else { + this.authenticated = true; + + this._changeConnectStatus(Strophe.Status.CONNECTED, null); + } + } + } else { + Strophe.warn("Resource binding failed."); + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + return false; + } + } + /** PrivateFunction: _establishSession + * Send IQ request to establish a session with the XMPP server. + * + * See https://xmpp.org/rfcs/rfc3921.html#session + * + * Note: The protocol for session establishment has been determined as + * unnecessary and removed in RFC-6121. + */ + + + _establishSession() { + if (!this.do_session) { + throw new Error("Strophe.Connection.prototype._establishSession " + "called but apparently ".concat(Strophe.NS.SESSION, " wasn't advertised by the server")); + } + + this._addSysHandler(this._onSessionResultIQ.bind(this), null, null, null, "_session_auth_2"); + + this.send($iq({ + type: "set", + id: "_session_auth_2" + }).c('session', { + xmlns: Strophe.NS.SESSION + }).tree()); + } + /** PrivateFunction: _onSessionResultIQ + * _Private_ handler for the server's IQ response to a client's session + * request. + * + * This sets Connection.authenticated to true on success, which + * starts the processing of user handlers. + * + * See https://xmpp.org/rfcs/rfc3921.html#session + * + * Note: The protocol for session establishment has been determined as + * unnecessary and removed in RFC-6121. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _onSessionResultIQ(elem) { + if (elem.getAttribute("type") === "result") { + this.authenticated = true; + + this._changeConnectStatus(Strophe.Status.CONNECTED, null); + } else if (elem.getAttribute("type") === "error") { + Strophe.warn("Session creation failed."); + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + return false; + } + + return false; + } + /** PrivateFunction: _sasl_failure_cb + * _Private_ handler for SASL authentication failure. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _sasl_failure_cb(elem) { + // delete unneeded handlers + if (this._sasl_success_handler) { + this.deleteHandler(this._sasl_success_handler); + this._sasl_success_handler = null; + } + + if (this._sasl_challenge_handler) { + this.deleteHandler(this._sasl_challenge_handler); + this._sasl_challenge_handler = null; + } + + if (this._sasl_mechanism) this._sasl_mechanism.onFailure(); + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + return false; + } + /** PrivateFunction: _auth2_cb + * _Private_ handler to finish legacy authentication. + * + * This handler is called when the result from the jabber:iq:auth + * stanza is returned. + * + * Parameters: + * (XMLElement) elem - The stanza that triggered the callback. + * + * Returns: + * false to remove the handler. + */ + + + _auth2_cb(elem) { + if (elem.getAttribute("type") === "result") { + this.authenticated = true; + + this._changeConnectStatus(Strophe.Status.CONNECTED, null); + } else if (elem.getAttribute("type") === "error") { + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + this.disconnect('authentication failed'); + } + + return false; + } + /** PrivateFunction: _addSysTimedHandler + * _Private_ function to add a system level timed handler. + * + * This function is used to add a Strophe.TimedHandler for the + * library code. System timed handlers are allowed to run before + * authentication is complete. + * + * Parameters: + * (Integer) period - The period of the handler. + * (Function) handler - The callback function. + */ + + + _addSysTimedHandler(period, handler) { + const thand = new Strophe.TimedHandler(period, handler); + thand.user = false; + this.addTimeds.push(thand); + return thand; + } + /** PrivateFunction: _addSysHandler + * _Private_ function to add a system level stanza handler. + * + * This function is used to add a Strophe.Handler for the + * library code. System stanza handlers are allowed to run before + * authentication is complete. + * + * Parameters: + * (Function) handler - The callback function. + * (String) ns - The namespace to match. + * (String) name - The stanza name to match. + * (String) type - The stanza type attribute to match. + * (String) id - The stanza id attribute to match. + */ + + + _addSysHandler(handler, ns, name, type, id) { + const hand = new Strophe.Handler(handler, ns, name, type, id); + hand.user = false; + this.addHandlers.push(hand); + return hand; + } + /** PrivateFunction: _onDisconnectTimeout + * _Private_ timeout handler for handling non-graceful disconnection. + * + * If the graceful disconnect process does not complete within the + * time allotted, this handler finishes the disconnect anyway. + * + * Returns: + * false to remove the handler. + */ + + + _onDisconnectTimeout() { + Strophe.debug("_onDisconnectTimeout was called"); + + this._changeConnectStatus(Strophe.Status.CONNTIMEOUT, null); + + this._proto._onDisconnectTimeout(); // actually disconnect + + + this._doDisconnect(); + + return false; + } + /** PrivateFunction: _onIdle + * _Private_ handler to process events during idle cycle. + * + * This handler is called every 100ms to fire timed handlers that + * are ready and keep poll requests going. + */ + + + _onIdle() { + // add timed handlers scheduled for addition + // NOTE: we add before remove in the case a timed handler is + // added and then deleted before the next _onIdle() call. + while (this.addTimeds.length > 0) { + this.timedHandlers.push(this.addTimeds.pop()); + } // remove timed handlers that have been scheduled for deletion + + + while (this.removeTimeds.length > 0) { + const thand = this.removeTimeds.pop(); + const i = this.timedHandlers.indexOf(thand); + + if (i >= 0) { + this.timedHandlers.splice(i, 1); + } + } // call ready timed handlers + + + const now = new Date().getTime(); + const newList = []; + + for (let i = 0; i < this.timedHandlers.length; i++) { + const thand = this.timedHandlers[i]; + + if (this.authenticated || !thand.user) { + const since = thand.lastCalled + thand.period; + + if (since - now <= 0) { + if (thand.run()) { + newList.push(thand); + } + } else { + newList.push(thand); + } + } + } + + this.timedHandlers = newList; + clearTimeout(this._idleTimeout); + + this._proto._onIdle(); // reactivate the timer only if connected + + + if (this.connected) { + this._idleTimeout = setTimeout(() => this._onIdle(), 100); + } + } + +}; +/** Class: Strophe.SASLMechanism + * + * encapsulates SASL authentication mechanisms. + * + * User code may override the priority for each mechanism or disable it completely. + * See for information about changing priority and for informatian on + * how to disable a mechanism. + * + * By default, all mechanisms are enabled and the priorities are + * + * SCRAM-SHA-1 - 60 + * PLAIN - 50 + * OAUTHBEARER - 40 + * X-OAUTH2 - 30 + * ANONYMOUS - 20 + * EXTERNAL - 10 + * + * See: Strophe.Connection.addSupportedSASLMechanisms + */ + +Strophe.SASLMechanism = class SASLMechanism { + /** + * PrivateConstructor: Strophe.SASLMechanism + * SASL auth mechanism abstraction. + * + * Parameters: + * (String) name - SASL Mechanism name. + * (Boolean) isClientFirst - If client should send response first without challenge. + * (Number) priority - Priority. + * + * Returns: + * A new Strophe.SASLMechanism object. + */ + constructor(name, isClientFirst, priority) { + /** PrivateVariable: name + * Mechanism name. + */ + this.name = name; + /** PrivateVariable: isClientFirst + * If client sends response without initial server challenge. + */ + + this.isClientFirst = isClientFirst; + /** Variable: priority + * Determines which is chosen for authentication (Higher is better). + * Users may override this to prioritize mechanisms differently. + * + * Example: (This will cause Strophe to choose the mechanism that the server sent first) + * + * > Strophe.SASLPlain.priority = Strophe.SASLSHA1.priority; + * + * See for a list of available mechanisms. + * + */ + + this.priority = priority; + } + /** + * Function: test + * Checks if mechanism able to run. + * To disable a mechanism, make this return false; + * + * To disable plain authentication run + * > Strophe.SASLPlain.test = function() { + * > return false; + * > } + * + * See for a list of available mechanisms. + * + * Parameters: + * (Strophe.Connection) connection - Target Connection. + * + * Returns: + * (Boolean) If mechanism was able to run. + */ + + + static test(connection) { + // eslint-disable-line no-unused-vars + return true; + } + /** PrivateFunction: onStart + * Called before starting mechanism on some connection. + * + * Parameters: + * (Strophe.Connection) connection - Target Connection. + */ + + + onStart(connection) { + this._connection = connection; + } + /** PrivateFunction: onChallenge + * Called by protocol implementation on incoming challenge. If client is + * first (isClientFirst === true) challenge will be null on the first call. + * + * Parameters: + * (Strophe.Connection) connection - Target Connection. + * (String) challenge - current challenge to handle. + * + * Returns: + * (String) Mechanism response. + */ + + + onChallenge(connection, challenge) { + // eslint-disable-line + throw new Error("You should implement challenge handling!"); + } + /** PrivateFunction: onFailure + * Protocol informs mechanism implementation about SASL failure. + */ + + + onFailure() { + this._connection = null; + } + /** PrivateFunction: onSuccess + * Protocol informs mechanism implementation about SASL success. + */ + + + onSuccess() { + this._connection = null; + } + +}; +/** Constants: SASL mechanisms + * Available authentication mechanisms + * + * Strophe.SASLAnonymous - SASL ANONYMOUS authentication. + * Strophe.SASLPlain - SASL PLAIN authentication. + * Strophe.SASLSHA1 - SASL SCRAM-SHA-1 authentication + * Strophe.SASLOAuthBearer - SASL OAuth Bearer authentication + * Strophe.SASLExternal - SASL EXTERNAL authentication + * Strophe.SASLXOAuth2 - SASL X-OAuth2 authentication + */ +// Building SASL callbacks + +Strophe.SASLAnonymous = class SASLAnonymous extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLAnonymous + * SASL ANONYMOUS authentication. + */ + constructor() { + super(Strophe.SASLAnonymous.name, false, Strophe.SASLAnonymous.priority); + } + + static get name() { + return "ANONYMOUS"; + } + + static get priority() { + return 20; + } + + static test(connection) { + return connection.authcid === null; + } + +}; +Strophe.SASLPlain = class SASLPlain extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLPlain + * SASL PLAIN authentication. + */ + constructor() { + super(Strophe.SASLPlain.name, true, Strophe.SASLPlain.priority); + } + + static get name() { + return "PLAIN"; + } + + static get priority() { + return 50; + } + + static test(connection) { + return connection.authcid !== null; + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + const { + authcid, + authzid, + domain, + pass + } = connection; + + if (!domain) { + throw new Error("SASLPlain onChallenge: domain is not defined!"); + } // Only include authzid if it differs from authcid. + // See: https://tools.ietf.org/html/rfc6120#section-6.3.8 + + + let auth_str = authzid !== "".concat(authcid, "@").concat(domain) ? authzid : ''; + auth_str = auth_str + "\u0000"; + auth_str = auth_str + authcid; + auth_str = auth_str + "\u0000"; + auth_str = auth_str + pass; + return utils.utf16to8(auth_str); + } + +}; +Strophe.SASLSHA1 = class SASLSHA1 extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLSHA1 + * SASL SCRAM SHA 1 authentication. + */ + constructor() { + super(Strophe.SASLSHA1.name, true, Strophe.SASLSHA1.priority); + } + + static get name() { + return "SCRAM-SHA-1"; + } + + static get priority() { + return 60; + } + + static test(connection) { + return connection.authcid !== null; + } + + onChallenge(connection, challenge, test_cnonce) { + const cnonce = test_cnonce || MD5.hexdigest("" + Math.random() * 1234567890); + let auth_str = "n=" + utils.utf16to8(connection.authcid); + auth_str += ",r="; + auth_str += cnonce; + connection._sasl_data.cnonce = cnonce; + connection._sasl_data["client-first-message-bare"] = auth_str; + auth_str = "n,," + auth_str; + + this.onChallenge = (connection, challenge) => { + let nonce, salt, iter, Hi, U, U_old, i, k; + let responseText = "c=biws,"; + let authMessage = "".concat(connection._sasl_data["client-first-message-bare"], ",").concat(challenge, ","); + const cnonce = connection._sasl_data.cnonce; + const attribMatch = /([a-z]+)=([^,]+)(,|$)/; + + while (challenge.match(attribMatch)) { + const matches = challenge.match(attribMatch); + challenge = challenge.replace(matches[0], ""); + + switch (matches[1]) { + case "r": + nonce = matches[2]; + break; + + case "s": + salt = matches[2]; + break; + + case "i": + iter = matches[2]; + break; + } + } + + if (nonce.substr(0, cnonce.length) !== cnonce) { + connection._sasl_data = {}; + return connection._sasl_failure_cb(); + } + + responseText += "r=" + nonce; + authMessage += responseText; + salt = Object(abab["atob"])(salt); + salt += "\x00\x00\x00\x01"; + const pass = utils.utf16to8(connection.pass); + Hi = U_old = sha1["a" /* default */].core_hmac_sha1(pass, salt); + + for (i = 1; i < iter; i++) { + U = sha1["a" /* default */].core_hmac_sha1(pass, sha1["a" /* default */].binb2str(U_old)); + + for (k = 0; k < 5; k++) { + Hi[k] ^= U[k]; + } + + U_old = U; + } + + Hi = sha1["a" /* default */].binb2str(Hi); + const clientKey = sha1["a" /* default */].core_hmac_sha1(Hi, "Client Key"); + const serverKey = sha1["a" /* default */].str_hmac_sha1(Hi, "Server Key"); + const clientSignature = sha1["a" /* default */].core_hmac_sha1(sha1["a" /* default */].str_sha1(sha1["a" /* default */].binb2str(clientKey)), authMessage); + connection._sasl_data["server-signature"] = sha1["a" /* default */].b64_hmac_sha1(serverKey, authMessage); + + for (k = 0; k < 5; k++) { + clientKey[k] ^= clientSignature[k]; + } + + responseText += ",p=" + Object(abab["btoa"])(sha1["a" /* default */].binb2str(clientKey)); + return responseText; + }; + + return auth_str; + } + +}; +Strophe.SASLOAuthBearer = class SASLOAuthBearer extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLOAuthBearer + * SASL OAuth Bearer authentication. + */ + constructor() { + super(Strophe.SASLOAuthBearer.name, true, Strophe.SASLOAuthBearer.priority); + } + + static get name() { + return "OAUTHBEARER"; + } + + static get priority() { + return 40; + } + + static test(connection) { + return connection.pass !== null; + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + let auth_str = 'n,'; + + if (connection.authcid !== null) { + auth_str = auth_str + 'a=' + connection.authzid; + } + + auth_str = auth_str + ','; + auth_str = auth_str + "\u0001"; + auth_str = auth_str + 'auth=Bearer '; + auth_str = auth_str + connection.pass; + auth_str = auth_str + "\u0001"; + auth_str = auth_str + "\u0001"; + return utils.utf16to8(auth_str); + } + +}; +Strophe.SASLExternal = class SASLExternal extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLExternal + * SASL EXTERNAL authentication. + * + * The EXTERNAL mechanism allows a client to request the server to use + * credentials established by means external to the mechanism to + * authenticate the client. The external means may be, for instance, + * TLS services. + */ + constructor() { + super(Strophe.SASLExternal.name, true, Strophe.SASLExternal.priority); + } + + static get name() { + return "EXTERNAL"; + } + + static get priority() { + return 10; + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + + /** According to XEP-178, an authzid SHOULD NOT be presented when the + * authcid contained or implied in the client certificate is the JID (i.e. + * authzid) with which the user wants to log in as. + * + * To NOT send the authzid, the user should therefore set the authcid equal + * to the JID when instantiating a new Strophe.Connection object. + */ + return connection.authcid === connection.authzid ? '' : connection.authzid; + } + +}; +Strophe.SASLXOAuth2 = class SASLXOAuth2 extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLXOAuth2 + * SASL X-OAuth2 authentication. + */ + constructor() { + super(Strophe.SASLXOAuth2.name, true, Strophe.SASLXOAuth2.priority); + } + + static get name() { + return "X-OAUTH2"; + } + + static get priority() { + return 30; + } + + static test(connection) { + return connection.pass !== null; + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + let auth_str = '\u0000'; + + if (connection.authcid !== null) { + auth_str = auth_str + connection.authzid; + } + + auth_str = auth_str + "\u0000"; + auth_str = auth_str + connection.pass; + return utils.utf16to8(auth_str); + } + +}; + +/* harmony default export */ var core = __webpack_exports__["f"] = ({ + 'Strophe': Strophe, + '$build': $build, + '$iq': $iq, + '$msg': $msg, + '$pres': $pres, + 'SHA1': sha1["a" /* default */], + 'MD5': MD5, + 'b64_hmac_sha1': sha1["a" /* default */].b64_hmac_sha1, + 'b64_sha1': sha1["a" /* default */].b64_sha1, + 'str_hmac_sha1': sha1["a" /* default */].str_hmac_sha1, + 'str_sha1': sha1["a" /* default */].str_sha1 +}); + +/***/ }), +/* 1 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, "a", function() { return /* binding */ $build; }); +__webpack_require__.d(__webpack_exports__, "b", function() { return /* binding */ $iq; }); +__webpack_require__.d(__webpack_exports__, "d", function() { return /* binding */ Strophe; }); +__webpack_require__.d(__webpack_exports__, "c", function() { return /* reexport */ SHA1; }); + +// UNUSED EXPORTS: $msg, $pres, MD5 + +// EXTERNAL MODULE: ./node_modules/strophe.js/src/shims.js +var shims = __webpack_require__(9); + +// CONCATENATED MODULE: ./node_modules/strophe.js/src/md5.js +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/* + * Everything that isn't used by Strophe has been stripped here! + */ + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +const safe_add = function safe_add(x, y) { + const lsw = (x & 0xFFFF) + (y & 0xFFFF); + const msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return msw << 16 | lsw & 0xFFFF; +}; +/* + * Bitwise rotate a 32-bit number to the left. + */ + + +const bit_rol = function bit_rol(num, cnt) { + return num << cnt | num >>> 32 - cnt; +}; +/* + * Convert a string to an array of little-endian words + */ + + +const str2binl = function str2binl(str) { + if (typeof str !== "string") { + throw new Error("str2binl was passed a non-string"); + } + + const bin = []; + + for (let i = 0; i < str.length * 8; i += 8) { + bin[i >> 5] |= (str.charCodeAt(i / 8) & 255) << i % 32; + } + + return bin; +}; +/* + * Convert an array of little-endian words to a string + */ + + +const binl2str = function binl2str(bin) { + let str = ""; + + for (let i = 0; i < bin.length * 32; i += 8) { + str += String.fromCharCode(bin[i >> 5] >>> i % 32 & 255); + } + + return str; +}; +/* + * Convert an array of little-endian words to a hex string. + */ + + +const binl2hex = function binl2hex(binarray) { + const hex_tab = "0123456789abcdef"; + let str = ""; + + for (let i = 0; i < binarray.length * 4; i++) { + str += hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 + 4 & 0xF) + hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 & 0xF); + } + + return str; +}; +/* + * These functions implement the four basic operations the algorithm uses. + */ + + +const md5_cmn = function md5_cmn(q, a, b, x, s, t) { + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); +}; + +const md5_ff = function md5_ff(a, b, c, d, x, s, t) { + return md5_cmn(b & c | ~b & d, a, b, x, s, t); +}; + +const md5_gg = function md5_gg(a, b, c, d, x, s, t) { + return md5_cmn(b & d | c & ~d, a, b, x, s, t); +}; + +const md5_hh = function md5_hh(a, b, c, d, x, s, t) { + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +}; + +const md5_ii = function md5_ii(a, b, c, d, x, s, t) { + return md5_cmn(c ^ (b | ~d), a, b, x, s, t); +}; +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ + + +const core_md5 = function core_md5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[(len + 64 >>> 9 << 4) + 14] = len; + let a = 1732584193; + let b = -271733879; + let c = -1732584194; + let d = 271733878; + let olda, oldb, oldc, oldd; + + for (let i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936); + d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); + a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); + a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); + a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844); + d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + + return [a, b, c, d]; +}; +/* + * These are the functions you'll usually want to call. + * They take string arguments and return either hex or base-64 encoded + * strings. + */ + + +const MD5 = { + hexdigest: function hexdigest(s) { + return binl2hex(core_md5(str2binl(s), s.length * 8)); + }, + hash: function hash(s) { + return binl2str(core_md5(str2binl(s), s.length * 8)); + } +}; + +// CONCATENATED MODULE: ./node_modules/strophe.js/src/sha1.js +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +/* global define */ + +/* Some functions and variables have been stripped for use with Strophe */ + +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << 24 - len % 32; + x[(len + 64 >> 9 << 4) + 15] = len; + var w = new Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + var i, j, t, olda, oldb, oldc, oldd, olde; + + for (i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + olde = e; + + for (j = 0; j < 80; j++) { + if (j < 16) { + w[j] = x[i + j]; + } else { + w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); + } + + t = sha1_safe_add(sha1_safe_add(rol(a, 5), sha1_ft(j, b, c, d)), sha1_safe_add(sha1_safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = sha1_safe_add(a, olda); + b = sha1_safe_add(b, oldb); + c = sha1_safe_add(c, oldc); + d = sha1_safe_add(d, oldd); + e = sha1_safe_add(e, olde); + } + + return [a, b, c, d, e]; +} +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ + + +function sha1_ft(t, b, c, d) { + if (t < 20) { + return b & c | ~b & d; + } + + if (t < 40) { + return b ^ c ^ d; + } + + if (t < 60) { + return b & c | b & d | c & d; + } + + return b ^ c ^ d; +} +/* + * Determine the appropriate additive constant for the current iteration + */ + + +function sha1_kt(t) { + return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514; +} +/* + * Calculate the HMAC-SHA1 of a key and some data + */ + + +function core_hmac_sha1(key, data) { + var bkey = str2binb(key); + + if (bkey.length > 16) { + bkey = core_sha1(bkey, key.length * 8); + } + + var ipad = new Array(16), + opad = new Array(16); + + for (var i = 0; i < 16; i++) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * 8); + return core_sha1(opad.concat(hash), 512 + 160); +} +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + + +function sha1_safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return msw << 16 | lsw & 0xFFFF; +} +/* + * Bitwise rotate a 32-bit number to the left. + */ + + +function rol(num, cnt) { + return num << cnt | num >>> 32 - cnt; +} +/* + * Convert an 8-bit or 16-bit string to an array of big-endian words + * In 8-bit function, characters >255 have their hi-byte silently ignored. + */ + + +function str2binb(str) { + var bin = []; + var mask = 255; + + for (var i = 0; i < str.length * 8; i += 8) { + bin[i >> 5] |= (str.charCodeAt(i / 8) & mask) << 24 - i % 32; + } + + return bin; +} +/* + * Convert an array of big-endian words to a base-64 string + */ + + +function binb2b64(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + var triplet, j; + + for (var i = 0; i < binarray.length * 4; i += 3) { + triplet = (binarray[i >> 2] >> 8 * (3 - i % 4) & 0xFF) << 16 | (binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4) & 0xFF) << 8 | binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4) & 0xFF; + + for (j = 0; j < 4; j++) { + if (i * 8 + j * 6 > binarray.length * 32) { + str += "="; + } else { + str += tab.charAt(triplet >> 6 * (3 - j) & 0x3F); + } + } + } + + return str; +} +/* + * Convert an array of big-endian words to a string + */ + + +function binb2str(bin) { + var str = ""; + var mask = 255; + + for (var i = 0; i < bin.length * 32; i += 8) { + str += String.fromCharCode(bin[i >> 5] >>> 24 - i % 32 & mask); + } + + return str; +} +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ + + +const SHA1 = { + b64_hmac_sha1: function b64_hmac_sha1(key, data) { + return binb2b64(core_hmac_sha1(key, data)); + }, + b64_sha1: function b64_sha1(s) { + return binb2b64(core_sha1(str2binb(s), s.length * 8)); + }, + binb2str: binb2str, + core_hmac_sha1: core_hmac_sha1, + str_hmac_sha1: function str_hmac_sha1(key, data) { + return binb2str(core_hmac_sha1(key, data)); + }, + str_sha1: function str_sha1(s) { + return binb2str(core_sha1(str2binb(s), s.length * 8)); + } +}; + +// CONCATENATED MODULE: ./node_modules/strophe.js/src/utils.js +const utils = { + utf16to8: function utf16to8(str) { + var i, c; + var out = ""; + var len = str.length; + + for (i = 0; i < len; i++) { + c = str.charCodeAt(i); + + if (c >= 0x0000 && c <= 0x007F) { + out += str.charAt(i); + } else if (c > 0x07FF) { + out += String.fromCharCode(0xE0 | c >> 12 & 0x0F); + out += String.fromCharCode(0x80 | c >> 6 & 0x3F); + out += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } else { + out += String.fromCharCode(0xC0 | c >> 6 & 0x1F); + out += String.fromCharCode(0x80 | c >> 0 & 0x3F); + } + } + + return out; + }, + addCookies: function addCookies(cookies) { + /* Parameters: + * (Object) cookies - either a map of cookie names + * to string values or to maps of cookie values. + * + * For example: + * { "myCookie": "1234" } + * + * or: + * { "myCookie": { + * "value": "1234", + * "domain": ".example.org", + * "path": "/", + * "expires": expirationDate + * } + * } + * + * These values get passed to Strophe.Connection via + * options.cookies + */ + cookies = cookies || {}; + + for (const cookieName in cookies) { + if (Object.prototype.hasOwnProperty.call(cookies, cookieName)) { + let expires = ''; + let domain = ''; + let path = ''; + const cookieObj = cookies[cookieName]; + const isObj = typeof cookieObj === "object"; + const cookieValue = escape(unescape(isObj ? cookieObj.value : cookieObj)); + + if (isObj) { + expires = cookieObj.expires ? ";expires=" + cookieObj.expires : ''; + domain = cookieObj.domain ? ";domain=" + cookieObj.domain : ''; + path = cookieObj.path ? ";path=" + cookieObj.path : ''; + } + + document.cookie = cookieName + '=' + cookieValue + expires + domain + path; + } + } + } +}; + +// EXTERNAL MODULE: ./node_modules/abab/index.js +var abab = __webpack_require__(10); + +// CONCATENATED MODULE: ./node_modules/strophe.js/src/core.js +/* + This program is distributed under the terms of the MIT license. + Please see the LICENSE file for details. + + Copyright 2006-2018, OGG, LLC +*/ + +/*global define, document, sessionStorage, setTimeout, clearTimeout, ActiveXObject, DOMParser, btoa, atob */ + + + + + +/** Function: $build + * Create a Strophe.Builder. + * This is an alias for 'new Strophe.Builder(name, attrs)'. + * + * Parameters: + * (String) name - The root element name. + * (Object) attrs - The attributes for the root element in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $build(name, attrs) { + return new Strophe.Builder(name, attrs); +} +/** Function: $msg + * Create a Strophe.Builder with a element as the root. + * + * Parameters: + * (Object) attrs - The element attributes in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $msg(attrs) { + return new Strophe.Builder("message", attrs); +} +/** Function: $iq + * Create a Strophe.Builder with an element as the root. + * + * Parameters: + * (Object) attrs - The element attributes in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $iq(attrs) { + return new Strophe.Builder("iq", attrs); +} +/** Function: $pres + * Create a Strophe.Builder with a element as the root. + * + * Parameters: + * (Object) attrs - The element attributes in object notation. + * + * Returns: + * A new Strophe.Builder object. + */ + +function $pres(attrs) { + return new Strophe.Builder("presence", attrs); +} +/** Class: Strophe + * An object container for all Strophe library functions. + * + * This class is just a container for all the objects and constants + * used in the library. It is not meant to be instantiated, but to + * provide a namespace for library objects, constants, and functions. + */ + +const Strophe = { + /** Constant: VERSION */ + VERSION: "1.4.0", + + /** Constants: XMPP Namespace Constants + * Common namespace constants from the XMPP RFCs and XEPs. + * + * NS.HTTPBIND - HTTP BIND namespace from XEP 124. + * NS.BOSH - BOSH namespace from XEP 206. + * NS.CLIENT - Main XMPP client namespace. + * NS.AUTH - Legacy authentication namespace. + * NS.ROSTER - Roster operations namespace. + * NS.PROFILE - Profile namespace. + * NS.DISCO_INFO - Service discovery info namespace from XEP 30. + * NS.DISCO_ITEMS - Service discovery items namespace from XEP 30. + * NS.MUC - Multi-User Chat namespace from XEP 45. + * NS.SASL - XMPP SASL namespace from RFC 3920. + * NS.STREAM - XMPP Streams namespace from RFC 3920. + * NS.BIND - XMPP Binding namespace from RFC 3920 and RFC 6120. + * NS.SESSION - XMPP Session namespace from RFC 3920. + * NS.XHTML_IM - XHTML-IM namespace from XEP 71. + * NS.XHTML - XHTML body namespace from XEP 71. + */ + NS: { + HTTPBIND: "http://jabber.org/protocol/httpbind", + BOSH: "urn:xmpp:xbosh", + CLIENT: "jabber:client", + AUTH: "jabber:iq:auth", + ROSTER: "jabber:iq:roster", + PROFILE: "jabber:iq:profile", + DISCO_INFO: "http://jabber.org/protocol/disco#info", + DISCO_ITEMS: "http://jabber.org/protocol/disco#items", + MUC: "http://jabber.org/protocol/muc", + SASL: "urn:ietf:params:xml:ns:xmpp-sasl", + STREAM: "http://etherx.jabber.org/streams", + FRAMING: "urn:ietf:params:xml:ns:xmpp-framing", + BIND: "urn:ietf:params:xml:ns:xmpp-bind", + SESSION: "urn:ietf:params:xml:ns:xmpp-session", + VERSION: "jabber:iq:version", + STANZAS: "urn:ietf:params:xml:ns:xmpp-stanzas", + XHTML_IM: "http://jabber.org/protocol/xhtml-im", + XHTML: "http://www.w3.org/1999/xhtml" + }, + + /** Constants: XHTML_IM Namespace + * contains allowed tags, tag attributes, and css properties. + * Used in the createHtml function to filter incoming html into the allowed XHTML-IM subset. + * See http://xmpp.org/extensions/xep-0071.html#profile-summary for the list of recommended + * allowed tags and their attributes. + */ + XHTML: { + tags: ['a', 'blockquote', 'br', 'cite', 'em', 'img', 'li', 'ol', 'p', 'span', 'strong', 'ul', 'body'], + attributes: { + 'a': ['href'], + 'blockquote': ['style'], + 'br': [], + 'cite': ['style'], + 'em': [], + 'img': ['src', 'alt', 'style', 'height', 'width'], + 'li': ['style'], + 'ol': ['style'], + 'p': ['style'], + 'span': ['style'], + 'strong': [], + 'ul': ['style'], + 'body': [] + }, + css: ['background-color', 'color', 'font-family', 'font-size', 'font-style', 'font-weight', 'margin-left', 'margin-right', 'text-align', 'text-decoration'], + + /** Function: XHTML.validTag + * + * Utility method to determine whether a tag is allowed + * in the XHTML_IM namespace. + * + * XHTML tag names are case sensitive and must be lower case. + */ + validTag(tag) { + for (let i = 0; i < Strophe.XHTML.tags.length; i++) { + if (tag === Strophe.XHTML.tags[i]) { + return true; + } + } + + return false; + }, + + /** Function: XHTML.validAttribute + * + * Utility method to determine whether an attribute is allowed + * as recommended per XEP-0071 + * + * XHTML attribute names are case sensitive and must be lower case. + */ + validAttribute(tag, attribute) { + if (typeof Strophe.XHTML.attributes[tag] !== 'undefined' && Strophe.XHTML.attributes[tag].length > 0) { + for (let i = 0; i < Strophe.XHTML.attributes[tag].length; i++) { + if (attribute === Strophe.XHTML.attributes[tag][i]) { + return true; + } + } + } + + return false; + }, + + validCSS(style) { + for (let i = 0; i < Strophe.XHTML.css.length; i++) { + if (style === Strophe.XHTML.css[i]) { + return true; + } + } + + return false; + } + + }, + + /** Constants: Connection Status Constants + * Connection status constants for use by the connection handler + * callback. + * + * Status.ERROR - An error has occurred + * Status.CONNECTING - The connection is currently being made + * Status.CONNFAIL - The connection attempt failed + * Status.AUTHENTICATING - The connection is authenticating + * Status.AUTHFAIL - The authentication attempt failed + * Status.CONNECTED - The connection has succeeded + * Status.DISCONNECTED - The connection has been terminated + * Status.DISCONNECTING - The connection is currently being terminated + * Status.ATTACHED - The connection has been attached + * Status.REDIRECT - The connection has been redirected + * Status.CONNTIMEOUT - The connection has timed out + */ + Status: { + ERROR: 0, + CONNECTING: 1, + CONNFAIL: 2, + AUTHENTICATING: 3, + AUTHFAIL: 4, + CONNECTED: 5, + DISCONNECTED: 6, + DISCONNECTING: 7, + ATTACHED: 8, + REDIRECT: 9, + CONNTIMEOUT: 10, + BINDREQUIRED: 11, + ATTACHFAIL: 12 + }, + ErrorCondition: { + BAD_FORMAT: "bad-format", + CONFLICT: "conflict", + MISSING_JID_NODE: "x-strophe-bad-non-anon-jid", + NO_AUTH_MECH: "no-auth-mech", + UNKNOWN_REASON: "unknown" + }, + + /** Constants: Log Level Constants + * Logging level indicators. + * + * LogLevel.DEBUG - Debug output + * LogLevel.INFO - Informational output + * LogLevel.WARN - Warnings + * LogLevel.ERROR - Errors + * LogLevel.FATAL - Fatal errors + */ + LogLevel: { + DEBUG: 0, + INFO: 1, + WARN: 2, + ERROR: 3, + FATAL: 4 + }, + + /** PrivateConstants: DOM Element Type Constants + * DOM element types. + * + * ElementType.NORMAL - Normal element. + * ElementType.TEXT - Text data element. + * ElementType.FRAGMENT - XHTML fragment element. + */ + ElementType: { + NORMAL: 1, + TEXT: 3, + CDATA: 4, + FRAGMENT: 11 + }, + + /** PrivateConstants: Timeout Values + * Timeout values for error states. These values are in seconds. + * These should not be changed unless you know exactly what you are + * doing. + * + * TIMEOUT - Timeout multiplier. A waiting request will be considered + * failed after Math.floor(TIMEOUT * wait) seconds have elapsed. + * This defaults to 1.1, and with default wait, 66 seconds. + * SECONDARY_TIMEOUT - Secondary timeout multiplier. In cases where + * Strophe can detect early failure, it will consider the request + * failed if it doesn't return after + * Math.floor(SECONDARY_TIMEOUT * wait) seconds have elapsed. + * This defaults to 0.1, and with default wait, 6 seconds. + */ + TIMEOUT: 1.1, + SECONDARY_TIMEOUT: 0.1, + + /** Function: addNamespace + * This function is used to extend the current namespaces in + * Strophe.NS. It takes a key and a value with the key being the + * name of the new namespace, with its actual value. + * For example: + * Strophe.addNamespace('PUBSUB', "http://jabber.org/protocol/pubsub"); + * + * Parameters: + * (String) name - The name under which the namespace will be + * referenced under Strophe.NS + * (String) value - The actual namespace. + */ + addNamespace(name, value) { + Strophe.NS[name] = value; + }, + + /** Function: forEachChild + * Map a function over some or all child elements of a given element. + * + * This is a small convenience function for mapping a function over + * some or all of the children of an element. If elemName is null, all + * children will be passed to the function, otherwise only children + * whose tag names match elemName will be passed. + * + * Parameters: + * (XMLElement) elem - The element to operate on. + * (String) elemName - The child element tag name filter. + * (Function) func - The function to apply to each child. This + * function should take a single argument, a DOM element. + */ + forEachChild(elem, elemName, func) { + for (let i = 0; i < elem.childNodes.length; i++) { + const childNode = elem.childNodes[i]; + + if (childNode.nodeType === Strophe.ElementType.NORMAL && (!elemName || this.isTagEqual(childNode, elemName))) { + func(childNode); + } + } + }, + + /** Function: isTagEqual + * Compare an element's tag name with a string. + * + * This function is case sensitive. + * + * Parameters: + * (XMLElement) el - A DOM element. + * (String) name - The element name. + * + * Returns: + * true if the element's tag name matches _el_, and false + * otherwise. + */ + isTagEqual(el, name) { + return el.tagName === name; + }, + + /** PrivateVariable: _xmlGenerator + * _Private_ variable that caches a DOM document to + * generate elements. + */ + _xmlGenerator: null, + + /** Function: xmlGenerator + * Get the DOM document to generate elements. + * + * Returns: + * The currently used DOM document. + */ + xmlGenerator() { + if (!Strophe._xmlGenerator) { + Strophe._xmlGenerator = shims["c" /* getDummyXMLDOMDocument */](); + } + + return Strophe._xmlGenerator; + }, + + /** Function: xmlElement + * Create an XML DOM element. + * + * This function creates an XML DOM element correctly across all + * implementations. Note that these are not HTML DOM elements, which + * aren't appropriate for XMPP stanzas. + * + * Parameters: + * (String) name - The name for the element. + * (Array|Object) attrs - An optional array or object containing + * key/value pairs to use as element attributes. The object should + * be in the format {'key': 'value'} or {key: 'value'}. The array + * should have the format [['key1', 'value1'], ['key2', 'value2']]. + * (String) text - The text child data for the element. + * + * Returns: + * A new XML DOM element. + */ + xmlElement(name) { + if (!name) { + return null; + } + + const node = Strophe.xmlGenerator().createElement(name); // FIXME: this should throw errors if args are the wrong type or + // there are more than two optional args + + for (let a = 1; a < arguments.length; a++) { + const arg = arguments[a]; + + if (!arg) { + continue; + } + + if (typeof arg === "string" || typeof arg === "number") { + node.appendChild(Strophe.xmlTextNode(arg)); + } else if (typeof arg === "object" && typeof arg.sort === "function") { + for (let i = 0; i < arg.length; i++) { + const attr = arg[i]; + + if (typeof attr === "object" && typeof attr.sort === "function" && attr[1] !== undefined && attr[1] !== null) { + node.setAttribute(attr[0], attr[1]); + } + } + } else if (typeof arg === "object") { + for (const k in arg) { + if (Object.prototype.hasOwnProperty.call(arg, k) && arg[k] !== undefined && arg[k] !== null) { + node.setAttribute(k, arg[k]); + } + } + } + } + + return node; + }, + + /* Function: xmlescape + * Excapes invalid xml characters. + * + * Parameters: + * (String) text - text to escape. + * + * Returns: + * Escaped text. + */ + xmlescape(text) { + text = text.replace(/\&/g, "&"); + text = text.replace(//g, ">"); + text = text.replace(/'/g, "'"); + text = text.replace(/"/g, """); + return text; + }, + + /* Function: xmlunescape + * Unexcapes invalid xml characters. + * + * Parameters: + * (String) text - text to unescape. + * + * Returns: + * Unescaped text. + */ + xmlunescape(text) { + text = text.replace(/\&/g, "&"); + text = text.replace(/</g, "<"); + text = text.replace(/>/g, ">"); + text = text.replace(/'/g, "'"); + text = text.replace(/"/g, "\""); + return text; + }, + + /** Function: xmlTextNode + * Creates an XML DOM text node. + * + * Provides a cross implementation version of document.createTextNode. + * + * Parameters: + * (String) text - The content of the text node. + * + * Returns: + * A new XML DOM text node. + */ + xmlTextNode(text) { + return Strophe.xmlGenerator().createTextNode(text); + }, + + /** Function: xmlHtmlNode + * Creates an XML DOM html node. + * + * Parameters: + * (String) html - The content of the html node. + * + * Returns: + * A new XML DOM text node. + */ + xmlHtmlNode(html) { + let node; //ensure text is escaped + + if (shims["a" /* DOMParser */]) { + const parser = new shims["a" /* DOMParser */](); + node = parser.parseFromString(html, "text/xml"); + } else { + node = new ActiveXObject("Microsoft.XMLDOM"); + node.async = "false"; + node.loadXML(html); + } + + return node; + }, + + /** Function: getText + * Get the concatenation of all text children of an element. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * A String with the concatenated text of all text element children. + */ + getText(elem) { + if (!elem) { + return null; + } + + let str = ""; + + if (elem.childNodes.length === 0 && elem.nodeType === Strophe.ElementType.TEXT) { + str += elem.nodeValue; + } + + for (let i = 0; i < elem.childNodes.length; i++) { + if (elem.childNodes[i].nodeType === Strophe.ElementType.TEXT) { + str += elem.childNodes[i].nodeValue; + } + } + + return Strophe.xmlescape(str); + }, + + /** Function: copyElement + * Copy an XML DOM element. + * + * This function copies a DOM element and all its descendants and returns + * the new copy. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * A new, copied DOM element tree. + */ + copyElement(elem) { + let el; + + if (elem.nodeType === Strophe.ElementType.NORMAL) { + el = Strophe.xmlElement(elem.tagName); + + for (let i = 0; i < elem.attributes.length; i++) { + el.setAttribute(elem.attributes[i].nodeName, elem.attributes[i].value); + } + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.copyElement(elem.childNodes[i])); + } + } else if (elem.nodeType === Strophe.ElementType.TEXT) { + el = Strophe.xmlGenerator().createTextNode(elem.nodeValue); + } + + return el; + }, + + /** Function: createHtml + * Copy an HTML DOM element into an XML DOM. + * + * This function copies a DOM element and all its descendants and returns + * the new copy. + * + * Parameters: + * (HTMLElement) elem - A DOM element. + * + * Returns: + * A new, copied DOM element tree. + */ + createHtml(elem) { + let el; + + if (elem.nodeType === Strophe.ElementType.NORMAL) { + const tag = elem.nodeName.toLowerCase(); // XHTML tags must be lower case. + + if (Strophe.XHTML.validTag(tag)) { + try { + el = Strophe.xmlElement(tag); + + for (let i = 0; i < Strophe.XHTML.attributes[tag].length; i++) { + const attribute = Strophe.XHTML.attributes[tag][i]; + let value = elem.getAttribute(attribute); + + if (typeof value === 'undefined' || value === null || value === '' || value === false || value === 0) { + continue; + } + + if (attribute === 'style' && typeof value === 'object' && typeof value.cssText !== 'undefined') { + value = value.cssText; // we're dealing with IE, need to get CSS out + } // filter out invalid css styles + + + if (attribute === 'style') { + const css = []; + const cssAttrs = value.split(';'); + + for (let j = 0; j < cssAttrs.length; j++) { + const attr = cssAttrs[j].split(':'); + const cssName = attr[0].replace(/^\s*/, "").replace(/\s*$/, "").toLowerCase(); + + if (Strophe.XHTML.validCSS(cssName)) { + const cssValue = attr[1].replace(/^\s*/, "").replace(/\s*$/, ""); + css.push(cssName + ': ' + cssValue); + } + } + + if (css.length > 0) { + value = css.join('; '); + el.setAttribute(attribute, value); + } + } else { + el.setAttribute(attribute, value); + } + } + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.createHtml(elem.childNodes[i])); + } + } catch (e) { + // invalid elements + el = Strophe.xmlTextNode(''); + } + } else { + el = Strophe.xmlGenerator().createDocumentFragment(); + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.createHtml(elem.childNodes[i])); + } + } + } else if (elem.nodeType === Strophe.ElementType.FRAGMENT) { + el = Strophe.xmlGenerator().createDocumentFragment(); + + for (let i = 0; i < elem.childNodes.length; i++) { + el.appendChild(Strophe.createHtml(elem.childNodes[i])); + } + } else if (elem.nodeType === Strophe.ElementType.TEXT) { + el = Strophe.xmlTextNode(elem.nodeValue); + } + + return el; + }, + + /** Function: escapeNode + * Escape the node part (also called local part) of a JID. + * + * Parameters: + * (String) node - A node (or local part). + * + * Returns: + * An escaped node (or local part). + */ + escapeNode(node) { + if (typeof node !== "string") { + return node; + } + + return node.replace(/^\s+|\s+$/g, '').replace(/\\/g, "\\5c").replace(/ /g, "\\20").replace(/\"/g, "\\22").replace(/\&/g, "\\26").replace(/\'/g, "\\27").replace(/\//g, "\\2f").replace(/:/g, "\\3a").replace(//g, "\\3e").replace(/@/g, "\\40"); + }, + + /** Function: unescapeNode + * Unescape a node part (also called local part) of a JID. + * + * Parameters: + * (String) node - A node (or local part). + * + * Returns: + * An unescaped node (or local part). + */ + unescapeNode(node) { + if (typeof node !== "string") { + return node; + } + + return node.replace(/\\20/g, " ").replace(/\\22/g, '"').replace(/\\26/g, "&").replace(/\\27/g, "'").replace(/\\2f/g, "/").replace(/\\3a/g, ":").replace(/\\3c/g, "<").replace(/\\3e/g, ">").replace(/\\40/g, "@").replace(/\\5c/g, "\\"); + }, + + /** Function: getNodeFromJid + * Get the node portion of a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the node. + */ + getNodeFromJid(jid) { + if (jid.indexOf("@") < 0) { + return null; + } + + return jid.split("@")[0]; + }, + + /** Function: getDomainFromJid + * Get the domain portion of a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the domain. + */ + getDomainFromJid(jid) { + const bare = Strophe.getBareJidFromJid(jid); + + if (bare.indexOf("@") < 0) { + return bare; + } else { + const parts = bare.split("@"); + parts.splice(0, 1); + return parts.join('@'); + } + }, + + /** Function: getResourceFromJid + * Get the resource portion of a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the resource. + */ + getResourceFromJid(jid) { + if (!jid) { + return null; + } + + const s = jid.split("/"); + + if (s.length < 2) { + return null; + } + + s.splice(0, 1); + return s.join('/'); + }, + + /** Function: getBareJidFromJid + * Get the bare JID from a JID String. + * + * Parameters: + * (String) jid - A JID. + * + * Returns: + * A String containing the bare JID. + */ + getBareJidFromJid(jid) { + return jid ? jid.split("/")[0] : null; + }, + + /** PrivateFunction: _handleError + * _Private_ function that properly logs an error to the console + */ + _handleError(e) { + if (typeof e.stack !== "undefined") { + Strophe.fatal(e.stack); + } + + if (e.sourceURL) { + Strophe.fatal("error: " + this.handler + " " + e.sourceURL + ":" + e.line + " - " + e.name + ": " + e.message); + } else if (e.fileName) { + Strophe.fatal("error: " + this.handler + " " + e.fileName + ":" + e.lineNumber + " - " + e.name + ": " + e.message); + } else { + Strophe.fatal("error: " + e.message); + } + }, + + /** Function: log + * User overrideable logging function. + * + * This function is called whenever the Strophe library calls any + * of the logging functions. The default implementation of this + * function logs only fatal errors. If client code wishes to handle the logging + * messages, it should override this with + * > Strophe.log = function (level, msg) { + * > (user code here) + * > }; + * + * Please note that data sent and received over the wire is logged + * via Strophe.Connection.rawInput() and Strophe.Connection.rawOutput(). + * + * The different levels and their meanings are + * + * DEBUG - Messages useful for debugging purposes. + * INFO - Informational messages. This is mostly information like + * 'disconnect was called' or 'SASL auth succeeded'. + * WARN - Warnings about potential problems. This is mostly used + * to report transient connection errors like request timeouts. + * ERROR - Some error occurred. + * FATAL - A non-recoverable fatal error occurred. + * + * Parameters: + * (Integer) level - The log level of the log message. This will + * be one of the values in Strophe.LogLevel. + * (String) msg - The log message. + */ + log(level, msg) { + if (level === this.LogLevel.FATAL) { + var _console; + + (_console = console) === null || _console === void 0 ? void 0 : _console.error(msg); + } + }, + + /** Function: debug + * Log a message at the Strophe.LogLevel.DEBUG level. + * + * Parameters: + * (String) msg - The log message. + */ + debug(msg) { + this.log(this.LogLevel.DEBUG, msg); + }, + + /** Function: info + * Log a message at the Strophe.LogLevel.INFO level. + * + * Parameters: + * (String) msg - The log message. + */ + info(msg) { + this.log(this.LogLevel.INFO, msg); + }, + + /** Function: warn + * Log a message at the Strophe.LogLevel.WARN level. + * + * Parameters: + * (String) msg - The log message. + */ + warn(msg) { + this.log(this.LogLevel.WARN, msg); + }, + + /** Function: error + * Log a message at the Strophe.LogLevel.ERROR level. + * + * Parameters: + * (String) msg - The log message. + */ + error(msg) { + this.log(this.LogLevel.ERROR, msg); + }, + + /** Function: fatal + * Log a message at the Strophe.LogLevel.FATAL level. + * + * Parameters: + * (String) msg - The log message. + */ + fatal(msg) { + this.log(this.LogLevel.FATAL, msg); + }, + + /** Function: serialize + * Render a DOM element and all descendants to a String. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * The serialized element tree as a String. + */ + serialize(elem) { + if (!elem) { + return null; + } + + if (typeof elem.tree === "function") { + elem = elem.tree(); + } + + const names = [...Array(elem.attributes.length).keys()].map(i => elem.attributes[i].nodeName); + names.sort(); + let result = names.reduce((a, n) => "".concat(a, " ").concat(n, "=\"").concat(Strophe.xmlescape(elem.attributes.getNamedItem(n).value), "\""), "<".concat(elem.nodeName)); + + if (elem.childNodes.length > 0) { + result += ">"; + + for (let i = 0; i < elem.childNodes.length; i++) { + const child = elem.childNodes[i]; + + switch (child.nodeType) { + case Strophe.ElementType.NORMAL: + // normal element, so recurse + result += Strophe.serialize(child); + break; + + case Strophe.ElementType.TEXT: + // text element to escape values + result += Strophe.xmlescape(child.nodeValue); + break; + + case Strophe.ElementType.CDATA: + // cdata section so don't escape values + result += ""; + } + } + + result += ""; + } else { + result += "/>"; + } + + return result; + }, + + /** PrivateVariable: _requestId + * _Private_ variable that keeps track of the request ids for + * connections. + */ + _requestId: 0, + + /** PrivateVariable: Strophe.connectionPlugins + * _Private_ variable Used to store plugin names that need + * initialization on Strophe.Connection construction. + */ + _connectionPlugins: {}, + + /** Function: addConnectionPlugin + * Extends the Strophe.Connection object with the given plugin. + * + * Parameters: + * (String) name - The name of the extension. + * (Object) ptype - The plugin's prototype. + */ + addConnectionPlugin(name, ptype) { + Strophe._connectionPlugins[name] = ptype; + } + +}; +/** Class: Strophe.Builder + * XML DOM builder. + * + * This object provides an interface similar to JQuery but for building + * DOM elements easily and rapidly. All the functions except for toString() + * and tree() return the object, so calls can be chained. Here's an + * example using the $iq() builder helper. + * > $iq({to: 'you', from: 'me', type: 'get', id: '1'}) + * > .c('query', {xmlns: 'strophe:example'}) + * > .c('example') + * > .toString() + * + * The above generates this XML fragment + * > + * > + * > + * > + * > + * The corresponding DOM manipulations to get a similar fragment would be + * a lot more tedious and probably involve several helper variables. + * + * Since adding children makes new operations operate on the child, up() + * is provided to traverse up the tree. To add two children, do + * > builder.c('child1', ...).up().c('child2', ...) + * The next operation on the Builder will be relative to the second child. + */ + +/** Constructor: Strophe.Builder + * Create a Strophe.Builder object. + * + * The attributes should be passed in object notation. For example + * > let b = new Builder('message', {to: 'you', from: 'me'}); + * or + * > let b = new Builder('messsage', {'xml:lang': 'en'}); + * + * Parameters: + * (String) name - The name of the root element. + * (Object) attrs - The attributes for the root element in object notation. + * + * Returns: + * A new Strophe.Builder. + */ + +Strophe.Builder = class Builder { + constructor(name, attrs) { + // Set correct namespace for jabber:client elements + if (name === "presence" || name === "message" || name === "iq") { + if (attrs && !attrs.xmlns) { + attrs.xmlns = Strophe.NS.CLIENT; + } else if (!attrs) { + attrs = { + xmlns: Strophe.NS.CLIENT + }; + } + } // Holds the tree being built. + + + this.nodeTree = Strophe.xmlElement(name, attrs); // Points to the current operation node. + + this.node = this.nodeTree; + } + /** Function: tree + * Return the DOM tree. + * + * This function returns the current DOM tree as an element object. This + * is suitable for passing to functions like Strophe.Connection.send(). + * + * Returns: + * The DOM tree as a element object. + */ + + + tree() { + return this.nodeTree; + } + /** Function: toString + * Serialize the DOM tree to a String. + * + * This function returns a string serialization of the current DOM + * tree. It is often used internally to pass data to a + * Strophe.Request object. + * + * Returns: + * The serialized DOM tree in a String. + */ + + + toString() { + return Strophe.serialize(this.nodeTree); + } + /** Function: up + * Make the current parent element the new current element. + * + * This function is often used after c() to traverse back up the tree. + * For example, to add two children to the same element + * > builder.c('child1', {}).up().c('child2', {}); + * + * Returns: + * The Stophe.Builder object. + */ + + + up() { + this.node = this.node.parentNode; + return this; + } + /** Function: root + * Make the root element the new current element. + * + * When at a deeply nested element in the tree, this function can be used + * to jump back to the root of the tree, instead of having to repeatedly + * call up(). + * + * Returns: + * The Stophe.Builder object. + */ + + + root() { + this.node = this.nodeTree; + return this; + } + /** Function: attrs + * Add or modify attributes of the current element. + * + * The attributes should be passed in object notation. This function + * does not move the current element pointer. + * + * Parameters: + * (Object) moreattrs - The attributes to add/modify in object notation. + * + * Returns: + * The Strophe.Builder object. + */ + + + attrs(moreattrs) { + for (const k in moreattrs) { + if (Object.prototype.hasOwnProperty.call(moreattrs, k)) { + if (moreattrs[k] === undefined) { + this.node.removeAttribute(k); + } else { + this.node.setAttribute(k, moreattrs[k]); + } + } + } + + return this; + } + /** Function: c + * Add a child to the current element and make it the new current + * element. + * + * This function moves the current element pointer to the child, + * unless text is provided. If you need to add another child, it + * is necessary to use up() to go back to the parent in the tree. + * + * Parameters: + * (String) name - The name of the child. + * (Object) attrs - The attributes of the child in object notation. + * (String) text - The text to add to the child. + * + * Returns: + * The Strophe.Builder object. + */ + + + c(name, attrs, text) { + const child = Strophe.xmlElement(name, attrs, text); + this.node.appendChild(child); + + if (typeof text !== "string" && typeof text !== "number") { + this.node = child; + } + + return this; + } + /** Function: cnode + * Add a child to the current element and make it the new current + * element. + * + * This function is the same as c() except that instead of using a + * name and an attributes object to create the child it uses an + * existing DOM element object. + * + * Parameters: + * (XMLElement) elem - A DOM element. + * + * Returns: + * The Strophe.Builder object. + */ + + + cnode(elem) { + let impNode; + const xmlGen = Strophe.xmlGenerator(); + + try { + impNode = xmlGen.importNode !== undefined; + } catch (e) { + impNode = false; + } + + const newElem = impNode ? xmlGen.importNode(elem, true) : Strophe.copyElement(elem); + this.node.appendChild(newElem); + this.node = newElem; + return this; + } + /** Function: t + * Add a child text element. + * + * This *does not* make the child the new current element since there + * are no children of text elements. + * + * Parameters: + * (String) text - The text data to append to the current element. + * + * Returns: + * The Strophe.Builder object. + */ + + + t(text) { + const child = Strophe.xmlTextNode(text); + this.node.appendChild(child); + return this; + } + /** Function: h + * Replace current element contents with the HTML passed in. + * + * This *does not* make the child the new current element + * + * Parameters: + * (String) html - The html to insert as contents of current element. + * + * Returns: + * The Strophe.Builder object. + */ + + + h(html) { + const fragment = Strophe.xmlGenerator().createElement('body'); // force the browser to try and fix any invalid HTML tags + + fragment.innerHTML = html; // copy cleaned html into an xml dom + + const xhtml = Strophe.createHtml(fragment); + + while (xhtml.childNodes.length > 0) { + this.node.appendChild(xhtml.childNodes[0]); + } + + return this; + } + +}; +/** PrivateClass: Strophe.Handler + * _Private_ helper class for managing stanza handlers. + * + * A Strophe.Handler encapsulates a user provided callback function to be + * executed when matching stanzas are received by the connection. + * Handlers can be either one-off or persistant depending on their + * return value. Returning true will cause a Handler to remain active, and + * returning false will remove the Handler. + * + * Users will not use Strophe.Handler objects directly, but instead they + * will use Strophe.Connection.addHandler() and + * Strophe.Connection.deleteHandler(). + */ + +/** PrivateConstructor: Strophe.Handler + * Create and initialize a new Strophe.Handler. + * + * Parameters: + * (Function) handler - A function to be executed when the handler is run. + * (String) ns - The namespace to match. + * (String) name - The element name to match. + * (String) type - The element type to match. + * (String) id - The element id attribute to match. + * (String) from - The element from attribute to match. + * (Object) options - Handler options + * + * Returns: + * A new Strophe.Handler object. + */ + +Strophe.Handler = function (handler, ns, name, type, id, from, options) { + this.handler = handler; + this.ns = ns; + this.name = name; + this.type = type; + this.id = id; + this.options = options || { + 'matchBareFromJid': false, + 'ignoreNamespaceFragment': false + }; // BBB: Maintain backward compatibility with old `matchBare` option + + if (this.options.matchBare) { + Strophe.warn('The "matchBare" option is deprecated, use "matchBareFromJid" instead.'); + this.options.matchBareFromJid = this.options.matchBare; + delete this.options.matchBare; + } + + if (this.options.matchBareFromJid) { + this.from = from ? Strophe.getBareJidFromJid(from) : null; + } else { + this.from = from; + } // whether the handler is a user handler or a system handler + + + this.user = true; +}; + +Strophe.Handler.prototype = { + /** PrivateFunction: getNamespace + * Returns the XML namespace attribute on an element. + * If `ignoreNamespaceFragment` was passed in for this handler, then the + * URL fragment will be stripped. + * + * Parameters: + * (XMLElement) elem - The XML element with the namespace. + * + * Returns: + * The namespace, with optionally the fragment stripped. + */ + getNamespace(elem) { + let elNamespace = elem.getAttribute("xmlns"); + + if (elNamespace && this.options.ignoreNamespaceFragment) { + elNamespace = elNamespace.split('#')[0]; + } + + return elNamespace; + }, + + /** PrivateFunction: namespaceMatch + * Tests if a stanza matches the namespace set for this Strophe.Handler. + * + * Parameters: + * (XMLElement) elem - The XML element to test. + * + * Returns: + * true if the stanza matches and false otherwise. + */ + namespaceMatch(elem) { + let nsMatch = false; + + if (!this.ns) { + return true; + } else { + Strophe.forEachChild(elem, null, elem => { + if (this.getNamespace(elem) === this.ns) { + nsMatch = true; + } + }); + return nsMatch || this.getNamespace(elem) === this.ns; + } + }, + + /** PrivateFunction: isMatch + * Tests if a stanza matches the Strophe.Handler. + * + * Parameters: + * (XMLElement) elem - The XML element to test. + * + * Returns: + * true if the stanza matches and false otherwise. + */ + isMatch(elem) { + let from = elem.getAttribute('from'); + + if (this.options.matchBareFromJid) { + from = Strophe.getBareJidFromJid(from); + } + + const elem_type = elem.getAttribute("type"); + + if (this.namespaceMatch(elem) && (!this.name || Strophe.isTagEqual(elem, this.name)) && (!this.type || (Array.isArray(this.type) ? this.type.indexOf(elem_type) !== -1 : elem_type === this.type)) && (!this.id || elem.getAttribute("id") === this.id) && (!this.from || from === this.from)) { + return true; + } + + return false; + }, + + /** PrivateFunction: run + * Run the callback on a matching stanza. + * + * Parameters: + * (XMLElement) elem - The DOM element that triggered the + * Strophe.Handler. + * + * Returns: + * A boolean indicating if the handler should remain active. + */ + run(elem) { + let result = null; + + try { + result = this.handler(elem); + } catch (e) { + Strophe._handleError(e); + + throw e; + } + + return result; + }, + + /** PrivateFunction: toString + * Get a String representation of the Strophe.Handler object. + * + * Returns: + * A String. + */ + toString() { + return "{Handler: " + this.handler + "(" + this.name + "," + this.id + "," + this.ns + ")}"; + } + +}; +/** PrivateClass: Strophe.TimedHandler + * _Private_ helper class for managing timed handlers. + * + * A Strophe.TimedHandler encapsulates a user provided callback that + * should be called after a certain period of time or at regular + * intervals. The return value of the callback determines whether the + * Strophe.TimedHandler will continue to fire. + * + * Users will not use Strophe.TimedHandler objects directly, but instead + * they will use Strophe.Connection.addTimedHandler() and + * Strophe.Connection.deleteTimedHandler(). + */ + +Strophe.TimedHandler = class TimedHandler { + /** PrivateConstructor: Strophe.TimedHandler + * Create and initialize a new Strophe.TimedHandler object. + * + * Parameters: + * (Integer) period - The number of milliseconds to wait before the + * handler is called. + * (Function) handler - The callback to run when the handler fires. This + * function should take no arguments. + * + * Returns: + * A new Strophe.TimedHandler object. + */ + constructor(period, handler) { + this.period = period; + this.handler = handler; + this.lastCalled = new Date().getTime(); + this.user = true; + } + /** PrivateFunction: run + * Run the callback for the Strophe.TimedHandler. + * + * Returns: + * true if the Strophe.TimedHandler should be called again, and false + * otherwise. + */ + + + run() { + this.lastCalled = new Date().getTime(); + return this.handler(); + } + /** PrivateFunction: reset + * Reset the last called time for the Strophe.TimedHandler. + */ + + + reset() { + this.lastCalled = new Date().getTime(); + } + /** PrivateFunction: toString + * Get a string representation of the Strophe.TimedHandler object. + * + * Returns: + * The string representation. + */ + + + toString() { + return "{TimedHandler: " + this.handler + "(" + this.period + ")}"; + } + +}; +/** Class: Strophe.Connection + * XMPP Connection manager. + * + * This class is the main part of Strophe. It manages a BOSH or websocket + * connection to an XMPP server and dispatches events to the user callbacks + * as data arrives. It supports SASL PLAIN, SASL SCRAM-SHA-1 + * and legacy authentication. + * + * After creating a Strophe.Connection object, the user will typically + * call connect() with a user supplied callback to handle connection level + * events like authentication failure, disconnection, or connection + * complete. + * + * The user will also have several event handlers defined by using + * addHandler() and addTimedHandler(). These will allow the user code to + * respond to interesting stanzas or do something periodically with the + * connection. These handlers will be active once authentication is + * finished. + * + * To send data to the connection, use send(). + */ + +/** Constructor: Strophe.Connection + * Create and initialize a Strophe.Connection object. + * + * The transport-protocol for this connection will be chosen automatically + * based on the given service parameter. URLs starting with "ws://" or + * "wss://" will use WebSockets, URLs starting with "http://", "https://" + * or without a protocol will use BOSH. + * + * To make Strophe connect to the current host you can leave out the protocol + * and host part and just pass the path, e.g. + * + * > let conn = new Strophe.Connection("/http-bind/"); + * + * Options common to both Websocket and BOSH: + * ------------------------------------------ + * + * cookies: + * + * The *cookies* option allows you to pass in cookies to be added to the + * document. These cookies will then be included in the BOSH XMLHttpRequest + * or in the websocket connection. + * + * The passed in value must be a map of cookie names and string values. + * + * > { "myCookie": { + * > "value": "1234", + * > "domain": ".example.org", + * > "path": "/", + * > "expires": expirationDate + * > } + * > } + * + * Note that cookies can't be set in this way for other domains (i.e. cross-domain). + * Those cookies need to be set under those domains, for example they can be + * set server-side by making a XHR call to that domain to ask it to set any + * necessary cookies. + * + * mechanisms: + * + * The *mechanisms* option allows you to specify the SASL mechanisms that this + * instance of Strophe.Connection (and therefore your XMPP client) will + * support. + * + * The value must be an array of objects with Strophe.SASLMechanism + * prototypes. + * + * If nothing is specified, then the following mechanisms (and their + * priorities) are registered: + * + * SCRAM-SHA-1 - 60 + * PLAIN - 50 + * OAUTHBEARER - 40 + * X-OAUTH2 - 30 + * ANONYMOUS - 20 + * EXTERNAL - 10 + * + * explicitResourceBinding: + * + * If `explicitResourceBinding` is set to a truthy value, then the XMPP client + * needs to explicitly call `Strophe.Connection.prototype.bind` once the XMPP + * server has advertised the "urn:ietf:params:xml:ns:xmpp-bind" feature. + * + * Making this step explicit allows client authors to first finish other + * stream related tasks, such as setting up an XEP-0198 Stream Management + * session, before binding the JID resource for this session. + * + * WebSocket options: + * ------------------ + * + * protocol: + * + * If you want to connect to the current host with a WebSocket connection you + * can tell Strophe to use WebSockets through a "protocol" attribute in the + * optional options parameter. Valid values are "ws" for WebSocket and "wss" + * for Secure WebSocket. + * So to connect to "wss://CURRENT_HOSTNAME/xmpp-websocket" you would call + * + * > let conn = new Strophe.Connection("/xmpp-websocket/", {protocol: "wss"}); + * + * Note that relative URLs _NOT_ starting with a "/" will also include the path + * of the current site. + * + * Also because downgrading security is not permitted by browsers, when using + * relative URLs both BOSH and WebSocket connections will use their secure + * variants if the current connection to the site is also secure (https). + * + * worker: + * + * Set this option to URL from where the shared worker script should be loaded. + * + * To run the websocket connection inside a shared worker. + * This allows you to share a single websocket-based connection between + * multiple Strophe.Connection instances, for example one per browser tab. + * + * The script to use is the one in `src/shared-connection-worker.js`. + * + * BOSH options: + * ------------- + * + * By adding "sync" to the options, you can control if requests will + * be made synchronously or not. The default behaviour is asynchronous. + * If you want to make requests synchronous, make "sync" evaluate to true. + * > let conn = new Strophe.Connection("/http-bind/", {sync: true}); + * + * You can also toggle this on an already established connection. + * > conn.options.sync = true; + * + * The *customHeaders* option can be used to provide custom HTTP headers to be + * included in the XMLHttpRequests made. + * + * The *keepalive* option can be used to instruct Strophe to maintain the + * current BOSH session across interruptions such as webpage reloads. + * + * It will do this by caching the sessions tokens in sessionStorage, and when + * "restore" is called it will check whether there are cached tokens with + * which it can resume an existing session. + * + * The *withCredentials* option should receive a Boolean value and is used to + * indicate wether cookies should be included in ajax requests (by default + * they're not). + * Set this value to true if you are connecting to a BOSH service + * and for some reason need to send cookies to it. + * In order for this to work cross-domain, the server must also enable + * credentials by setting the Access-Control-Allow-Credentials response header + * to "true". For most usecases however this setting should be false (which + * is the default). + * Additionally, when using Access-Control-Allow-Credentials, the + * Access-Control-Allow-Origin header can't be set to the wildcard "*", but + * instead must be restricted to actual domains. + * + * The *contentType* option can be set to change the default Content-Type + * of "text/xml; charset=utf-8", which can be useful to reduce the amount of + * CORS preflight requests that are sent to the server. + * + * Parameters: + * (String) service - The BOSH or WebSocket service URL. + * (Object) options - A hash of configuration options + * + * Returns: + * A new Strophe.Connection object. + */ + +Strophe.Connection = class Connection { + constructor(service, options) { + // The service URL + this.service = service; // Configuration options + + this.options = options || {}; + this.setProtocol(); + /* The connected JID. */ + + this.jid = ""; + /* the JIDs domain */ + + this.domain = null; + /* stream:features */ + + this.features = null; // SASL + + this._sasl_data = {}; + this.do_bind = false; + this.do_session = false; + this.mechanisms = {}; // handler lists + + this.timedHandlers = []; + this.handlers = []; + this.removeTimeds = []; + this.removeHandlers = []; + this.addTimeds = []; + this.addHandlers = []; + this.protocolErrorHandlers = { + 'HTTP': {}, + 'websocket': {} + }; + this._idleTimeout = null; + this._disconnectTimeout = null; + this.authenticated = false; + this.connected = false; + this.disconnecting = false; + this.do_authentication = true; + this.paused = false; + this.restored = false; + this._data = []; + this._uniqueId = 0; + this._sasl_success_handler = null; + this._sasl_failure_handler = null; + this._sasl_challenge_handler = null; // Max retries before disconnecting + + this.maxRetries = 5; // Call onIdle callback every 1/10th of a second + + this._idleTimeout = setTimeout(() => this._onIdle(), 100); + utils.addCookies(this.options.cookies); + this.registerSASLMechanisms(this.options.mechanisms); // initialize plugins + + for (const k in Strophe._connectionPlugins) { + if (Object.prototype.hasOwnProperty.call(Strophe._connectionPlugins, k)) { + const F = function F() {}; + + F.prototype = Strophe._connectionPlugins[k]; + this[k] = new F(); + this[k].init(this); + } + } + } + /** Function: setProtocol + * Select protocal based on this.options or this.service + */ + + + setProtocol() { + const proto = this.options.protocol || ""; + + if (this.options.worker) { + this._proto = new Strophe.WorkerWebsocket(this); + } else if (this.service.indexOf("ws:") === 0 || this.service.indexOf("wss:") === 0 || proto.indexOf("ws") === 0) { + this._proto = new Strophe.Websocket(this); + } else { + this._proto = new Strophe.Bosh(this); + } + } + /** Function: reset + * Reset the connection. + * + * This function should be called after a connection is disconnected + * before that connection is reused. + */ + + + reset() { + this._proto._reset(); // SASL + + + this.do_session = false; + this.do_bind = false; // handler lists + + this.timedHandlers = []; + this.handlers = []; + this.removeTimeds = []; + this.removeHandlers = []; + this.addTimeds = []; + this.addHandlers = []; + this.authenticated = false; + this.connected = false; + this.disconnecting = false; + this.restored = false; + this._data = []; + this._requests = []; + this._uniqueId = 0; + } + /** Function: pause + * Pause the request manager. + * + * This will prevent Strophe from sending any more requests to the + * server. This is very useful for temporarily pausing + * BOSH-Connections while a lot of send() calls are happening quickly. + * This causes Strophe to send the data in a single request, saving + * many request trips. + */ + + + pause() { + this.paused = true; + } + /** Function: resume + * Resume the request manager. + * + * This resumes after pause() has been called. + */ + + + resume() { + this.paused = false; + } + /** Function: getUniqueId + * Generate a unique ID for use in elements. + * + * All stanzas are required to have unique id attributes. This + * function makes creating these easy. Each connection instance has + * a counter which starts from zero, and the value of this counter + * plus a colon followed by the suffix becomes the unique id. If no + * suffix is supplied, the counter is used as the unique id. + * + * Suffixes are used to make debugging easier when reading the stream + * data, and their use is recommended. The counter resets to 0 for + * every new connection for the same reason. For connections to the + * same server that authenticate the same way, all the ids should be + * the same, which makes it easy to see changes. This is useful for + * automated testing as well. + * + * Parameters: + * (String) suffix - A optional suffix to append to the id. + * + * Returns: + * A unique string to be used for the id attribute. + */ + + + getUniqueId(suffix) { + // eslint-disable-line class-methods-use-this + const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + const r = Math.random() * 16 | 0, + v = c === 'x' ? r : r & 0x3 | 0x8; + return v.toString(16); + }); + + if (typeof suffix === "string" || typeof suffix === "number") { + return uuid + ":" + suffix; + } else { + return uuid + ""; + } + } + /** Function: addProtocolErrorHandler + * Register a handler function for when a protocol (websocker or HTTP) + * error occurs. + * + * NOTE: Currently only HTTP errors for BOSH requests are handled. + * Patches that handle websocket errors would be very welcome. + * + * Parameters: + * (String) protocol - 'HTTP' or 'websocket' + * (Integer) status_code - Error status code (e.g 500, 400 or 404) + * (Function) callback - Function that will fire on Http error + * + * Example: + * function onError(err_code){ + * //do stuff + * } + * + * let conn = Strophe.connect('http://example.com/http-bind'); + * conn.addProtocolErrorHandler('HTTP', 500, onError); + * // Triggers HTTP 500 error and onError handler will be called + * conn.connect('user_jid@incorrect_jabber_host', 'secret', onConnect); + */ + + + addProtocolErrorHandler(protocol, status_code, callback) { + this.protocolErrorHandlers[protocol][status_code] = callback; + } + /** Function: connect + * Starts the connection process. + * + * As the connection process proceeds, the user supplied callback will + * be triggered multiple times with status updates. The callback + * should take two arguments - the status code and the error condition. + * + * The status code will be one of the values in the Strophe.Status + * constants. The error condition will be one of the conditions + * defined in RFC 3920 or the condition 'strophe-parsererror'. + * + * The Parameters _wait_, _hold_ and _route_ are optional and only relevant + * for BOSH connections. Please see XEP 124 for a more detailed explanation + * of the optional parameters. + * + * Parameters: + * (String) jid - The user's JID. This may be a bare JID, + * or a full JID. If a node is not supplied, SASL OAUTHBEARER or + * SASL ANONYMOUS authentication will be attempted (OAUTHBEARER will + * process the provided password value as an access token). + * (String) pass - The user's password. + * (Function) callback - The connect callback function. + * (Integer) wait - The optional HTTPBIND wait value. This is the + * time the server will wait before returning an empty result for + * a request. The default setting of 60 seconds is recommended. + * (Integer) hold - The optional HTTPBIND hold value. This is the + * number of connections the server will hold at one time. This + * should almost always be set to 1 (the default). + * (String) route - The optional route value. + * (String) authcid - The optional alternative authentication identity + * (username) if intending to impersonate another user. + * When using the SASL-EXTERNAL authentication mechanism, for example + * with client certificates, then the authcid value is used to + * determine whether an authorization JID (authzid) should be sent to + * the server. The authzid should NOT be sent to the server if the + * authzid and authcid are the same. So to prevent it from being sent + * (for example when the JID is already contained in the client + * certificate), set authcid to that same JID. See XEP-178 for more + * details. + */ + + + connect(jid, pass, callback, wait, hold, route, authcid) { + this.jid = jid; + /** Variable: authzid + * Authorization identity. + */ + + this.authzid = Strophe.getBareJidFromJid(this.jid); + /** Variable: authcid + * Authentication identity (User name). + */ + + this.authcid = authcid || Strophe.getNodeFromJid(this.jid); + /** Variable: pass + * Authentication identity (User password). + */ + + this.pass = pass; + this.connect_callback = callback; + this.disconnecting = false; + this.connected = false; + this.authenticated = false; + this.restored = false; // parse jid for domain + + this.domain = Strophe.getDomainFromJid(this.jid); + + this._changeConnectStatus(Strophe.Status.CONNECTING, null); + + this._proto._connect(wait, hold, route); + } + /** Function: attach + * Attach to an already created and authenticated BOSH session. + * + * This function is provided to allow Strophe to attach to BOSH + * sessions which have been created externally, perhaps by a Web + * application. This is often used to support auto-login type features + * without putting user credentials into the page. + * + * Parameters: + * (String) jid - The full JID that is bound by the session. + * (String) sid - The SID of the BOSH session. + * (String) rid - The current RID of the BOSH session. This RID + * will be used by the next request. + * (Function) callback The connect callback function. + * (Integer) wait - The optional HTTPBIND wait value. This is the + * time the server will wait before returning an empty result for + * a request. The default setting of 60 seconds is recommended. + * Other settings will require tweaks to the Strophe.TIMEOUT value. + * (Integer) hold - The optional HTTPBIND hold value. This is the + * number of connections the server will hold at one time. This + * should almost always be set to 1 (the default). + * (Integer) wind - The optional HTTBIND window value. This is the + * allowed range of request ids that are valid. The default is 5. + */ + + + attach(jid, sid, rid, callback, wait, hold, wind) { + if (this._proto._attach) { + return this._proto._attach(jid, sid, rid, callback, wait, hold, wind); + } else { + const error = new Error('The "attach" method is not available for your connection protocol'); + error.name = 'StropheSessionError'; + throw error; + } + } + /** Function: restore + * Attempt to restore a cached BOSH session. + * + * This function is only useful in conjunction with providing the + * "keepalive":true option when instantiating a new Strophe.Connection. + * + * When "keepalive" is set to true, Strophe will cache the BOSH tokens + * RID (Request ID) and SID (Session ID) and then when this function is + * called, it will attempt to restore the session from those cached + * tokens. + * + * This function must therefore be called instead of connect or attach. + * + * For an example on how to use it, please see examples/restore.js + * + * Parameters: + * (String) jid - The user's JID. This may be a bare JID or a full JID. + * (Function) callback - The connect callback function. + * (Integer) wait - The optional HTTPBIND wait value. This is the + * time the server will wait before returning an empty result for + * a request. The default setting of 60 seconds is recommended. + * (Integer) hold - The optional HTTPBIND hold value. This is the + * number of connections the server will hold at one time. This + * should almost always be set to 1 (the default). + * (Integer) wind - The optional HTTBIND window value. This is the + * allowed range of request ids that are valid. The default is 5. + */ + + + restore(jid, callback, wait, hold, wind) { + if (this._sessionCachingSupported()) { + this._proto._restore(jid, callback, wait, hold, wind); + } else { + const error = new Error('The "restore" method can only be used with a BOSH connection.'); + error.name = 'StropheSessionError'; + throw error; + } + } + /** PrivateFunction: _sessionCachingSupported + * Checks whether sessionStorage and JSON are supported and whether we're + * using BOSH. + */ + + + _sessionCachingSupported() { + if (this._proto instanceof Strophe.Bosh) { + if (!JSON) { + return false; + } + + try { + sessionStorage.setItem('_strophe_', '_strophe_'); + sessionStorage.removeItem('_strophe_'); + } catch (e) { + return false; + } + + return true; + } + + return false; + } + /** Function: xmlInput + * User overrideable function that receives XML data coming into the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.xmlInput = function (elem) { + * > (user code) + * > }; + * + * Due to limitations of current Browsers' XML-Parsers the opening and closing + * tag for WebSocket-Connoctions will be passed as selfclosing here. + * + * BOSH-Connections will have all stanzas wrapped in a tag. See + * if you want to strip this tag. + * + * Parameters: + * (XMLElement) elem - The XML data received by the connection. + */ + + + xmlInput(elem) { + // eslint-disable-line + return; + } + /** Function: xmlOutput + * User overrideable function that receives XML data sent to the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.xmlOutput = function (elem) { + * > (user code) + * > }; + * + * Due to limitations of current Browsers' XML-Parsers the opening and closing + * tag for WebSocket-Connoctions will be passed as selfclosing here. + * + * BOSH-Connections will have all stanzas wrapped in a tag. See + * if you want to strip this tag. + * + * Parameters: + * (XMLElement) elem - The XMLdata sent by the connection. + */ + + + xmlOutput(elem) { + // eslint-disable-line + return; + } + /** Function: rawInput + * User overrideable function that receives raw data coming into the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.rawInput = function (data) { + * > (user code) + * > }; + * + * Parameters: + * (String) data - The data received by the connection. + */ + + + rawInput(data) { + // eslint-disable-line + return; + } + /** Function: rawOutput + * User overrideable function that receives raw data sent to the + * connection. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.rawOutput = function (data) { + * > (user code) + * > }; + * + * Parameters: + * (String) data - The data sent by the connection. + */ + + + rawOutput(data) { + // eslint-disable-line + return; + } + /** Function: nextValidRid + * User overrideable function that receives the new valid rid. + * + * The default function does nothing. User code can override this with + * > Strophe.Connection.nextValidRid = function (rid) { + * > (user code) + * > }; + * + * Parameters: + * (Number) rid - The next valid rid + */ + + + nextValidRid(rid) { + // eslint-disable-line + return; + } + /** Function: send + * Send a stanza. + * + * This function is called to push data onto the send queue to + * go out over the wire. Whenever a request is sent to the BOSH + * server, all pending data is sent and the queue is flushed. + * + * Parameters: + * (XMLElement | + * [XMLElement] | + * Strophe.Builder) elem - The stanza to send. + */ + + + send(elem) { + if (elem === null) { + return; + } + + if (typeof elem.sort === "function") { + for (let i = 0; i < elem.length; i++) { + this._queueData(elem[i]); + } + } else if (typeof elem.tree === "function") { + this._queueData(elem.tree()); + } else { + this._queueData(elem); + } + + this._proto._send(); + } + /** Function: flush + * Immediately send any pending outgoing data. + * + * Normally send() queues outgoing data until the next idle period + * (100ms), which optimizes network use in the common cases when + * several send()s are called in succession. flush() can be used to + * immediately send all pending data. + */ + + + flush() { + // cancel the pending idle period and run the idle function + // immediately + clearTimeout(this._idleTimeout); + + this._onIdle(); + } + /** Function: sendPresence + * Helper function to send presence stanzas. The main benefit is for + * sending presence stanzas for which you expect a responding presence + * stanza with the same id (for example when leaving a chat room). + * + * Parameters: + * (XMLElement) elem - The stanza to send. + * (Function) callback - The callback function for a successful request. + * (Function) errback - The callback function for a failed or timed + * out request. On timeout, the stanza will be null. + * (Integer) timeout - The time specified in milliseconds for a + * timeout to occur. + * + * Returns: + * The id used to send the presence. + */ + + + sendPresence(elem, callback, errback, timeout) { + let timeoutHandler = null; + + if (typeof elem.tree === "function") { + elem = elem.tree(); + } + + let id = elem.getAttribute('id'); + + if (!id) { + // inject id if not found + id = this.getUniqueId("sendPresence"); + elem.setAttribute("id", id); + } + + if (typeof callback === "function" || typeof errback === "function") { + const handler = this.addHandler(stanza => { + // remove timeout handler if there is one + if (timeoutHandler) { + this.deleteTimedHandler(timeoutHandler); + } + + if (stanza.getAttribute('type') === 'error') { + if (errback) { + errback(stanza); + } + } else if (callback) { + callback(stanza); + } + }, null, 'presence', null, id); // if timeout specified, set up a timeout handler. + + if (timeout) { + timeoutHandler = this.addTimedHandler(timeout, () => { + // get rid of normal handler + this.deleteHandler(handler); // call errback on timeout with null stanza + + if (errback) { + errback(null); + } + + return false; + }); + } + } + + this.send(elem); + return id; + } + /** Function: sendIQ + * Helper function to send IQ stanzas. + * + * Parameters: + * (XMLElement) elem - The stanza to send. + * (Function) callback - The callback function for a successful request. + * (Function) errback - The callback function for a failed or timed + * out request. On timeout, the stanza will be null. + * (Integer) timeout - The time specified in milliseconds for a + * timeout to occur. + * + * Returns: + * The id used to send the IQ. + */ + + + sendIQ(elem, callback, errback, timeout) { + let timeoutHandler = null; + + if (typeof elem.tree === "function") { + elem = elem.tree(); + } + + let id = elem.getAttribute('id'); + + if (!id) { + // inject id if not found + id = this.getUniqueId("sendIQ"); + elem.setAttribute("id", id); + } + + if (typeof callback === "function" || typeof errback === "function") { + const handler = this.addHandler(stanza => { + // remove timeout handler if there is one + if (timeoutHandler) { + this.deleteTimedHandler(timeoutHandler); + } + + const iqtype = stanza.getAttribute('type'); + + if (iqtype === 'result') { + if (callback) { + callback(stanza); + } + } else if (iqtype === 'error') { + if (errback) { + errback(stanza); + } + } else { + const error = new Error("Got bad IQ type of ".concat(iqtype)); + error.name = "StropheError"; + throw error; + } + }, null, 'iq', ['error', 'result'], id); // if timeout specified, set up a timeout handler. + + if (timeout) { + timeoutHandler = this.addTimedHandler(timeout, () => { + // get rid of normal handler + this.deleteHandler(handler); // call errback on timeout with null stanza + + if (errback) { + errback(null); + } + + return false; + }); + } + } + + this.send(elem); + return id; + } + /** PrivateFunction: _queueData + * Queue outgoing data for later sending. Also ensures that the data + * is a DOMElement. + */ + + + _queueData(element) { + if (element === null || !element.tagName || !element.childNodes) { + const error = new Error("Cannot queue non-DOMElement."); + error.name = "StropheError"; + throw error; + } + + this._data.push(element); + } + /** PrivateFunction: _sendRestart + * Send an xmpp:restart stanza. + */ + + + _sendRestart() { + this._data.push("restart"); + + this._proto._sendRestart(); + + this._idleTimeout = setTimeout(() => this._onIdle(), 100); + } + /** Function: addTimedHandler + * Add a timed handler to the connection. + * + * This function adds a timed handler. The provided handler will + * be called every period milliseconds until it returns false, + * the connection is terminated, or the handler is removed. Handlers + * that wish to continue being invoked should return true. + * + * Because of method binding it is necessary to save the result of + * this function if you wish to remove a handler with + * deleteTimedHandler(). + * + * Note that user handlers are not active until authentication is + * successful. + * + * Parameters: + * (Integer) period - The period of the handler. + * (Function) handler - The callback function. + * + * Returns: + * A reference to the handler that can be used to remove it. + */ + + + addTimedHandler(period, handler) { + const thand = new Strophe.TimedHandler(period, handler); + this.addTimeds.push(thand); + return thand; + } + /** Function: deleteTimedHandler + * Delete a timed handler for a connection. + * + * This function removes a timed handler from the connection. The + * handRef parameter is *not* the function passed to addTimedHandler(), + * but is the reference returned from addTimedHandler(). + * + * Parameters: + * (Strophe.TimedHandler) handRef - The handler reference. + */ + + + deleteTimedHandler(handRef) { + // this must be done in the Idle loop so that we don't change + // the handlers during iteration + this.removeTimeds.push(handRef); + } + /** Function: addHandler + * Add a stanza handler for the connection. + * + * This function adds a stanza handler to the connection. The + * handler callback will be called for any stanza that matches + * the parameters. Note that if multiple parameters are supplied, + * they must all match for the handler to be invoked. + * + * The handler will receive the stanza that triggered it as its argument. + * *The handler should return true if it is to be invoked again; + * returning false will remove the handler after it returns.* + * + * As a convenience, the ns parameters applies to the top level element + * and also any of its immediate children. This is primarily to make + * matching /iq/query elements easy. + * + * Options + * ~~~~~~~ + * With the options argument, you can specify boolean flags that affect how + * matches are being done. + * + * Currently two flags exist: + * + * - matchBareFromJid: + * When set to true, the from parameter and the + * from attribute on the stanza will be matched as bare JIDs instead + * of full JIDs. To use this, pass {matchBareFromJid: true} as the + * value of options. The default value for matchBareFromJid is false. + * + * - ignoreNamespaceFragment: + * When set to true, a fragment specified on the stanza's namespace + * URL will be ignored when it's matched with the one configured for + * the handler. + * + * This means that if you register like this: + * > connection.addHandler( + * > handler, + * > 'http://jabber.org/protocol/muc', + * > null, null, null, null, + * > {'ignoreNamespaceFragment': true} + * > ); + * + * Then a stanza with XML namespace of + * 'http://jabber.org/protocol/muc#user' will also be matched. If + * 'ignoreNamespaceFragment' is false, then only stanzas with + * 'http://jabber.org/protocol/muc' will be matched. + * + * Deleting the handler + * ~~~~~~~~~~~~~~~~~~~~ + * The return value should be saved if you wish to remove the handler + * with deleteHandler(). + * + * Parameters: + * (Function) handler - The user callback. + * (String) ns - The namespace to match. + * (String) name - The stanza name to match. + * (String|Array) type - The stanza type (or types if an array) to match. + * (String) id - The stanza id attribute to match. + * (String) from - The stanza from attribute to match. + * (String) options - The handler options + * + * Returns: + * A reference to the handler that can be used to remove it. + */ + + + addHandler(handler, ns, name, type, id, from, options) { + const hand = new Strophe.Handler(handler, ns, name, type, id, from, options); + this.addHandlers.push(hand); + return hand; + } + /** Function: deleteHandler + * Delete a stanza handler for a connection. + * + * This function removes a stanza handler from the connection. The + * handRef parameter is *not* the function passed to addHandler(), + * but is the reference returned from addHandler(). + * + * Parameters: + * (Strophe.Handler) handRef - The handler reference. + */ + + + deleteHandler(handRef) { + // this must be done in the Idle loop so that we don't change + // the handlers during iteration + this.removeHandlers.push(handRef); // If a handler is being deleted while it is being added, + // prevent it from getting added + + const i = this.addHandlers.indexOf(handRef); + + if (i >= 0) { + this.addHandlers.splice(i, 1); + } + } + /** Function: registerSASLMechanisms + * + * Register the SASL mechanisms which will be supported by this instance of + * Strophe.Connection (i.e. which this XMPP client will support). + * + * Parameters: + * (Array) mechanisms - Array of objects with Strophe.SASLMechanism prototypes + * + */ + + + registerSASLMechanisms(mechanisms) { + this.mechanisms = {}; + mechanisms = mechanisms || [Strophe.SASLAnonymous, Strophe.SASLExternal, Strophe.SASLOAuthBearer, Strophe.SASLXOAuth2, Strophe.SASLPlain, Strophe.SASLSHA1]; + mechanisms.forEach(m => this.registerSASLMechanism(m)); + } + /** Function: registerSASLMechanism + * + * Register a single SASL mechanism, to be supported by this client. + * + * Parameters: + * (Object) mechanism - Object with a Strophe.SASLMechanism prototype + * + */ + + + registerSASLMechanism(Mechanism) { + const mechanism = new Mechanism(); + this.mechanisms[mechanism.mechname] = mechanism; + } + /** Function: disconnect + * Start the graceful disconnection process. + * + * This function starts the disconnection process. This process starts + * by sending unavailable presence and sending BOSH body of type + * terminate. A timeout handler makes sure that disconnection happens + * even if the BOSH server does not respond. + * If the Connection object isn't connected, at least tries to abort all pending requests + * so the connection object won't generate successful requests (which were already opened). + * + * The user supplied connection callback will be notified of the + * progress as this process happens. + * + * Parameters: + * (String) reason - The reason the disconnect is occuring. + */ + + + disconnect(reason) { + this._changeConnectStatus(Strophe.Status.DISCONNECTING, reason); + + if (reason) { + Strophe.warn("Disconnect was called because: " + reason); + } else { + Strophe.info("Disconnect was called"); + } + + if (this.connected) { + let pres = false; + this.disconnecting = true; + + if (this.authenticated) { + pres = $pres({ + 'xmlns': Strophe.NS.CLIENT, + 'type': 'unavailable' + }); + } // setup timeout handler + + + this._disconnectTimeout = this._addSysTimedHandler(3000, this._onDisconnectTimeout.bind(this)); + + this._proto._disconnect(pres); + } else { + Strophe.warn("Disconnect was called before Strophe connected to the server"); + + this._proto._abortAllRequests(); + + this._doDisconnect(); + } + } + /** PrivateFunction: _changeConnectStatus + * _Private_ helper function that makes sure plugins and the user's + * callback are notified of connection status changes. + * + * Parameters: + * (Integer) status - the new connection status, one of the values + * in Strophe.Status + * (String) condition - the error condition or null + * (XMLElement) elem - The triggering stanza. + */ + + + _changeConnectStatus(status, condition, elem) { + // notify all plugins listening for status changes + for (const k in Strophe._connectionPlugins) { + if (Object.prototype.hasOwnProperty.call(Strophe._connectionPlugins, k)) { + const plugin = this[k]; + + if (plugin.statusChanged) { + try { + plugin.statusChanged(status, condition); + } catch (err) { + Strophe.error("".concat(k, " plugin caused an exception changing status: ").concat(err)); + } + } + } + } // notify the user's callback + + + if (this.connect_callback) { + try { + this.connect_callback(status, condition, elem); + } catch (e) { + Strophe._handleError(e); + + Strophe.error("User connection callback caused an exception: ".concat(e)); + } + } + } + /** PrivateFunction: _doDisconnect + * _Private_ function to disconnect. + * + * This is the last piece of the disconnection logic. This resets the + * connection and alerts the user's connection callback. + */ + + + _doDisconnect(condition) { + if (typeof this._idleTimeout === "number") { + clearTimeout(this._idleTimeout); + } // Cancel Disconnect Timeout + + + if (this._disconnectTimeout !== null) { + this.deleteTimedHandler(this._disconnectTimeout); + this._disconnectTimeout = null; + } + + Strophe.debug("_doDisconnect was called"); + + this._proto._doDisconnect(); + + this.authenticated = false; + this.disconnecting = false; + this.restored = false; // delete handlers + + this.handlers = []; + this.timedHandlers = []; + this.removeTimeds = []; + this.removeHandlers = []; + this.addTimeds = []; + this.addHandlers = []; // tell the parent we disconnected + + this._changeConnectStatus(Strophe.Status.DISCONNECTED, condition); + + this.connected = false; + } + /** PrivateFunction: _dataRecv + * _Private_ handler to processes incoming data from the the connection. + * + * Except for _connect_cb handling the initial connection request, + * this function handles the incoming data for all requests. This + * function also fires stanza handlers that match each incoming + * stanza. + * + * Parameters: + * (Strophe.Request) req - The request that has data ready. + * (string) req - The stanza a raw string (optiona). + */ + + + _dataRecv(req, raw) { + const elem = this._proto._reqToData(req); + + if (elem === null) { + return; + } + + if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) { + if (elem.nodeName === this._proto.strip && elem.childNodes.length) { + this.xmlInput(elem.childNodes[0]); + } else { + this.xmlInput(elem); + } + } + + if (this.rawInput !== Strophe.Connection.prototype.rawInput) { + if (raw) { + this.rawInput(raw); + } else { + this.rawInput(Strophe.serialize(elem)); + } + } // remove handlers scheduled for deletion + + + while (this.removeHandlers.length > 0) { + const hand = this.removeHandlers.pop(); + const i = this.handlers.indexOf(hand); + + if (i >= 0) { + this.handlers.splice(i, 1); + } + } // add handlers scheduled for addition + + + while (this.addHandlers.length > 0) { + this.handlers.push(this.addHandlers.pop()); + } // handle graceful disconnect + + + if (this.disconnecting && this._proto._emptyQueue()) { + this._doDisconnect(); + + return; + } + + const type = elem.getAttribute("type"); + + if (type !== null && type === "terminate") { + // Don't process stanzas that come in after disconnect + if (this.disconnecting) { + return; + } // an error occurred + + + let cond = elem.getAttribute("condition"); + const conflict = elem.getElementsByTagName("conflict"); + + if (cond !== null) { + if (cond === "remote-stream-error" && conflict.length > 0) { + cond = "conflict"; + } + + this._changeConnectStatus(Strophe.Status.CONNFAIL, cond); + } else { + this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.UNKOWN_REASON); + } + + this._doDisconnect(cond); + + return; + } // send each incoming stanza through the handler chain + + + Strophe.forEachChild(elem, null, child => { + // process handlers + const newList = this.handlers; + this.handlers = []; + + for (let i = 0; i < newList.length; i++) { + const hand = newList[i]; // encapsulate 'handler.run' not to lose the whole handler list if + // one of the handlers throws an exception + + try { + if (hand.isMatch(child) && (this.authenticated || !hand.user)) { + if (hand.run(child)) { + this.handlers.push(hand); + } + } else { + this.handlers.push(hand); + } + } catch (e) { + // if the handler throws an exception, we consider it as false + Strophe.warn('Removing Strophe handlers due to uncaught exception: ' + e.message); + } + } + }); + } + /** PrivateFunction: _connect_cb + * _Private_ handler for initial connection request. + * + * This handler is used to process the initial connection request + * response from the BOSH server. It is used to set up authentication + * handlers and start the authentication process. + * + * SASL authentication will be attempted if available, otherwise + * the code will fall back to legacy authentication. + * + * Parameters: + * (Strophe.Request) req - The current request. + * (Function) _callback - low level (xmpp) connect callback function. + * Useful for plugins with their own xmpp connect callback (when they + * want to do something special). + */ + + + _connect_cb(req, _callback, raw) { + Strophe.debug("_connect_cb was called"); + this.connected = true; + let bodyWrap; + + try { + bodyWrap = this._proto._reqToData(req); + } catch (e) { + if (e.name !== Strophe.ErrorCondition.BAD_FORMAT) { + throw e; + } + + this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.BAD_FORMAT); + + this._doDisconnect(Strophe.ErrorCondition.BAD_FORMAT); + } + + if (!bodyWrap) { + return; + } + + if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) { + if (bodyWrap.nodeName === this._proto.strip && bodyWrap.childNodes.length) { + this.xmlInput(bodyWrap.childNodes[0]); + } else { + this.xmlInput(bodyWrap); + } + } + + if (this.rawInput !== Strophe.Connection.prototype.rawInput) { + if (raw) { + this.rawInput(raw); + } else { + this.rawInput(Strophe.serialize(bodyWrap)); + } + } + + const conncheck = this._proto._connect_cb(bodyWrap); + + if (conncheck === Strophe.Status.CONNFAIL) { + return; + } // Check for the stream:features tag + + + let hasFeatures; + + if (bodyWrap.getElementsByTagNameNS) { + hasFeatures = bodyWrap.getElementsByTagNameNS(Strophe.NS.STREAM, "features").length > 0; + } else { + hasFeatures = bodyWrap.getElementsByTagName("stream:features").length > 0 || bodyWrap.getElementsByTagName("features").length > 0; + } + + if (!hasFeatures) { + this._proto._no_auth_received(_callback); + + return; + } + + const matched = Array.from(bodyWrap.getElementsByTagName("mechanism")).map(m => this.mechanisms[m.textContent]).filter(m => m); + + if (matched.length === 0) { + if (bodyWrap.getElementsByTagName("auth").length === 0) { + // There are no matching SASL mechanisms and also no legacy + // auth available. + this._proto._no_auth_received(_callback); + + return; + } + } + + if (this.do_authentication !== false) { + this.authenticate(matched); + } + } + /** Function: sortMechanismsByPriority + * + * Sorts an array of objects with prototype SASLMechanism according to + * their priorities. + * + * Parameters: + * (Array) mechanisms - Array of SASL mechanisms. + * + */ + + + sortMechanismsByPriority(mechanisms) { + // eslint-disable-line class-methods-use-this + // Sorting mechanisms according to priority. + for (let i = 0; i < mechanisms.length - 1; ++i) { + let higher = i; + + for (let j = i + 1; j < mechanisms.length; ++j) { + if (mechanisms[j].priority > mechanisms[higher].priority) { + higher = j; + } + } + + if (higher !== i) { + const swap = mechanisms[i]; + mechanisms[i] = mechanisms[higher]; + mechanisms[higher] = swap; + } + } + + return mechanisms; + } + /** Function: authenticate + * Set up authentication + * + * Continues the initial connection request by setting up authentication + * handlers and starting the authentication process. + * + * SASL authentication will be attempted if available, otherwise + * the code will fall back to legacy authentication. + * + * Parameters: + * (Array) matched - Array of SASL mechanisms supported. + * + */ + + + authenticate(matched) { + if (!this._attemptSASLAuth(matched)) { + this._attemptLegacyAuth(); + } + } + /** PrivateFunction: _attemptSASLAuth + * + * Iterate through an array of SASL mechanisms and attempt authentication + * with the highest priority (enabled) mechanism. + * + * Parameters: + * (Array) mechanisms - Array of SASL mechanisms. + * + * Returns: + * (Boolean) mechanism_found - true or false, depending on whether a + * valid SASL mechanism was found with which authentication could be + * started. + */ + + + _attemptSASLAuth(mechanisms) { + mechanisms = this.sortMechanismsByPriority(mechanisms || []); + let mechanism_found = false; + + for (let i = 0; i < mechanisms.length; ++i) { + if (!mechanisms[i].test(this)) { + continue; + } + + this._sasl_success_handler = this._addSysHandler(this._sasl_success_cb.bind(this), null, "success", null, null); + this._sasl_failure_handler = this._addSysHandler(this._sasl_failure_cb.bind(this), null, "failure", null, null); + this._sasl_challenge_handler = this._addSysHandler(this._sasl_challenge_cb.bind(this), null, "challenge", null, null); + this._sasl_mechanism = mechanisms[i]; + + this._sasl_mechanism.onStart(this); + + const request_auth_exchange = $build("auth", { + 'xmlns': Strophe.NS.SASL, + 'mechanism': this._sasl_mechanism.mechname + }); + + if (this._sasl_mechanism.isClientFirst) { + const response = this._sasl_mechanism.onChallenge(this, null); + + request_auth_exchange.t(Object(abab["btoa"])(response)); + } + + this.send(request_auth_exchange.tree()); + mechanism_found = true; + break; + } + + return mechanism_found; + } + /** PrivateFunction: _sasl_challenge_cb + * _Private_ handler for the SASL challenge + * + */ + + + _sasl_challenge_cb(elem) { + const challenge = Object(abab["atob"])(Strophe.getText(elem)); + + const response = this._sasl_mechanism.onChallenge(this, challenge); + + const stanza = $build('response', { + 'xmlns': Strophe.NS.SASL + }); + + if (response !== "") { + stanza.t(Object(abab["btoa"])(response)); + } + + this.send(stanza.tree()); + return true; + } + /** PrivateFunction: _attemptLegacyAuth + * + * Attempt legacy (i.e. non-SASL) authentication. + */ + + + _attemptLegacyAuth() { + if (Strophe.getNodeFromJid(this.jid) === null) { + // we don't have a node, which is required for non-anonymous + // client connections + this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.MISSING_JID_NODE); + + this.disconnect(Strophe.ErrorCondition.MISSING_JID_NODE); + } else { + // Fall back to legacy authentication + this._changeConnectStatus(Strophe.Status.AUTHENTICATING, null); + + this._addSysHandler(this._onLegacyAuthIQResult.bind(this), null, null, null, "_auth_1"); + + this.send($iq({ + 'type': "get", + 'to': this.domain, + 'id': "_auth_1" + }).c("query", { + xmlns: Strophe.NS.AUTH + }).c("username", {}).t(Strophe.getNodeFromJid(this.jid)).tree()); + } + } + /** PrivateFunction: _onLegacyAuthIQResult + * _Private_ handler for legacy authentication. + * + * This handler is called in response to the initial + * for legacy authentication. It builds an authentication and + * sends it, creating a handler (calling back to _auth2_cb()) to + * handle the result + * + * Parameters: + * (XMLElement) elem - The stanza that triggered the callback. + * + * Returns: + * false to remove the handler. + */ + + + _onLegacyAuthIQResult(elem) { + // eslint-disable-line no-unused-vars + // build plaintext auth iq + const iq = $iq({ + type: "set", + id: "_auth_2" + }).c('query', { + xmlns: Strophe.NS.AUTH + }).c('username', {}).t(Strophe.getNodeFromJid(this.jid)).up().c('password').t(this.pass); + + if (!Strophe.getResourceFromJid(this.jid)) { + // since the user has not supplied a resource, we pick + // a default one here. unlike other auth methods, the server + // cannot do this for us. + this.jid = Strophe.getBareJidFromJid(this.jid) + '/strophe'; + } + + iq.up().c('resource', {}).t(Strophe.getResourceFromJid(this.jid)); + + this._addSysHandler(this._auth2_cb.bind(this), null, null, null, "_auth_2"); + + this.send(iq.tree()); + return false; + } + /** PrivateFunction: _sasl_success_cb + * _Private_ handler for succesful SASL authentication. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _sasl_success_cb(elem) { + if (this._sasl_data["server-signature"]) { + let serverSignature; + const success = Object(abab["atob"])(Strophe.getText(elem)); + const attribMatch = /([a-z]+)=([^,]+)(,|$)/; + const matches = success.match(attribMatch); + + if (matches[1] === "v") { + serverSignature = matches[2]; + } + + if (serverSignature !== this._sasl_data["server-signature"]) { + // remove old handlers + this.deleteHandler(this._sasl_failure_handler); + this._sasl_failure_handler = null; + + if (this._sasl_challenge_handler) { + this.deleteHandler(this._sasl_challenge_handler); + this._sasl_challenge_handler = null; + } + + this._sasl_data = {}; + return this._sasl_failure_cb(null); + } + } + + Strophe.info("SASL authentication succeeded."); + + if (this._sasl_mechanism) { + this._sasl_mechanism.onSuccess(); + } // remove old handlers + + + this.deleteHandler(this._sasl_failure_handler); + this._sasl_failure_handler = null; + + if (this._sasl_challenge_handler) { + this.deleteHandler(this._sasl_challenge_handler); + this._sasl_challenge_handler = null; + } + + const streamfeature_handlers = []; + + const wrapper = (handlers, elem) => { + while (handlers.length) { + this.deleteHandler(handlers.pop()); + } + + this._onStreamFeaturesAfterSASL(elem); + + return false; + }; + + streamfeature_handlers.push(this._addSysHandler(elem => wrapper(streamfeature_handlers, elem), null, "stream:features", null, null)); + streamfeature_handlers.push(this._addSysHandler(elem => wrapper(streamfeature_handlers, elem), Strophe.NS.STREAM, "features", null, null)); // we must send an xmpp:restart now + + this._sendRestart(); + + return false; + } + /** PrivateFunction: _onStreamFeaturesAfterSASL + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _onStreamFeaturesAfterSASL(elem) { + // save stream:features for future usage + this.features = elem; + + for (let i = 0; i < elem.childNodes.length; i++) { + const child = elem.childNodes[i]; + + if (child.nodeName === 'bind') { + this.do_bind = true; + } + + if (child.nodeName === 'session') { + this.do_session = true; + } + } + + if (!this.do_bind) { + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null); + + return false; + } else if (!this.options.explicitResourceBinding) { + this.bind(); + } else { + this._changeConnectStatus(Strophe.Status.BINDREQUIRED, null); + } + + return false; + } + /** Function: bind + * + * Sends an IQ to the XMPP server to bind a JID resource for this session. + * + * https://tools.ietf.org/html/rfc6120#section-7.5 + * + * If `explicitResourceBinding` was set to a truthy value in the options + * passed to the Strophe.Connection constructor, then this function needs + * to be called explicitly by the client author. + * + * Otherwise it'll be called automatically as soon as the XMPP server + * advertises the "urn:ietf:params:xml:ns:xmpp-bind" stream feature. + */ + + + bind() { + if (!this.do_bind) { + Strophe.log(Strophe.LogLevel.INFO, "Strophe.Connection.prototype.bind called but \"do_bind\" is false"); + return; + } + + this._addSysHandler(this._onResourceBindResultIQ.bind(this), null, null, null, "_bind_auth_2"); + + const resource = Strophe.getResourceFromJid(this.jid); + + if (resource) { + this.send($iq({ + type: "set", + id: "_bind_auth_2" + }).c('bind', { + xmlns: Strophe.NS.BIND + }).c('resource', {}).t(resource).tree()); + } else { + this.send($iq({ + type: "set", + id: "_bind_auth_2" + }).c('bind', { + xmlns: Strophe.NS.BIND + }).tree()); + } + } + /** PrivateFunction: _onResourceBindIQ + * _Private_ handler for binding result and session start. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _onResourceBindResultIQ(elem) { + if (elem.getAttribute("type") === "error") { + Strophe.warn("Resource binding failed."); + const conflict = elem.getElementsByTagName("conflict"); + let condition; + + if (conflict.length > 0) { + condition = Strophe.ErrorCondition.CONFLICT; + } + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, condition, elem); + + return false; + } // TODO - need to grab errors + + + const bind = elem.getElementsByTagName("bind"); + + if (bind.length > 0) { + const jidNode = bind[0].getElementsByTagName("jid"); + + if (jidNode.length > 0) { + this.authenticated = true; + this.jid = Strophe.getText(jidNode[0]); + + if (this.do_session) { + this._establishSession(); + } else { + this._changeConnectStatus(Strophe.Status.CONNECTED, null); + } + } + } else { + Strophe.warn("Resource binding failed."); + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + return false; + } + } + /** PrivateFunction: _establishSession + * Send IQ request to establish a session with the XMPP server. + * + * See https://xmpp.org/rfcs/rfc3921.html#session + * + * Note: The protocol for session establishment has been determined as + * unnecessary and removed in RFC-6121. + */ + + + _establishSession() { + if (!this.do_session) { + throw new Error("Strophe.Connection.prototype._establishSession " + "called but apparently ".concat(Strophe.NS.SESSION, " wasn't advertised by the server")); + } + + this._addSysHandler(this._onSessionResultIQ.bind(this), null, null, null, "_session_auth_2"); + + this.send($iq({ + type: "set", + id: "_session_auth_2" + }).c('session', { + xmlns: Strophe.NS.SESSION + }).tree()); + } + /** PrivateFunction: _onSessionResultIQ + * _Private_ handler for the server's IQ response to a client's session + * request. + * + * This sets Connection.authenticated to true on success, which + * starts the processing of user handlers. + * + * See https://xmpp.org/rfcs/rfc3921.html#session + * + * Note: The protocol for session establishment has been determined as + * unnecessary and removed in RFC-6121. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _onSessionResultIQ(elem) { + if (elem.getAttribute("type") === "result") { + this.authenticated = true; + + this._changeConnectStatus(Strophe.Status.CONNECTED, null); + } else if (elem.getAttribute("type") === "error") { + this.authenticated = false; + Strophe.warn("Session creation failed."); + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + return false; + } + + return false; + } + /** PrivateFunction: _sasl_failure_cb + * _Private_ handler for SASL authentication failure. + * + * Parameters: + * (XMLElement) elem - The matching stanza. + * + * Returns: + * false to remove the handler. + */ + + + _sasl_failure_cb(elem) { + // delete unneeded handlers + if (this._sasl_success_handler) { + this.deleteHandler(this._sasl_success_handler); + this._sasl_success_handler = null; + } + + if (this._sasl_challenge_handler) { + this.deleteHandler(this._sasl_challenge_handler); + this._sasl_challenge_handler = null; + } + + if (this._sasl_mechanism) this._sasl_mechanism.onFailure(); + + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + return false; + } + /** PrivateFunction: _auth2_cb + * _Private_ handler to finish legacy authentication. + * + * This handler is called when the result from the jabber:iq:auth + * stanza is returned. + * + * Parameters: + * (XMLElement) elem - The stanza that triggered the callback. + * + * Returns: + * false to remove the handler. + */ + + + _auth2_cb(elem) { + if (elem.getAttribute("type") === "result") { + this.authenticated = true; + + this._changeConnectStatus(Strophe.Status.CONNECTED, null); + } else if (elem.getAttribute("type") === "error") { + this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem); + + this.disconnect('authentication failed'); + } + + return false; + } + /** PrivateFunction: _addSysTimedHandler + * _Private_ function to add a system level timed handler. + * + * This function is used to add a Strophe.TimedHandler for the + * library code. System timed handlers are allowed to run before + * authentication is complete. + * + * Parameters: + * (Integer) period - The period of the handler. + * (Function) handler - The callback function. + */ + + + _addSysTimedHandler(period, handler) { + const thand = new Strophe.TimedHandler(period, handler); + thand.user = false; + this.addTimeds.push(thand); + return thand; + } + /** PrivateFunction: _addSysHandler + * _Private_ function to add a system level stanza handler. + * + * This function is used to add a Strophe.Handler for the + * library code. System stanza handlers are allowed to run before + * authentication is complete. + * + * Parameters: + * (Function) handler - The callback function. + * (String) ns - The namespace to match. + * (String) name - The stanza name to match. + * (String) type - The stanza type attribute to match. + * (String) id - The stanza id attribute to match. + */ + + + _addSysHandler(handler, ns, name, type, id) { + const hand = new Strophe.Handler(handler, ns, name, type, id); + hand.user = false; + this.addHandlers.push(hand); + return hand; + } + /** PrivateFunction: _onDisconnectTimeout + * _Private_ timeout handler for handling non-graceful disconnection. + * + * If the graceful disconnect process does not complete within the + * time allotted, this handler finishes the disconnect anyway. + * + * Returns: + * false to remove the handler. + */ + + + _onDisconnectTimeout() { + Strophe.debug("_onDisconnectTimeout was called"); + + this._changeConnectStatus(Strophe.Status.CONNTIMEOUT, null); + + this._proto._onDisconnectTimeout(); // actually disconnect + + + this._doDisconnect(); + + return false; + } + /** PrivateFunction: _onIdle + * _Private_ handler to process events during idle cycle. + * + * This handler is called every 100ms to fire timed handlers that + * are ready and keep poll requests going. + */ + + + _onIdle() { + // add timed handlers scheduled for addition + // NOTE: we add before remove in the case a timed handler is + // added and then deleted before the next _onIdle() call. + while (this.addTimeds.length > 0) { + this.timedHandlers.push(this.addTimeds.pop()); + } // remove timed handlers that have been scheduled for deletion + + + while (this.removeTimeds.length > 0) { + const thand = this.removeTimeds.pop(); + const i = this.timedHandlers.indexOf(thand); + + if (i >= 0) { + this.timedHandlers.splice(i, 1); + } + } // call ready timed handlers + + + const now = new Date().getTime(); + const newList = []; + + for (let i = 0; i < this.timedHandlers.length; i++) { + const thand = this.timedHandlers[i]; + + if (this.authenticated || !thand.user) { + const since = thand.lastCalled + thand.period; + + if (since - now <= 0) { + if (thand.run()) { + newList.push(thand); + } + } else { + newList.push(thand); + } + } + } + + this.timedHandlers = newList; + clearTimeout(this._idleTimeout); + + this._proto._onIdle(); // reactivate the timer only if connected + + + if (this.connected) { + this._idleTimeout = setTimeout(() => this._onIdle(), 100); + } + } + +}; +/** Class: Strophe.SASLMechanism + * + * Encapsulates an SASL authentication mechanism. + * + * User code may override the priority for each mechanism or disable it completely. + * See for information about changing priority and for informatian on + * how to disable a mechanism. + * + * By default, all mechanisms are enabled and the priorities are + * + * SCRAM-SHA-1 - 60 + * PLAIN - 50 + * OAUTHBEARER - 40 + * X-OAUTH2 - 30 + * ANONYMOUS - 20 + * EXTERNAL - 10 + * + * See: Strophe.Connection.addSupportedSASLMechanisms + */ + +Strophe.SASLMechanism = class SASLMechanism { + /** + * PrivateConstructor: Strophe.SASLMechanism + * SASL auth mechanism abstraction. + * + * Parameters: + * (String) name - SASL Mechanism name. + * (Boolean) isClientFirst - If client should send response first without challenge. + * (Number) priority - Priority. + * + * Returns: + * A new Strophe.SASLMechanism object. + */ + constructor(name, isClientFirst, priority) { + /** PrivateVariable: mechname + * Mechanism name. + */ + this.mechname = name; + /** PrivateVariable: isClientFirst + * If client sends response without initial server challenge. + */ + + this.isClientFirst = isClientFirst; + /** Variable: priority + * Determines which is chosen for authentication (Higher is better). + * Users may override this to prioritize mechanisms differently. + * + * Example: (This will cause Strophe to choose the mechanism that the server sent first) + * + * > Strophe.SASLPlain.priority = Strophe.SASLSHA1.priority; + * + * See for a list of available mechanisms. + * + */ + + this.priority = priority; + } + /** + * Function: test + * Checks if mechanism able to run. + * To disable a mechanism, make this return false; + * + * To disable plain authentication run + * > Strophe.SASLPlain.test = function() { + * > return false; + * > } + * + * See for a list of available mechanisms. + * + * Parameters: + * (Strophe.Connection) connection - Target Connection. + * + * Returns: + * (Boolean) If mechanism was able to run. + */ + + + test() { + // eslint-disable-line class-methods-use-this + return true; + } + /** PrivateFunction: onStart + * Called before starting mechanism on some connection. + * + * Parameters: + * (Strophe.Connection) connection - Target Connection. + */ + + + onStart(connection) { + this._connection = connection; + } + /** PrivateFunction: onChallenge + * Called by protocol implementation on incoming challenge. If client is + * first (isClientFirst === true) challenge will be null on the first call. + * + * Parameters: + * (Strophe.Connection) connection - Target Connection. + * (String) challenge - current challenge to handle. + * + * Returns: + * (String) Mechanism response. + */ + + + onChallenge(connection, challenge) { + // eslint-disable-line + throw new Error("You should implement challenge handling!"); + } + /** PrivateFunction: onFailure + * Protocol informs mechanism implementation about SASL failure. + */ + + + onFailure() { + this._connection = null; + } + /** PrivateFunction: onSuccess + * Protocol informs mechanism implementation about SASL success. + */ + + + onSuccess() { + this._connection = null; + } + +}; +/** Constants: SASL mechanisms + * Available authentication mechanisms + * + * Strophe.SASLAnonymous - SASL ANONYMOUS authentication. + * Strophe.SASLPlain - SASL PLAIN authentication. + * Strophe.SASLSHA1 - SASL SCRAM-SHA-1 authentication + * Strophe.SASLOAuthBearer - SASL OAuth Bearer authentication + * Strophe.SASLExternal - SASL EXTERNAL authentication + * Strophe.SASLXOAuth2 - SASL X-OAuth2 authentication + */ +// Building SASL callbacks + +Strophe.SASLAnonymous = class SASLAnonymous extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLAnonymous + * SASL ANONYMOUS authentication. + */ + constructor(mechname = 'ANONYMOUS', isClientFirst = false, priority = 20) { + super(mechname, isClientFirst, priority); + } + + test(connection) { + // eslint-disable-line class-methods-use-this + return connection.authcid === null; + } + +}; +Strophe.SASLPlain = class SASLPlain extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLPlain + * SASL PLAIN authentication. + */ + constructor(mechname = 'PLAIN', isClientFirst = true, priority = 50) { + super(mechname, isClientFirst, priority); + } + + test(connection) { + // eslint-disable-line class-methods-use-this + return connection.authcid !== null; + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + const { + authcid, + authzid, + domain, + pass + } = connection; + + if (!domain) { + throw new Error("SASLPlain onChallenge: domain is not defined!"); + } // Only include authzid if it differs from authcid. + // See: https://tools.ietf.org/html/rfc6120#section-6.3.8 + + + let auth_str = authzid !== "".concat(authcid, "@").concat(domain) ? authzid : ''; + auth_str = auth_str + "\u0000"; + auth_str = auth_str + authcid; + auth_str = auth_str + "\u0000"; + auth_str = auth_str + pass; + return utils.utf16to8(auth_str); + } + +}; +Strophe.SASLSHA1 = class SASLSHA1 extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLSHA1 + * SASL SCRAM SHA 1 authentication. + */ + constructor(mechname = 'SCRAM-SHA-1', isClientFirst = true, priority = 60) { + super(mechname, isClientFirst, priority); + } + + test(connection) { + // eslint-disable-line class-methods-use-this + return connection.authcid !== null; + } + + onChallenge(connection, challenge, test_cnonce) { + const cnonce = test_cnonce || MD5.hexdigest("" + Math.random() * 1234567890); + let auth_str = "n=" + utils.utf16to8(connection.authcid); + auth_str += ",r="; + auth_str += cnonce; + connection._sasl_data.cnonce = cnonce; + connection._sasl_data["client-first-message-bare"] = auth_str; + auth_str = "n,," + auth_str; + + this.onChallenge = (connection, challenge) => { + let nonce, salt, iter, Hi, U, U_old, i, k; + let responseText = "c=biws,"; + let authMessage = "".concat(connection._sasl_data["client-first-message-bare"], ",").concat(challenge, ","); + const cnonce = connection._sasl_data.cnonce; + const attribMatch = /([a-z]+)=([^,]+)(,|$)/; + + while (challenge.match(attribMatch)) { + const matches = challenge.match(attribMatch); + challenge = challenge.replace(matches[0], ""); + + switch (matches[1]) { + case "r": + nonce = matches[2]; + break; + + case "s": + salt = matches[2]; + break; + + case "i": + iter = matches[2]; + break; + } + } + + if (nonce.substr(0, cnonce.length) !== cnonce) { + connection._sasl_data = {}; + return connection._sasl_failure_cb(); + } + + responseText += "r=" + nonce; + authMessage += responseText; + salt = Object(abab["atob"])(salt); + salt += "\x00\x00\x00\x01"; + const pass = utils.utf16to8(connection.pass); + Hi = U_old = SHA1.core_hmac_sha1(pass, salt); + + for (i = 1; i < iter; i++) { + U = SHA1.core_hmac_sha1(pass, SHA1.binb2str(U_old)); + + for (k = 0; k < 5; k++) { + Hi[k] ^= U[k]; + } + + U_old = U; + } + + Hi = SHA1.binb2str(Hi); + const clientKey = SHA1.core_hmac_sha1(Hi, "Client Key"); + const serverKey = SHA1.str_hmac_sha1(Hi, "Server Key"); + const clientSignature = SHA1.core_hmac_sha1(SHA1.str_sha1(SHA1.binb2str(clientKey)), authMessage); + connection._sasl_data["server-signature"] = SHA1.b64_hmac_sha1(serverKey, authMessage); + + for (k = 0; k < 5; k++) { + clientKey[k] ^= clientSignature[k]; + } + + responseText += ",p=" + Object(abab["btoa"])(SHA1.binb2str(clientKey)); + return responseText; + }; + + return auth_str; + } + +}; +Strophe.SASLOAuthBearer = class SASLOAuthBearer extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLOAuthBearer + * SASL OAuth Bearer authentication. + */ + constructor(mechname = 'OAUTHBEARER', isClientFirst = true, priority = 40) { + super(mechname, isClientFirst, priority); + } + + test(connection) { + // eslint-disable-line class-methods-use-this + return connection.pass !== null; + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + let auth_str = 'n,'; + + if (connection.authcid !== null) { + auth_str = auth_str + 'a=' + connection.authzid; + } + + auth_str = auth_str + ','; + auth_str = auth_str + "\u0001"; + auth_str = auth_str + 'auth=Bearer '; + auth_str = auth_str + connection.pass; + auth_str = auth_str + "\u0001"; + auth_str = auth_str + "\u0001"; + return utils.utf16to8(auth_str); + } + +}; +Strophe.SASLExternal = class SASLExternal extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLExternal + * SASL EXTERNAL authentication. + * + * The EXTERNAL mechanism allows a client to request the server to use + * credentials established by means external to the mechanism to + * authenticate the client. The external means may be, for instance, + * TLS services. + */ + constructor(mechname = 'EXTERNAL', isClientFirst = true, priority = 10) { + super(mechname, isClientFirst, priority); + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + + /** According to XEP-178, an authzid SHOULD NOT be presented when the + * authcid contained or implied in the client certificate is the JID (i.e. + * authzid) with which the user wants to log in as. + * + * To NOT send the authzid, the user should therefore set the authcid equal + * to the JID when instantiating a new Strophe.Connection object. + */ + return connection.authcid === connection.authzid ? '' : connection.authzid; + } + +}; +Strophe.SASLXOAuth2 = class SASLXOAuth2 extends Strophe.SASLMechanism { + /** PrivateConstructor: SASLXOAuth2 + * SASL X-OAuth2 authentication. + */ + constructor(mechname = 'X-OAUTH2', isClientFirst = true, priority = 30) { + super(mechname, isClientFirst, priority); + } + + test(connection) { + // eslint-disable-line class-methods-use-this + return connection.pass !== null; + } + + onChallenge(connection) { + // eslint-disable-line class-methods-use-this + let auth_str = '\u0000'; + + if (connection.authcid !== null) { + auth_str = auth_str + connection.authzid; + } + + auth_str = auth_str + "\u0000"; + auth_str = auth_str + connection.pass; + return utils.utf16to8(auth_str); + } + +}; + +/* harmony default export */ var core = __webpack_exports__["e"] = ({ + 'Strophe': Strophe, + '$build': $build, + '$iq': $iq, + '$msg': $msg, + '$pres': $pres, + 'SHA1': SHA1, + 'MD5': MD5, + 'b64_hmac_sha1': SHA1.b64_hmac_sha1, + 'b64_sha1': SHA1.b64_sha1, + 'str_hmac_sha1': SHA1.str_hmac_sha1, + 'str_sha1': SHA1.str_sha1 +}); + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +var __WEBPACK_AMD_DEFINE_RESULT__;/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +// EXPOSE +var _sizzle = window.Sizzle; + +Sizzle.noConflict = function() { + if ( window.Sizzle === Sizzle ) { + window.Sizzle = _sizzle; + } + + return Sizzle; +}; + +if ( true ) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() { + return Sizzle; + }).call(exports, __webpack_require__, exports, module), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + +// Sizzle requires that there be a global window in Common-JS like environments +} else {} + +// EXPOSE + +} )( window ); + + +/***/ }), +/* 3 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var _bosh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(154); +/* harmony import */ var _websocket__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68); +/* harmony import */ var _worker_websocket__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(493); +/* harmony import */ var _core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(0); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "e", function() { return _core__WEBPACK_IMPORTED_MODULE_3__["e"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _core__WEBPACK_IMPORTED_MODULE_3__["a"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "b", function() { return _core__WEBPACK_IMPORTED_MODULE_3__["b"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "c", function() { return _core__WEBPACK_IMPORTED_MODULE_3__["c"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "d", function() { return _core__WEBPACK_IMPORTED_MODULE_3__["d"]; }); + +/*global global*/ + + + + +global.$build = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "f"].$build; +global.$iq = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "f"].$iq; +global.$msg = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "f"].$msg; +global.$pres = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "f"].$pres; +global.Strophe = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "f"].Strophe; + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(12))) + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +!function(t,e){ true?module.exports=e():undefined}(this,function(){"use strict";var t="millisecond",e="second",n="minute",r="hour",i="day",s="week",u="month",o="quarter",a="year",h=/^(\d{4})-?(\d{1,2})-?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d{1,3})?$/,f=/\[([^\]]+)]|Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,c=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},d={s:c,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+c(r,2,"0")+":"+c(i,2,"0")},m:function(t,e){var n=12*(e.year()-t.year())+(e.month()-t.month()),r=t.clone().add(n,u),i=e-r<0,s=t.clone().add(n+(i?-1:1),u);return Number(-(n+(e-r)/(i?r-s:s-r))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(h){return{M:u,y:a,w:s,d:i,D:"date",h:r,m:n,s:e,ms:t,Q:o}[h]||String(h||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},$={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},l="en",m={};m[l]=$;var y=function(t){return t instanceof v},M=function(t,e,n){var r;if(!t)return l;if("string"==typeof t)m[t]&&(r=t),e&&(m[t]=e,r=t);else{var i=t.name;m[i]=t,r=i}return!n&&r&&(l=r),r||!n&&l},g=function(t,e){if(y(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new v(n)},D=d;D.l=M,D.i=y,D.w=function(t,e){return g(t,{locale:e.$L,utc:e.$u,$offset:e.$offset})};var v=function(){function c(t){this.$L=this.$L||M(t.locale,null,!0),this.parse(t)}var d=c.prototype;return d.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(D.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(h);if(r)return n?new Date(Date.UTC(r[1],r[2]-1,r[3]||1,r[4]||0,r[5]||0,r[6]||0,r[7]||0)):new Date(r[1],r[2]-1,r[3]||1,r[4]||0,r[5]||0,r[6]||0,r[7]||0)}return new Date(e)}(t),this.init()},d.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},d.$utils=function(){return D},d.isValid=function(){return!("Invalid Date"===this.$d.toString())},d.isSame=function(t,e){var n=g(t);return this.startOf(e)<=n&&n<=this.endOf(e)},d.isAfter=function(t,e){return g(t)> 5] |= 0x80 << 24 - len % 32; + x[(len + 64 >> 9 << 4) + 15] = len; + var w = new Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + var i, j, t, olda, oldb, oldc, oldd, olde; + + for (i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + olde = e; + + for (j = 0; j < 80; j++) { + if (j < 16) { + w[j] = x[i + j]; + } else { + w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); + } + + t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + + return [a, b, c, d, e]; +} +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ + + +function sha1_ft(t, b, c, d) { + if (t < 20) { + return b & c | ~b & d; + } + + if (t < 40) { + return b ^ c ^ d; + } + + if (t < 60) { + return b & c | b & d | c & d; + } + + return b ^ c ^ d; +} +/* + * Determine the appropriate additive constant for the current iteration + */ + + +function sha1_kt(t) { + return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514; +} +/* + * Calculate the HMAC-SHA1 of a key and some data + */ + + +function core_hmac_sha1(key, data) { + var bkey = str2binb(key); + + if (bkey.length > 16) { + bkey = core_sha1(bkey, key.length * 8); + } + + var ipad = new Array(16), + opad = new Array(16); + + for (var i = 0; i < 16; i++) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * 8); + return core_sha1(opad.concat(hash), 512 + 160); +} +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + + +function safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return msw << 16 | lsw & 0xFFFF; +} +/* + * Bitwise rotate a 32-bit number to the left. + */ + + +function rol(num, cnt) { + return num << cnt | num >>> 32 - cnt; +} +/* + * Convert an 8-bit or 16-bit string to an array of big-endian words + * In 8-bit function, characters >255 have their hi-byte silently ignored. + */ + + +function str2binb(str) { + var bin = []; + var mask = 255; + + for (var i = 0; i < str.length * 8; i += 8) { + bin[i >> 5] |= (str.charCodeAt(i / 8) & mask) << 24 - i % 32; + } + + return bin; +} +/* + * Convert an array of big-endian words to a base-64 string + */ + + +function binb2b64(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + var triplet, j; + + for (var i = 0; i < binarray.length * 4; i += 3) { + triplet = (binarray[i >> 2] >> 8 * (3 - i % 4) & 0xFF) << 16 | (binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4) & 0xFF) << 8 | binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4) & 0xFF; + + for (j = 0; j < 4; j++) { + if (i * 8 + j * 6 > binarray.length * 32) { + str += "="; + } else { + str += tab.charAt(triplet >> 6 * (3 - j) & 0x3F); + } + } + } + + return str; +} +/* + * Convert an array of big-endian words to a string + */ + + +function binb2str(bin) { + var str = ""; + var mask = 255; + + for (var i = 0; i < bin.length * 32; i += 8) { + str += String.fromCharCode(bin[i >> 5] >>> 24 - i % 32 & mask); + } + + return str; +} +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ + + +const SHA1 = { + b64_hmac_sha1: function b64_hmac_sha1(key, data) { + return binb2b64(core_hmac_sha1(key, data)); + }, + b64_sha1: function b64_sha1(s) { + return binb2b64(core_sha1(str2binb(s), s.length * 8)); + }, + binb2str: binb2str, + core_hmac_sha1: core_hmac_sha1, + str_hmac_sha1: function str_hmac_sha1(key, data) { + return binb2str(core_hmac_sha1(key, data)); + }, + str_sha1: function str_sha1(s) { + return binb2str(core_sha1(str2binb(s), s.length * 8)); + } +}; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +var escapeHtmlChar = __webpack_require__(496), + toString = __webpack_require__(137); + +/** Used to match HTML entities and HTML characters. */ +var reUnescapedHtml = /[&<>"']/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + +/** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ +function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; +} + +module.exports = escape; + + +/***/ }), +/* 9 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return WebSocket; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return DOMParser; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return getDummyXMLDOMDocument; }); +/* + * This module provides uniform + * Shims APIs and globals that are not present in all JS environments, + * the most common example for Strophe being browser APIs like WebSocket + * and DOM that don't exist under nodejs. + * + * Usually these will be supplied in nodejs by conditionally requiring a + * NPM module that provides a compatible implementation. + */ + +/* global global */ + +/** + * WHATWG WebSockets API + * https://www.w3.org/TR/websockets/ + * + * Interface to use the web socket protocol + * + * Used implementations: + * - supported browsers: built-in in WebSocket global + * https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Browser_compatibility + * - nodejs: use standard-compliant 'ws' module + * https://www.npmjs.com/package/ws + */ +function getWebSocketImplementation() { + let WebSocketImplementation = global.WebSocket; + + if (typeof WebSocketImplementation === 'undefined') { + try { + WebSocketImplementation = __webpack_require__(499); + } catch (err) { + throw new Error('You must install the "ws" package to use Strophe in nodejs.'); + } + } + + return WebSocketImplementation; +} + +const WebSocket = getWebSocketImplementation(); +/** + * DOMParser + * https://w3c.github.io/DOM-Parsing/#the-domparser-interface + * + * Interface to parse XML strings into Document objects + * + * Used implementations: + * - supported browsers: built-in in DOMParser global + * https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Browser_compatibility + * - nodejs: use 'xmldom' module + * https://www.npmjs.com/package/xmldom + */ + +function getDOMParserImplementation() { + let DOMParserImplementation = global.DOMParser; + + if (typeof DOMParserImplementation === 'undefined') { + try { + DOMParserImplementation = __webpack_require__(47).DOMParser; + } catch (err) { + throw new Error('You must install the "xmldom" package to use Strophe in nodejs.'); + } + } + + return DOMParserImplementation; +} + +const DOMParser = getDOMParserImplementation(); +/** + * Gets IE xml doc object. Used by getDummyXMLDocument shim. + * + * Returns: + * A Microsoft XML DOM Object + * See Also: + * http://msdn.microsoft.com/en-us/library/ms757837%28VS.85%29.aspx + */ + +function _getIEXmlDom() { + const docStrings = ["Msxml2.DOMDocument.6.0", "Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]; + + for (let d = 0; d < docStrings.length; d++) { + try { + // eslint-disable-next-line no-undef + const doc = new ActiveXObject(docStrings[d]); + return doc; + } catch (e) {// Try next one + } + } +} +/** + * Creates a dummy XML DOM document to serve as an element and text node generator. + * + * Used implementations: + * - IE < 10: avoid using createDocument() due to a memory leak, use ie-specific + * workaround + * - other supported browsers: use document's createDocument + * - nodejs: use 'xmldom' + */ + + +function getDummyXMLDOMDocument() { + // nodejs + if (typeof document === 'undefined') { + try { + const DOMImplementation = __webpack_require__(47).DOMImplementation; + + return new DOMImplementation().createDocument('jabber:client', 'strophe', null); + } catch (err) { + throw new Error('You must install the "xmldom" package to use Strophe in nodejs.'); + } + } // IE < 10 + + + if (document.implementation.createDocument === undefined || document.implementation.createDocument && document.documentMode && document.documentMode < 10) { + const doc = _getIEXmlDom(); + + doc.appendChild(doc.createElement('strophe')); + return doc; + } // All other supported browsers + + + return document.implementation.createDocument('jabber:client', 'strophe', null); +} +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(12))) + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const atob = __webpack_require__(330); +const btoa = __webpack_require__(331); + +module.exports = { + atob, + btoa +}; + + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +var freeGlobal = __webpack_require__(96); + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +module.exports = root; + + +/***/ }), +/* 12 */ +/***/ (function(module, exports) { + +var g; + +// This works in non-strict mode +g = (function() { + return this; +})(); + +try { + // This works if eval is allowed (see CSP) + g = g || new Function("return this")(); +} catch (e) { + // This works if the window reference is available + if (typeof window === "object") g = window; +} + +// g can still be undefined, but nothing to do about it... +// We return undefined, instead of nothing here, so it's +// easier to handle this case. if(!global) { ...} + +module.exports = g; + + +/***/ }), +/* 13 */ +/***/ (function(module, exports) { + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); +if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef + + +/***/ }), +/* 14 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(module) {/* harmony import */ var _freeGlobal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); + + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && _freeGlobal_js__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"].process; + +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} +}()); + +/* harmony default export */ __webpack_exports__["a"] = (nodeUtil); + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(69)(module))) + +/***/ }), +/* 15 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) {/* unused harmony export WebSocket */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return DOMParser; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return getDummyXMLDOMDocument; }); +/* + * This module provides uniform + * Shims APIs and globals that are not present in all JS environments, + * the most common example for Strophe being browser APIs like WebSocket + * and DOM that don't exist under nodejs. + * + * Usually these will be supplied in nodejs by conditionally requiring a + * NPM module that provides a compatible implementation. + */ + +/* global global */ + +/** + * WHATWG WebSockets API + * https://www.w3.org/TR/websockets/ + * + * Interface to use the web socket protocol + * + * Used implementations: + * - supported browsers: built-in in WebSocket global + * https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Browser_compatibility + * - nodejs: use standard-compliant 'ws' module + * https://www.npmjs.com/package/ws + */ +function getWebSocketImplementation() { + let WebSocketImplementation = global.WebSocket; + + if (typeof WebSocketImplementation === 'undefined') { + try { + WebSocketImplementation = __webpack_require__(328); + } catch (err) { + throw new Error('You must install the "ws" package to use Strophe in nodejs.'); + } + } + + return WebSocketImplementation; +} + +const WebSocket = getWebSocketImplementation(); +/** + * DOMParser + * https://w3c.github.io/DOM-Parsing/#the-domparser-interface + * + * Interface to parse XML strings into Document objects + * + * Used implementations: + * - supported browsers: built-in in DOMParser global + * https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Browser_compatibility + * - nodejs: use 'xmldom' module + * https://www.npmjs.com/package/xmldom + */ + +function getDOMParserImplementation() { + let DOMParserImplementation = global.DOMParser; + + if (typeof DOMParserImplementation === 'undefined') { + try { + DOMParserImplementation = __webpack_require__(47).DOMParser; + } catch (err) { + throw new Error('You must install the "xmldom" package to use Strophe in nodejs.'); + } + } + + return DOMParserImplementation; +} + +const DOMParser = getDOMParserImplementation(); +/** + * Gets IE xml doc object. Used by getDummyXMLDocument shim. + * + * Returns: + * A Microsoft XML DOM Object + * See Also: + * http://msdn.microsoft.com/en-us/library/ms757837%28VS.85%29.aspx + */ + +function _getIEXmlDom() { + const docStrings = ["Msxml2.DOMDocument.6.0", "Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]; + + for (let d = 0; d < docStrings.length; d++) { + try { + // eslint-disable-next-line no-undef + const doc = new ActiveXObject(docStrings[d]); + return doc; + } catch (e) {// Try next one + } + } +} +/** + * Creates a dummy XML DOM document to serve as an element and text node generator. + * + * Used implementations: + * - IE < 10: avoid using createDocument() due to a memory leak, use ie-specific + * workaround + * - other supported browsers: use document's createDocument + * - nodejs: use 'xmldom' + */ + + +function getDummyXMLDOMDocument() { + // nodejs + if (typeof document === 'undefined') { + try { + const DOMImplementation = __webpack_require__(47).DOMImplementation; + + return new DOMImplementation().createDocument('jabber:client', 'strophe', null); + } catch (err) { + throw new Error('You must install the "xmldom" package to use Strophe in nodejs.'); + } + } // IE < 10 + + + if (document.implementation.createDocument === undefined || document.implementation.createDocument && document.documentMode && document.documentMode < 10) { + const doc = _getIEXmlDom(); + + doc.appendChild(doc.createElement('strophe')); + return doc; + } // All other supported browsers + + + return document.implementation.createDocument('jabber:client', 'strophe', null); +} +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(12))) + +/***/ }), +/* 16 */ +/***/ (function(module, exports) { + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +module.exports = isArray; + + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +var store = __webpack_require__(144)('wks'); +var uid = __webpack_require__(145); +var Symbol = __webpack_require__(13).Symbol; +var USE_SYMBOL = typeof Symbol == 'function'; + +var $exports = module.exports = function (name) { + return store[name] || (store[name] = + USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); +}; + +$exports.store = store; + + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +var require;var require;(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return require(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i + */ + +var FilterCSS = require("cssfilter").FilterCSS; +var getDefaultCSSWhiteList = require("cssfilter").getDefaultWhiteList; +var _ = require("./util"); + +function getDefaultWhiteList() { + return { + a: ["target", "href", "title"], + abbr: ["title"], + address: [], + area: ["shape", "coords", "href", "alt"], + article: [], + aside: [], + audio: ["autoplay", "controls", "loop", "preload", "src"], + b: [], + bdi: ["dir"], + bdo: ["dir"], + big: [], + blockquote: ["cite"], + br: [], + caption: [], + center: [], + cite: [], + code: [], + col: ["align", "valign", "span", "width"], + colgroup: ["align", "valign", "span", "width"], + dd: [], + del: ["datetime"], + details: ["open"], + div: [], + dl: [], + dt: [], + em: [], + font: ["color", "size", "face"], + footer: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + header: [], + hr: [], + i: [], + img: ["src", "alt", "title", "width", "height"], + ins: ["datetime"], + li: [], + mark: [], + nav: [], + ol: [], + p: [], + pre: [], + s: [], + section: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + table: ["width", "border", "align", "valign"], + tbody: ["align", "valign"], + td: ["width", "rowspan", "colspan", "align", "valign"], + tfoot: ["align", "valign"], + th: ["width", "rowspan", "colspan", "align", "valign"], + thead: ["align", "valign"], + tr: ["rowspan", "align", "valign"], + tt: [], + u: [], + ul: [], + video: ["autoplay", "controls", "loop", "preload", "src", "height", "width"] + }; +} + +var defaultCSSFilter = new FilterCSS(); + +/** + * default onTag function + * + * @param {String} tag + * @param {String} html + * @param {Object} options + * @return {String} + */ +function onTag(tag, html, options) { + // do nothing +} + +/** + * default onIgnoreTag function + * + * @param {String} tag + * @param {String} html + * @param {Object} options + * @return {String} + */ +function onIgnoreTag(tag, html, options) { + // do nothing +} + +/** + * default onTagAttr function + * + * @param {String} tag + * @param {String} name + * @param {String} value + * @return {String} + */ +function onTagAttr(tag, name, value) { + // do nothing +} + +/** + * default onIgnoreTagAttr function + * + * @param {String} tag + * @param {String} name + * @param {String} value + * @return {String} + */ +function onIgnoreTagAttr(tag, name, value) { + // do nothing +} + +/** + * default escapeHtml function + * + * @param {String} html + */ +function escapeHtml(html) { + return html.replace(REGEXP_LT, "<").replace(REGEXP_GT, ">"); +} + +/** + * default safeAttrValue function + * + * @param {String} tag + * @param {String} name + * @param {String} value + * @param {Object} cssFilter + * @return {String} + */ +function safeAttrValue(tag, name, value, cssFilter) { + // unescape attribute value firstly + value = friendlyAttrValue(value); + + if (name === "href" || name === "src") { + // filter `href` and `src` attribute + // only allow the value that starts with `http://` | `https://` | `mailto:` | `/` | `#` + value = _.trim(value); + if (value === "#") return "#"; + if ( + !( + value.substr(0, 7) === "http://" || + value.substr(0, 8) === "https://" || + value.substr(0, 7) === "mailto:" || + value.substr(0, 4) === "tel:" || + value.substr(0, 11) === "data:image/" || + value.substr(0, 6) === "ftp://" || + value.substr(0, 2) === "./" || + value.substr(0, 3) === "../" || + value[0] === "#" || + value[0] === "/" + ) + ) { + return ""; + } + } else if (name === "background") { + // filter `background` attribute (maybe no use) + // `javascript:` + REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) { + return ""; + } + } else if (name === "style") { + // `expression()` + REGEXP_DEFAULT_ON_TAG_ATTR_7.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_7.test(value)) { + return ""; + } + // `url()` + REGEXP_DEFAULT_ON_TAG_ATTR_8.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_8.test(value)) { + REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) { + return ""; + } + } + if (cssFilter !== false) { + cssFilter = cssFilter || defaultCSSFilter; + value = cssFilter.process(value); + } + } + + // escape `<>"` before returns + value = escapeAttrValue(value); + return value; +} + +// RegExp list +var REGEXP_LT = //g; +var REGEXP_QUOTE = /"/g; +var REGEXP_QUOTE_2 = /"/g; +var REGEXP_ATTR_VALUE_1 = /&#([a-zA-Z0-9]*);?/gim; +var REGEXP_ATTR_VALUE_COLON = /:?/gim; +var REGEXP_ATTR_VALUE_NEWLINE = /&newline;?/gim; +var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//gm; +var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/gi; +var REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/gi; +var REGEXP_DEFAULT_ON_TAG_ATTR_6 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//gi; +var REGEXP_DEFAULT_ON_TAG_ATTR_7 = /e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi; +var REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\s*r\s*l\s*\(.*/gi; + +/** + * escape doube quote + * + * @param {String} str + * @return {String} str + */ +function escapeQuote(str) { + return str.replace(REGEXP_QUOTE, """); +} + +/** + * unescape double quote + * + * @param {String} str + * @return {String} str + */ +function unescapeQuote(str) { + return str.replace(REGEXP_QUOTE_2, '"'); +} + +/** + * escape html entities + * + * @param {String} str + * @return {String} + */ +function escapeHtmlEntities(str) { + return str.replace(REGEXP_ATTR_VALUE_1, function replaceUnicode(str, code) { + return code[0] === "x" || code[0] === "X" + ? String.fromCharCode(parseInt(code.substr(1), 16)) + : String.fromCharCode(parseInt(code, 10)); + }); +} + +/** + * escape html5 new danger entities + * + * @param {String} str + * @return {String} + */ +function escapeDangerHtml5Entities(str) { + return str + .replace(REGEXP_ATTR_VALUE_COLON, ":") + .replace(REGEXP_ATTR_VALUE_NEWLINE, " "); +} + +/** + * clear nonprintable characters + * + * @param {String} str + * @return {String} + */ +function clearNonPrintableCharacter(str) { + var str2 = ""; + for (var i = 0, len = str.length; i < len; i++) { + str2 += str.charCodeAt(i) < 32 ? " " : str.charAt(i); + } + return _.trim(str2); +} + +/** + * get friendly attribute value + * + * @param {String} str + * @return {String} + */ +function friendlyAttrValue(str) { + str = unescapeQuote(str); + str = escapeHtmlEntities(str); + str = escapeDangerHtml5Entities(str); + str = clearNonPrintableCharacter(str); + return str; +} + +/** + * unescape attribute value + * + * @param {String} str + * @return {String} + */ +function escapeAttrValue(str) { + str = escapeQuote(str); + str = escapeHtml(str); + return str; +} + +/** + * `onIgnoreTag` function for removing all the tags that are not in whitelist + */ +function onIgnoreTagStripAll() { + return ""; +} + +/** + * remove tag body + * specify a `tags` list, if the tag is not in the `tags` list then process by the specify function (optional) + * + * @param {array} tags + * @param {function} next + */ +function StripTagBody(tags, next) { + if (typeof next !== "function") { + next = function() {}; + } + + var isRemoveAllTag = !Array.isArray(tags); + function isRemoveTag(tag) { + if (isRemoveAllTag) return true; + return _.indexOf(tags, tag) !== -1; + } + + var removeList = []; + var posStart = false; + + return { + onIgnoreTag: function(tag, html, options) { + if (isRemoveTag(tag)) { + if (options.isClosing) { + var ret = "[/removed]"; + var end = options.position + ret.length; + removeList.push([ + posStart !== false ? posStart : options.position, + end + ]); + posStart = false; + return ret; + } else { + if (!posStart) { + posStart = options.position; + } + return "[removed]"; + } + } else { + return next(tag, html, options); + } + }, + remove: function(html) { + var rethtml = ""; + var lastPos = 0; + _.forEach(removeList, function(pos) { + rethtml += html.slice(lastPos, pos[0]); + lastPos = pos[1]; + }); + rethtml += html.slice(lastPos); + return rethtml; + } + }; +} + +/** + * remove html comments + * + * @param {String} html + * @return {String} + */ +function stripCommentTag(html) { + return html.replace(STRIP_COMMENT_TAG_REGEXP, ""); +} +var STRIP_COMMENT_TAG_REGEXP = //g; + +/** + * remove invisible characters + * + * @param {String} html + * @return {String} + */ +function stripBlankChar(html) { + var chars = html.split(""); + chars = chars.filter(function(char) { + var c = char.charCodeAt(0); + if (c === 127) return false; + if (c <= 31) { + if (c === 10 || c === 13) return true; + return false; + } + return true; + }); + return chars.join(""); +} + +exports.whiteList = getDefaultWhiteList(); +exports.getDefaultWhiteList = getDefaultWhiteList; +exports.onTag = onTag; +exports.onIgnoreTag = onIgnoreTag; +exports.onTagAttr = onTagAttr; +exports.onIgnoreTagAttr = onIgnoreTagAttr; +exports.safeAttrValue = safeAttrValue; +exports.escapeHtml = escapeHtml; +exports.escapeQuote = escapeQuote; +exports.unescapeQuote = unescapeQuote; +exports.escapeHtmlEntities = escapeHtmlEntities; +exports.escapeDangerHtml5Entities = escapeDangerHtml5Entities; +exports.clearNonPrintableCharacter = clearNonPrintableCharacter; +exports.friendlyAttrValue = friendlyAttrValue; +exports.escapeAttrValue = escapeAttrValue; +exports.onIgnoreTagStripAll = onIgnoreTagStripAll; +exports.StripTagBody = StripTagBody; +exports.stripCommentTag = stripCommentTag; +exports.stripBlankChar = stripBlankChar; +exports.cssFilter = defaultCSSFilter; +exports.getDefaultCSSWhiteList = getDefaultCSSWhiteList; + +},{"./util":4,"cssfilter":8}],2:[function(require,module,exports){ +/** + * xss + * + * @author Zongmin Lei + */ + +var DEFAULT = require("./default"); +var parser = require("./parser"); +var FilterXSS = require("./xss"); + +/** + * filter xss function + * + * @param {String} html + * @param {Object} options { whiteList, onTag, onTagAttr, onIgnoreTag, onIgnoreTagAttr, safeAttrValue, escapeHtml } + * @return {String} + */ +function filterXSS(html, options) { + var xss = new FilterXSS(options); + return xss.process(html); +} + +exports = module.exports = filterXSS; +exports.filterXSS = filterXSS; +exports.FilterXSS = FilterXSS; +for (var i in DEFAULT) exports[i] = DEFAULT[i]; +for (var i in parser) exports[i] = parser[i]; + +// using `xss` on the browser, output `filterXSS` to the globals +if (typeof window !== "undefined") { + window.filterXSS = module.exports; +} + +// using `xss` on the WebWorker, output `filterXSS` to the globals +function isWorkerEnv() { + return typeof self !== 'undefined' && typeof DedicatedWorkerGlobalScope !== 'undefined' && self instanceof DedicatedWorkerGlobalScope; +} +if (isWorkerEnv()) { + self.filterXSS = module.exports; +} + +},{"./default":1,"./parser":3,"./xss":5}],3:[function(require,module,exports){ +/** + * Simple HTML Parser + * + * @author Zongmin Lei + */ + +var _ = require("./util"); + +/** + * get tag name + * + * @param {String} html e.g. '' + * @return {String} + */ +function getTagName(html) { + var i = _.spaceIndex(html); + if (i === -1) { + var tagName = html.slice(1, -1); + } else { + var tagName = html.slice(1, i + 1); + } + tagName = _.trim(tagName).toLowerCase(); + if (tagName.slice(0, 1) === "/") tagName = tagName.slice(1); + if (tagName.slice(-1) === "/") tagName = tagName.slice(0, -1); + return tagName; +} + +/** + * is close tag? + * + * @param {String} html 如:'' + * @return {Boolean} + */ +function isClosing(html) { + return html.slice(0, 2) === "") { + rethtml += escapeHtml(html.slice(lastPos, tagStart)); + currentHtml = html.slice(tagStart, currentPos + 1); + currentTagName = getTagName(currentHtml); + rethtml += onTag( + tagStart, + rethtml.length, + currentTagName, + currentHtml, + isClosing(currentHtml) + ); + lastPos = currentPos + 1; + tagStart = false; + continue; + } + if ((c === '"' || c === "'") && html.charAt(currentPos - 1) === "=") { + quoteStart = c; + continue; + } + } else { + if (c === quoteStart) { + quoteStart = false; + continue; + } + } + } + } + if (lastPos < html.length) { + rethtml += escapeHtml(html.substr(lastPos)); + } + + return rethtml; +} + +var REGEXP_ILLEGAL_ATTR_NAME = /[^a-zA-Z0-9_:\.\-]/gim; + +/** + * parse input attributes and returns processed attributes + * + * @param {String} html e.g. `href="#" target="_blank"` + * @param {Function} onAttr e.g. `function (name, value)` + * @return {String} + */ +function parseAttr(html, onAttr) { + "use strict"; + + var lastPos = 0; + var retAttrs = []; + var tmpName = false; + var len = html.length; + + function addAttr(name, value) { + name = _.trim(name); + name = name.replace(REGEXP_ILLEGAL_ATTR_NAME, "").toLowerCase(); + if (name.length < 1) return; + var ret = onAttr(name, value || ""); + if (ret) retAttrs.push(ret); + } + + // 逐个分析字符 + for (var i = 0; i < len; i++) { + var c = html.charAt(i); + var v, j; + if (tmpName === false && c === "=") { + tmpName = html.slice(lastPos, i); + lastPos = i + 1; + continue; + } + if (tmpName !== false) { + if ( + i === lastPos && + (c === '"' || c === "'") && + html.charAt(i - 1) === "=" + ) { + j = html.indexOf(c, i + 1); + if (j === -1) { + break; + } else { + v = _.trim(html.slice(lastPos + 1, j)); + addAttr(tmpName, v); + tmpName = false; + i = j; + lastPos = i + 1; + continue; + } + } + } + if (/\s|\n|\t/.test(c)) { + html = html.replace(/\s|\n|\t/g, " "); + if (tmpName === false) { + j = findNextEqual(html, i); + if (j === -1) { + v = _.trim(html.slice(lastPos, i)); + addAttr(v); + tmpName = false; + lastPos = i + 1; + continue; + } else { + i = j - 1; + continue; + } + } else { + j = findBeforeEqual(html, i - 1); + if (j === -1) { + v = _.trim(html.slice(lastPos, i)); + v = stripQuoteWrap(v); + addAttr(tmpName, v); + tmpName = false; + lastPos = i + 1; + continue; + } else { + continue; + } + } + } + } + + if (lastPos < html.length) { + if (tmpName === false) { + addAttr(html.slice(lastPos)); + } else { + addAttr(tmpName, stripQuoteWrap(_.trim(html.slice(lastPos)))); + } + } + + return _.trim(retAttrs.join(" ")); +} + +function findNextEqual(str, i) { + for (; i < str.length; i++) { + var c = str[i]; + if (c === " ") continue; + if (c === "=") return i; + return -1; + } +} + +function findBeforeEqual(str, i) { + for (; i > 0; i--) { + var c = str[i]; + if (c === " ") continue; + if (c === "=") return i; + return -1; + } +} + +function isQuoteWrapString(text) { + if ( + (text[0] === '"' && text[text.length - 1] === '"') || + (text[0] === "'" && text[text.length - 1] === "'") + ) { + return true; + } else { + return false; + } +} + +function stripQuoteWrap(text) { + if (isQuoteWrapString(text)) { + return text.substr(1, text.length - 2); + } else { + return text; + } +} + +exports.parseTag = parseTag; +exports.parseAttr = parseAttr; + +},{"./util":4}],4:[function(require,module,exports){ +module.exports = { + indexOf: function(arr, item) { + var i, j; + if (Array.prototype.indexOf) { + return arr.indexOf(item); + } + for (i = 0, j = arr.length; i < j; i++) { + if (arr[i] === item) { + return i; + } + } + return -1; + }, + forEach: function(arr, fn, scope) { + var i, j; + if (Array.prototype.forEach) { + return arr.forEach(fn, scope); + } + for (i = 0, j = arr.length; i < j; i++) { + fn.call(scope, arr[i], i, arr); + } + }, + trim: function(str) { + if (String.prototype.trim) { + return str.trim(); + } + return str.replace(/(^\s*)|(\s*$)/g, ""); + }, + spaceIndex: function(str) { + var reg = /\s|\n|\t/; + var match = reg.exec(str); + return match ? match.index : -1; + } +}; + +},{}],5:[function(require,module,exports){ +/** + * filter xss + * + * @author Zongmin Lei + */ + +var FilterCSS = require("cssfilter").FilterCSS; +var DEFAULT = require("./default"); +var parser = require("./parser"); +var parseTag = parser.parseTag; +var parseAttr = parser.parseAttr; +var _ = require("./util"); + +/** + * returns `true` if the input value is `undefined` or `null` + * + * @param {Object} obj + * @return {Boolean} + */ +function isNull(obj) { + return obj === undefined || obj === null; +} + +/** + * get attributes for a tag + * + * @param {String} html + * @return {Object} + * - {String} html + * - {Boolean} closing + */ +function getAttrs(html) { + var i = _.spaceIndex(html); + if (i === -1) { + return { + html: "", + closing: html[html.length - 2] === "/" + }; + } + html = _.trim(html.slice(i + 1, -1)); + var isClosing = html[html.length - 1] === "/"; + if (isClosing) html = _.trim(html.slice(0, -1)); + return { + html: html, + closing: isClosing + }; +} + +/** + * shallow copy + * + * @param {Object} obj + * @return {Object} + */ +function shallowCopyObject(obj) { + var ret = {}; + for (var i in obj) { + ret[i] = obj[i]; + } + return ret; +} + +/** + * FilterXSS class + * + * @param {Object} options + * whiteList, onTag, onTagAttr, onIgnoreTag, + * onIgnoreTagAttr, safeAttrValue, escapeHtml + * stripIgnoreTagBody, allowCommentTag, stripBlankChar + * css{whiteList, onAttr, onIgnoreAttr} `css=false` means don't use `cssfilter` + */ +function FilterXSS(options) { + options = shallowCopyObject(options || {}); + + if (options.stripIgnoreTag) { + if (options.onIgnoreTag) { + console.error( + 'Notes: cannot use these two options "stripIgnoreTag" and "onIgnoreTag" at the same time' + ); + } + options.onIgnoreTag = DEFAULT.onIgnoreTagStripAll; + } + + options.whiteList = options.whiteList || DEFAULT.whiteList; + options.onTag = options.onTag || DEFAULT.onTag; + options.onTagAttr = options.onTagAttr || DEFAULT.onTagAttr; + options.onIgnoreTag = options.onIgnoreTag || DEFAULT.onIgnoreTag; + options.onIgnoreTagAttr = options.onIgnoreTagAttr || DEFAULT.onIgnoreTagAttr; + options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue; + options.escapeHtml = options.escapeHtml || DEFAULT.escapeHtml; + this.options = options; + + if (options.css === false) { + this.cssFilter = false; + } else { + options.css = options.css || {}; + this.cssFilter = new FilterCSS(options.css); + } +} + +/** + * start process and returns result + * + * @param {String} html + * @return {String} + */ +FilterXSS.prototype.process = function(html) { + // compatible with the input + html = html || ""; + html = html.toString(); + if (!html) return ""; + + var me = this; + var options = me.options; + var whiteList = options.whiteList; + var onTag = options.onTag; + var onIgnoreTag = options.onIgnoreTag; + var onTagAttr = options.onTagAttr; + var onIgnoreTagAttr = options.onIgnoreTagAttr; + var safeAttrValue = options.safeAttrValue; + var escapeHtml = options.escapeHtml; + var cssFilter = me.cssFilter; + + // remove invisible characters + if (options.stripBlankChar) { + html = DEFAULT.stripBlankChar(html); + } + + // remove html comments + if (!options.allowCommentTag) { + html = DEFAULT.stripCommentTag(html); + } + + // if enable stripIgnoreTagBody + var stripIgnoreTagBody = false; + if (options.stripIgnoreTagBody) { + var stripIgnoreTagBody = DEFAULT.StripTagBody( + options.stripIgnoreTagBody, + onIgnoreTag + ); + onIgnoreTag = stripIgnoreTagBody.onIgnoreTag; + } + + var retHtml = parseTag( + html, + function(sourcePosition, position, tag, html, isClosing) { + var info = { + sourcePosition: sourcePosition, + position: position, + isClosing: isClosing, + isWhite: whiteList.hasOwnProperty(tag) + }; + + // call `onTag()` + var ret = onTag(tag, html, info); + if (!isNull(ret)) return ret; + + if (info.isWhite) { + if (info.isClosing) { + return ""; + } + + var attrs = getAttrs(html); + var whiteAttrList = whiteList[tag]; + var attrsHtml = parseAttr(attrs.html, function(name, value) { + // call `onTagAttr()` + var isWhiteAttr = _.indexOf(whiteAttrList, name) !== -1; + var ret = onTagAttr(tag, name, value, isWhiteAttr); + if (!isNull(ret)) return ret; + + if (isWhiteAttr) { + // call `safeAttrValue()` + value = safeAttrValue(tag, name, value, cssFilter); + if (value) { + return name + '="' + value + '"'; + } else { + return name; + } + } else { + // call `onIgnoreTagAttr()` + var ret = onIgnoreTagAttr(tag, name, value, isWhiteAttr); + if (!isNull(ret)) return ret; + return; + } + }); + + // build new tag html + var html = "<" + tag; + if (attrsHtml) html += " " + attrsHtml; + if (attrs.closing) html += " /"; + html += ">"; + return html; + } else { + // call `onIgnoreTag()` + var ret = onIgnoreTag(tag, html, info); + if (!isNull(ret)) return ret; + return escapeHtml(html); + } + }, + escapeHtml + ); + + // if enable stripIgnoreTagBody + if (stripIgnoreTagBody) { + retHtml = stripIgnoreTagBody.remove(retHtml); + } + + return retHtml; +}; + +module.exports = FilterXSS; + +},{"./default":1,"./parser":3,"./util":4,"cssfilter":8}],6:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +var DEFAULT = require('./default'); +var parseStyle = require('./parser'); +var _ = require('./util'); + + +/** + * 返回值是否为空 + * + * @param {Object} obj + * @return {Boolean} + */ +function isNull (obj) { + return (obj === undefined || obj === null); +} + +/** + * 浅拷贝对象 + * + * @param {Object} obj + * @return {Object} + */ +function shallowCopyObject (obj) { + var ret = {}; + for (var i in obj) { + ret[i] = obj[i]; + } + return ret; +} + +/** + * 创建CSS过滤器 + * + * @param {Object} options + * - {Object} whiteList + * - {Function} onAttr + * - {Function} onIgnoreAttr + * - {Function} safeAttrValue + */ +function FilterCSS (options) { + options = shallowCopyObject(options || {}); + options.whiteList = options.whiteList || DEFAULT.whiteList; + options.onAttr = options.onAttr || DEFAULT.onAttr; + options.onIgnoreAttr = options.onIgnoreAttr || DEFAULT.onIgnoreAttr; + options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue; + this.options = options; +} + +FilterCSS.prototype.process = function (css) { + // 兼容各种奇葩输入 + css = css || ''; + css = css.toString(); + if (!css) return ''; + + var me = this; + var options = me.options; + var whiteList = options.whiteList; + var onAttr = options.onAttr; + var onIgnoreAttr = options.onIgnoreAttr; + var safeAttrValue = options.safeAttrValue; + + var retCSS = parseStyle(css, function (sourcePosition, position, name, value, source) { + + var check = whiteList[name]; + var isWhite = false; + if (check === true) isWhite = check; + else if (typeof check === 'function') isWhite = check(value); + else if (check instanceof RegExp) isWhite = check.test(value); + if (isWhite !== true) isWhite = false; + + // 如果过滤后 value 为空则直接忽略 + value = safeAttrValue(name, value); + if (!value) return; + + var opts = { + position: position, + sourcePosition: sourcePosition, + source: source, + isWhite: isWhite + }; + + if (isWhite) { + + var ret = onAttr(name, value, opts); + if (isNull(ret)) { + return name + ':' + value; + } else { + return ret; + } + + } else { + + var ret = onIgnoreAttr(name, value, opts); + if (!isNull(ret)) { + return ret; + } + + } + }); + + return retCSS; +}; + + +module.exports = FilterCSS; + +},{"./default":7,"./parser":9,"./util":10}],7:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +function getDefaultWhiteList () { + // 白名单值说明: + // true: 允许该属性 + // Function: function (val) { } 返回true表示允许该属性,其他值均表示不允许 + // RegExp: regexp.test(val) 返回true表示允许该属性,其他值均表示不允许 + // 除上面列出的值外均表示不允许 + var whiteList = {}; + + whiteList['align-content'] = false; // default: auto + whiteList['align-items'] = false; // default: auto + whiteList['align-self'] = false; // default: auto + whiteList['alignment-adjust'] = false; // default: auto + whiteList['alignment-baseline'] = false; // default: baseline + whiteList['all'] = false; // default: depending on individual properties + whiteList['anchor-point'] = false; // default: none + whiteList['animation'] = false; // default: depending on individual properties + whiteList['animation-delay'] = false; // default: 0 + whiteList['animation-direction'] = false; // default: normal + whiteList['animation-duration'] = false; // default: 0 + whiteList['animation-fill-mode'] = false; // default: none + whiteList['animation-iteration-count'] = false; // default: 1 + whiteList['animation-name'] = false; // default: none + whiteList['animation-play-state'] = false; // default: running + whiteList['animation-timing-function'] = false; // default: ease + whiteList['azimuth'] = false; // default: center + whiteList['backface-visibility'] = false; // default: visible + whiteList['background'] = true; // default: depending on individual properties + whiteList['background-attachment'] = true; // default: scroll + whiteList['background-clip'] = true; // default: border-box + whiteList['background-color'] = true; // default: transparent + whiteList['background-image'] = true; // default: none + whiteList['background-origin'] = true; // default: padding-box + whiteList['background-position'] = true; // default: 0% 0% + whiteList['background-repeat'] = true; // default: repeat + whiteList['background-size'] = true; // default: auto + whiteList['baseline-shift'] = false; // default: baseline + whiteList['binding'] = false; // default: none + whiteList['bleed'] = false; // default: 6pt + whiteList['bookmark-label'] = false; // default: content() + whiteList['bookmark-level'] = false; // default: none + whiteList['bookmark-state'] = false; // default: open + whiteList['border'] = true; // default: depending on individual properties + whiteList['border-bottom'] = true; // default: depending on individual properties + whiteList['border-bottom-color'] = true; // default: current color + whiteList['border-bottom-left-radius'] = true; // default: 0 + whiteList['border-bottom-right-radius'] = true; // default: 0 + whiteList['border-bottom-style'] = true; // default: none + whiteList['border-bottom-width'] = true; // default: medium + whiteList['border-collapse'] = true; // default: separate + whiteList['border-color'] = true; // default: depending on individual properties + whiteList['border-image'] = true; // default: none + whiteList['border-image-outset'] = true; // default: 0 + whiteList['border-image-repeat'] = true; // default: stretch + whiteList['border-image-slice'] = true; // default: 100% + whiteList['border-image-source'] = true; // default: none + whiteList['border-image-width'] = true; // default: 1 + whiteList['border-left'] = true; // default: depending on individual properties + whiteList['border-left-color'] = true; // default: current color + whiteList['border-left-style'] = true; // default: none + whiteList['border-left-width'] = true; // default: medium + whiteList['border-radius'] = true; // default: 0 + whiteList['border-right'] = true; // default: depending on individual properties + whiteList['border-right-color'] = true; // default: current color + whiteList['border-right-style'] = true; // default: none + whiteList['border-right-width'] = true; // default: medium + whiteList['border-spacing'] = true; // default: 0 + whiteList['border-style'] = true; // default: depending on individual properties + whiteList['border-top'] = true; // default: depending on individual properties + whiteList['border-top-color'] = true; // default: current color + whiteList['border-top-left-radius'] = true; // default: 0 + whiteList['border-top-right-radius'] = true; // default: 0 + whiteList['border-top-style'] = true; // default: none + whiteList['border-top-width'] = true; // default: medium + whiteList['border-width'] = true; // default: depending on individual properties + whiteList['bottom'] = false; // default: auto + whiteList['box-decoration-break'] = true; // default: slice + whiteList['box-shadow'] = true; // default: none + whiteList['box-sizing'] = true; // default: content-box + whiteList['box-snap'] = true; // default: none + whiteList['box-suppress'] = true; // default: show + whiteList['break-after'] = true; // default: auto + whiteList['break-before'] = true; // default: auto + whiteList['break-inside'] = true; // default: auto + whiteList['caption-side'] = false; // default: top + whiteList['chains'] = false; // default: none + whiteList['clear'] = true; // default: none + whiteList['clip'] = false; // default: auto + whiteList['clip-path'] = false; // default: none + whiteList['clip-rule'] = false; // default: nonzero + whiteList['color'] = true; // default: implementation dependent + whiteList['color-interpolation-filters'] = true; // default: auto + whiteList['column-count'] = false; // default: auto + whiteList['column-fill'] = false; // default: balance + whiteList['column-gap'] = false; // default: normal + whiteList['column-rule'] = false; // default: depending on individual properties + whiteList['column-rule-color'] = false; // default: current color + whiteList['column-rule-style'] = false; // default: medium + whiteList['column-rule-width'] = false; // default: medium + whiteList['column-span'] = false; // default: none + whiteList['column-width'] = false; // default: auto + whiteList['columns'] = false; // default: depending on individual properties + whiteList['contain'] = false; // default: none + whiteList['content'] = false; // default: normal + whiteList['counter-increment'] = false; // default: none + whiteList['counter-reset'] = false; // default: none + whiteList['counter-set'] = false; // default: none + whiteList['crop'] = false; // default: auto + whiteList['cue'] = false; // default: depending on individual properties + whiteList['cue-after'] = false; // default: none + whiteList['cue-before'] = false; // default: none + whiteList['cursor'] = false; // default: auto + whiteList['direction'] = false; // default: ltr + whiteList['display'] = true; // default: depending on individual properties + whiteList['display-inside'] = true; // default: auto + whiteList['display-list'] = true; // default: none + whiteList['display-outside'] = true; // default: inline-level + whiteList['dominant-baseline'] = false; // default: auto + whiteList['elevation'] = false; // default: level + whiteList['empty-cells'] = false; // default: show + whiteList['filter'] = false; // default: none + whiteList['flex'] = false; // default: depending on individual properties + whiteList['flex-basis'] = false; // default: auto + whiteList['flex-direction'] = false; // default: row + whiteList['flex-flow'] = false; // default: depending on individual properties + whiteList['flex-grow'] = false; // default: 0 + whiteList['flex-shrink'] = false; // default: 1 + whiteList['flex-wrap'] = false; // default: nowrap + whiteList['float'] = false; // default: none + whiteList['float-offset'] = false; // default: 0 0 + whiteList['flood-color'] = false; // default: black + whiteList['flood-opacity'] = false; // default: 1 + whiteList['flow-from'] = false; // default: none + whiteList['flow-into'] = false; // default: none + whiteList['font'] = true; // default: depending on individual properties + whiteList['font-family'] = true; // default: implementation dependent + whiteList['font-feature-settings'] = true; // default: normal + whiteList['font-kerning'] = true; // default: auto + whiteList['font-language-override'] = true; // default: normal + whiteList['font-size'] = true; // default: medium + whiteList['font-size-adjust'] = true; // default: none + whiteList['font-stretch'] = true; // default: normal + whiteList['font-style'] = true; // default: normal + whiteList['font-synthesis'] = true; // default: weight style + whiteList['font-variant'] = true; // default: normal + whiteList['font-variant-alternates'] = true; // default: normal + whiteList['font-variant-caps'] = true; // default: normal + whiteList['font-variant-east-asian'] = true; // default: normal + whiteList['font-variant-ligatures'] = true; // default: normal + whiteList['font-variant-numeric'] = true; // default: normal + whiteList['font-variant-position'] = true; // default: normal + whiteList['font-weight'] = true; // default: normal + whiteList['grid'] = false; // default: depending on individual properties + whiteList['grid-area'] = false; // default: depending on individual properties + whiteList['grid-auto-columns'] = false; // default: auto + whiteList['grid-auto-flow'] = false; // default: none + whiteList['grid-auto-rows'] = false; // default: auto + whiteList['grid-column'] = false; // default: depending on individual properties + whiteList['grid-column-end'] = false; // default: auto + whiteList['grid-column-start'] = false; // default: auto + whiteList['grid-row'] = false; // default: depending on individual properties + whiteList['grid-row-end'] = false; // default: auto + whiteList['grid-row-start'] = false; // default: auto + whiteList['grid-template'] = false; // default: depending on individual properties + whiteList['grid-template-areas'] = false; // default: none + whiteList['grid-template-columns'] = false; // default: none + whiteList['grid-template-rows'] = false; // default: none + whiteList['hanging-punctuation'] = false; // default: none + whiteList['height'] = true; // default: auto + whiteList['hyphens'] = false; // default: manual + whiteList['icon'] = false; // default: auto + whiteList['image-orientation'] = false; // default: auto + whiteList['image-resolution'] = false; // default: normal + whiteList['ime-mode'] = false; // default: auto + whiteList['initial-letters'] = false; // default: normal + whiteList['inline-box-align'] = false; // default: last + whiteList['justify-content'] = false; // default: auto + whiteList['justify-items'] = false; // default: auto + whiteList['justify-self'] = false; // default: auto + whiteList['left'] = false; // default: auto + whiteList['letter-spacing'] = true; // default: normal + whiteList['lighting-color'] = true; // default: white + whiteList['line-box-contain'] = false; // default: block inline replaced + whiteList['line-break'] = false; // default: auto + whiteList['line-grid'] = false; // default: match-parent + whiteList['line-height'] = false; // default: normal + whiteList['line-snap'] = false; // default: none + whiteList['line-stacking'] = false; // default: depending on individual properties + whiteList['line-stacking-ruby'] = false; // default: exclude-ruby + whiteList['line-stacking-shift'] = false; // default: consider-shifts + whiteList['line-stacking-strategy'] = false; // default: inline-line-height + whiteList['list-style'] = true; // default: depending on individual properties + whiteList['list-style-image'] = true; // default: none + whiteList['list-style-position'] = true; // default: outside + whiteList['list-style-type'] = true; // default: disc + whiteList['margin'] = true; // default: depending on individual properties + whiteList['margin-bottom'] = true; // default: 0 + whiteList['margin-left'] = true; // default: 0 + whiteList['margin-right'] = true; // default: 0 + whiteList['margin-top'] = true; // default: 0 + whiteList['marker-offset'] = false; // default: auto + whiteList['marker-side'] = false; // default: list-item + whiteList['marks'] = false; // default: none + whiteList['mask'] = false; // default: border-box + whiteList['mask-box'] = false; // default: see individual properties + whiteList['mask-box-outset'] = false; // default: 0 + whiteList['mask-box-repeat'] = false; // default: stretch + whiteList['mask-box-slice'] = false; // default: 0 fill + whiteList['mask-box-source'] = false; // default: none + whiteList['mask-box-width'] = false; // default: auto + whiteList['mask-clip'] = false; // default: border-box + whiteList['mask-image'] = false; // default: none + whiteList['mask-origin'] = false; // default: border-box + whiteList['mask-position'] = false; // default: center + whiteList['mask-repeat'] = false; // default: no-repeat + whiteList['mask-size'] = false; // default: border-box + whiteList['mask-source-type'] = false; // default: auto + whiteList['mask-type'] = false; // default: luminance + whiteList['max-height'] = true; // default: none + whiteList['max-lines'] = false; // default: none + whiteList['max-width'] = true; // default: none + whiteList['min-height'] = true; // default: 0 + whiteList['min-width'] = true; // default: 0 + whiteList['move-to'] = false; // default: normal + whiteList['nav-down'] = false; // default: auto + whiteList['nav-index'] = false; // default: auto + whiteList['nav-left'] = false; // default: auto + whiteList['nav-right'] = false; // default: auto + whiteList['nav-up'] = false; // default: auto + whiteList['object-fit'] = false; // default: fill + whiteList['object-position'] = false; // default: 50% 50% + whiteList['opacity'] = false; // default: 1 + whiteList['order'] = false; // default: 0 + whiteList['orphans'] = false; // default: 2 + whiteList['outline'] = false; // default: depending on individual properties + whiteList['outline-color'] = false; // default: invert + whiteList['outline-offset'] = false; // default: 0 + whiteList['outline-style'] = false; // default: none + whiteList['outline-width'] = false; // default: medium + whiteList['overflow'] = false; // default: depending on individual properties + whiteList['overflow-wrap'] = false; // default: normal + whiteList['overflow-x'] = false; // default: visible + whiteList['overflow-y'] = false; // default: visible + whiteList['padding'] = true; // default: depending on individual properties + whiteList['padding-bottom'] = true; // default: 0 + whiteList['padding-left'] = true; // default: 0 + whiteList['padding-right'] = true; // default: 0 + whiteList['padding-top'] = true; // default: 0 + whiteList['page'] = false; // default: auto + whiteList['page-break-after'] = false; // default: auto + whiteList['page-break-before'] = false; // default: auto + whiteList['page-break-inside'] = false; // default: auto + whiteList['page-policy'] = false; // default: start + whiteList['pause'] = false; // default: implementation dependent + whiteList['pause-after'] = false; // default: implementation dependent + whiteList['pause-before'] = false; // default: implementation dependent + whiteList['perspective'] = false; // default: none + whiteList['perspective-origin'] = false; // default: 50% 50% + whiteList['pitch'] = false; // default: medium + whiteList['pitch-range'] = false; // default: 50 + whiteList['play-during'] = false; // default: auto + whiteList['position'] = false; // default: static + whiteList['presentation-level'] = false; // default: 0 + whiteList['quotes'] = false; // default: text + whiteList['region-fragment'] = false; // default: auto + whiteList['resize'] = false; // default: none + whiteList['rest'] = false; // default: depending on individual properties + whiteList['rest-after'] = false; // default: none + whiteList['rest-before'] = false; // default: none + whiteList['richness'] = false; // default: 50 + whiteList['right'] = false; // default: auto + whiteList['rotation'] = false; // default: 0 + whiteList['rotation-point'] = false; // default: 50% 50% + whiteList['ruby-align'] = false; // default: auto + whiteList['ruby-merge'] = false; // default: separate + whiteList['ruby-position'] = false; // default: before + whiteList['shape-image-threshold'] = false; // default: 0.0 + whiteList['shape-outside'] = false; // default: none + whiteList['shape-margin'] = false; // default: 0 + whiteList['size'] = false; // default: auto + whiteList['speak'] = false; // default: auto + whiteList['speak-as'] = false; // default: normal + whiteList['speak-header'] = false; // default: once + whiteList['speak-numeral'] = false; // default: continuous + whiteList['speak-punctuation'] = false; // default: none + whiteList['speech-rate'] = false; // default: medium + whiteList['stress'] = false; // default: 50 + whiteList['string-set'] = false; // default: none + whiteList['tab-size'] = false; // default: 8 + whiteList['table-layout'] = false; // default: auto + whiteList['text-align'] = true; // default: start + whiteList['text-align-last'] = true; // default: auto + whiteList['text-combine-upright'] = true; // default: none + whiteList['text-decoration'] = true; // default: none + whiteList['text-decoration-color'] = true; // default: currentColor + whiteList['text-decoration-line'] = true; // default: none + whiteList['text-decoration-skip'] = true; // default: objects + whiteList['text-decoration-style'] = true; // default: solid + whiteList['text-emphasis'] = true; // default: depending on individual properties + whiteList['text-emphasis-color'] = true; // default: currentColor + whiteList['text-emphasis-position'] = true; // default: over right + whiteList['text-emphasis-style'] = true; // default: none + whiteList['text-height'] = true; // default: auto + whiteList['text-indent'] = true; // default: 0 + whiteList['text-justify'] = true; // default: auto + whiteList['text-orientation'] = true; // default: mixed + whiteList['text-overflow'] = true; // default: clip + whiteList['text-shadow'] = true; // default: none + whiteList['text-space-collapse'] = true; // default: collapse + whiteList['text-transform'] = true; // default: none + whiteList['text-underline-position'] = true; // default: auto + whiteList['text-wrap'] = true; // default: normal + whiteList['top'] = false; // default: auto + whiteList['transform'] = false; // default: none + whiteList['transform-origin'] = false; // default: 50% 50% 0 + whiteList['transform-style'] = false; // default: flat + whiteList['transition'] = false; // default: depending on individual properties + whiteList['transition-delay'] = false; // default: 0s + whiteList['transition-duration'] = false; // default: 0s + whiteList['transition-property'] = false; // default: all + whiteList['transition-timing-function'] = false; // default: ease + whiteList['unicode-bidi'] = false; // default: normal + whiteList['vertical-align'] = false; // default: baseline + whiteList['visibility'] = false; // default: visible + whiteList['voice-balance'] = false; // default: center + whiteList['voice-duration'] = false; // default: auto + whiteList['voice-family'] = false; // default: implementation dependent + whiteList['voice-pitch'] = false; // default: medium + whiteList['voice-range'] = false; // default: medium + whiteList['voice-rate'] = false; // default: normal + whiteList['voice-stress'] = false; // default: normal + whiteList['voice-volume'] = false; // default: medium + whiteList['volume'] = false; // default: medium + whiteList['white-space'] = false; // default: normal + whiteList['widows'] = false; // default: 2 + whiteList['width'] = true; // default: auto + whiteList['will-change'] = false; // default: auto + whiteList['word-break'] = true; // default: normal + whiteList['word-spacing'] = true; // default: normal + whiteList['word-wrap'] = true; // default: normal + whiteList['wrap-flow'] = false; // default: auto + whiteList['wrap-through'] = false; // default: wrap + whiteList['writing-mode'] = false; // default: horizontal-tb + whiteList['z-index'] = false; // default: auto + + return whiteList; +} + + +/** + * 匹配到白名单上的一个属性时 + * + * @param {String} name + * @param {String} value + * @param {Object} options + * @return {String} + */ +function onAttr (name, value, options) { + // do nothing +} + +/** + * 匹配到不在白名单上的一个属性时 + * + * @param {String} name + * @param {String} value + * @param {Object} options + * @return {String} + */ +function onIgnoreAttr (name, value, options) { + // do nothing +} + +var REGEXP_URL_JAVASCRIPT = /javascript\s*\:/img; + +/** + * 过滤属性值 + * + * @param {String} name + * @param {String} value + * @return {String} + */ +function safeAttrValue(name, value) { + if (REGEXP_URL_JAVASCRIPT.test(value)) return ''; + return value; +} + + +exports.whiteList = getDefaultWhiteList(); +exports.getDefaultWhiteList = getDefaultWhiteList; +exports.onAttr = onAttr; +exports.onIgnoreAttr = onIgnoreAttr; +exports.safeAttrValue = safeAttrValue; + +},{}],8:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +var DEFAULT = require('./default'); +var FilterCSS = require('./css'); + + +/** + * XSS过滤 + * + * @param {String} css 要过滤的CSS代码 + * @param {Object} options 选项:whiteList, onAttr, onIgnoreAttr + * @return {String} + */ +function filterCSS (html, options) { + var xss = new FilterCSS(options); + return xss.process(html); +} + + +// 输出 +exports = module.exports = filterCSS; +exports.FilterCSS = FilterCSS; +for (var i in DEFAULT) exports[i] = DEFAULT[i]; + +// 在浏览器端使用 +if (typeof window !== 'undefined') { + window.filterCSS = module.exports; +} + +},{"./css":6,"./default":7}],9:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +var _ = require('./util'); + + +/** + * 解析style + * + * @param {String} css + * @param {Function} onAttr 处理属性的函数 + * 参数格式: function (sourcePosition, position, name, value, source) + * @return {String} + */ +function parseStyle (css, onAttr) { + css = _.trimRight(css); + if (css[css.length - 1] !== ';') css += ';'; + var cssLength = css.length; + var isParenthesisOpen = false; + var lastPos = 0; + var i = 0; + var retCSS = ''; + + function addNewAttr () { + // 如果没有正常的闭合圆括号,则直接忽略当前属性 + if (!isParenthesisOpen) { + var source = _.trim(css.slice(lastPos, i)); + var j = source.indexOf(':'); + if (j !== -1) { + var name = _.trim(source.slice(0, j)); + var value = _.trim(source.slice(j + 1)); + // 必须有属性名称 + if (name) { + var ret = onAttr(lastPos, retCSS.length, name, value, source); + if (ret) retCSS += ret + '; '; + } + } + } + lastPos = i + 1; + } + + for (; i < cssLength; i++) { + var c = css[i]; + if (c === '/' && css[i + 1] === '*') { + // 备注开始 + var j = css.indexOf('*/', i + 2); + // 如果没有正常的备注结束,则后面的部分全部跳过 + if (j === -1) break; + // 直接将当前位置调到备注结尾,并且初始化状态 + i = j + 1; + lastPos = i + 1; + isParenthesisOpen = false; + } else if (c === '(') { + isParenthesisOpen = true; + } else if (c === ')') { + isParenthesisOpen = false; + } else if (c === ';') { + if (isParenthesisOpen) { + // 在圆括号里面,忽略 + } else { + addNewAttr(); + } + } else if (c === '\n') { + addNewAttr(); + } + } + + return _.trim(retCSS); +} + +module.exports = parseStyle; + +},{"./util":10}],10:[function(require,module,exports){ +module.exports = { + indexOf: function (arr, item) { + var i, j; + if (Array.prototype.indexOf) { + return arr.indexOf(item); + } + for (i = 0, j = arr.length; i < j; i++) { + if (arr[i] === item) { + return i; + } + } + return -1; + }, + forEach: function (arr, fn, scope) { + var i, j; + if (Array.prototype.forEach) { + return arr.forEach(fn, scope); + } + for (i = 0, j = arr.length; i < j; i++) { + fn.call(scope, arr[i], i, arr); + } + }, + trim: function (str) { + if (String.prototype.trim) { + return str.trim(); + } + return str.replace(/(^\s*)|(\s*$)/g, ''); + }, + trimRight: function (str) { + if (String.prototype.trimRight) { + return str.trimRight(); + } + return str.replace(/(\s*$)/g, ''); + } +}; + +},{}]},{},[2]); + + +/*** EXPORTS FROM exports-loader ***/ +exports["filterXSS"] = (filterXSS); +exports["filterCSS"] = (filterCSS); + +/***/ }), +/* 19 */ +/***/ (function(module, exports) { + +var core = module.exports = { version: '2.6.12' }; +if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef + + +/***/ }), +/* 20 */ +/***/ (function(module, exports) { + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} + +module.exports = isObject; + + +/***/ }), +/* 21 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(module) {/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); +/* harmony import */ var _stubFalse_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(159); + + + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Built-in value references. */ +var Buffer = moduleExports ? _root_js__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"].Buffer : undefined; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || _stubFalse_js__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"]; + +/* harmony default export */ __webpack_exports__["a"] = (isBuffer); + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(69)(module))) + +/***/ }), +/* 22 */ +/***/ (function(module, exports) { + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +module.exports = isObjectLike; + + +/***/ }), +/* 23 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* WEBPACK VAR INJECTION */(function(global) {/* unused harmony export b64_sha1 */ +/* harmony import */ var _bosh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(498); +/* harmony import */ var _websocket__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _worker_websocket__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(500); +/* harmony import */ var _core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "b", function() { return _core__WEBPACK_IMPORTED_MODULE_3__["d"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _core__WEBPACK_IMPORTED_MODULE_3__["b"]; }); + +/*global global*/ + + + + +global.$build = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "e"].$build; +global.$iq = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "e"].$iq; +global.$msg = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "e"].$msg; +global.$pres = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "e"].$pres; +global.Strophe = _core__WEBPACK_IMPORTED_MODULE_3__[/* default */ "e"].Strophe; + +const { + b64_sha1 +} = _core__WEBPACK_IMPORTED_MODULE_3__[/* SHA1 */ "c"]; +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(12))) + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +var Symbol = __webpack_require__(49), + getRawTag = __webpack_require__(335), + objectToString = __webpack_require__(336); + +/** `Object#toString` result references. */ +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); +} + +module.exports = baseGetTag; + + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +var baseIsNative = __webpack_require__(353), + getValue = __webpack_require__(356); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +module.exports = getNative; + + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { + +var isObject = __webpack_require__(41); +module.exports = function (it) { + if (!isObject(it)) throw TypeError(it + ' is not an object!'); + return it; +}; + + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global) {var require;var require;/*! + localForage -- Offline Storage, Improved + Version 1.9.0 + https://localforage.github.io/localForage + (c) 2013-2017 Mozilla, Apache License 2.0 +*/ +(function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return require(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw (f.code="MODULE_NOT_FOUND", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted + // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. + var scriptEl = global.document.createElement('script'); + scriptEl.onreadystatechange = function () { + nextTick(); + + scriptEl.onreadystatechange = null; + scriptEl.parentNode.removeChild(scriptEl); + scriptEl = null; + }; + global.document.documentElement.appendChild(scriptEl); + }; + } else { + scheduleDrain = function () { + setTimeout(nextTick, 0); + }; + } +} + +var draining; +var queue = []; +//named nextTick for less confusing stack traces +function nextTick() { + draining = true; + var i, oldQueue; + var len = queue.length; + while (len) { + oldQueue = queue; + queue = []; + i = -1; + while (++i < len) { + oldQueue[i](); + } + len = queue.length; + } + draining = false; +} + +module.exports = immediate; +function immediate(task) { + if (queue.push(task) === 1 && !draining) { + scheduleDrain(); + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],2:[function(_dereq_,module,exports){ +'use strict'; +var immediate = _dereq_(1); + +/* istanbul ignore next */ +function INTERNAL() {} + +var handlers = {}; + +var REJECTED = ['REJECTED']; +var FULFILLED = ['FULFILLED']; +var PENDING = ['PENDING']; + +module.exports = Promise; + +function Promise(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('resolver must be a function'); + } + this.state = PENDING; + this.queue = []; + this.outcome = void 0; + if (resolver !== INTERNAL) { + safelyResolveThenable(this, resolver); + } +} + +Promise.prototype["catch"] = function (onRejected) { + return this.then(null, onRejected); +}; +Promise.prototype.then = function (onFulfilled, onRejected) { + if (typeof onFulfilled !== 'function' && this.state === FULFILLED || + typeof onRejected !== 'function' && this.state === REJECTED) { + return this; + } + var promise = new this.constructor(INTERNAL); + if (this.state !== PENDING) { + var resolver = this.state === FULFILLED ? onFulfilled : onRejected; + unwrap(promise, resolver, this.outcome); + } else { + this.queue.push(new QueueItem(promise, onFulfilled, onRejected)); + } + + return promise; +}; +function QueueItem(promise, onFulfilled, onRejected) { + this.promise = promise; + if (typeof onFulfilled === 'function') { + this.onFulfilled = onFulfilled; + this.callFulfilled = this.otherCallFulfilled; + } + if (typeof onRejected === 'function') { + this.onRejected = onRejected; + this.callRejected = this.otherCallRejected; + } +} +QueueItem.prototype.callFulfilled = function (value) { + handlers.resolve(this.promise, value); +}; +QueueItem.prototype.otherCallFulfilled = function (value) { + unwrap(this.promise, this.onFulfilled, value); +}; +QueueItem.prototype.callRejected = function (value) { + handlers.reject(this.promise, value); +}; +QueueItem.prototype.otherCallRejected = function (value) { + unwrap(this.promise, this.onRejected, value); +}; + +function unwrap(promise, func, value) { + immediate(function () { + var returnValue; + try { + returnValue = func(value); + } catch (e) { + return handlers.reject(promise, e); + } + if (returnValue === promise) { + handlers.reject(promise, new TypeError('Cannot resolve promise with itself')); + } else { + handlers.resolve(promise, returnValue); + } + }); +} + +handlers.resolve = function (self, value) { + var result = tryCatch(getThen, value); + if (result.status === 'error') { + return handlers.reject(self, result.value); + } + var thenable = result.value; + + if (thenable) { + safelyResolveThenable(self, thenable); + } else { + self.state = FULFILLED; + self.outcome = value; + var i = -1; + var len = self.queue.length; + while (++i < len) { + self.queue[i].callFulfilled(value); + } + } + return self; +}; +handlers.reject = function (self, error) { + self.state = REJECTED; + self.outcome = error; + var i = -1; + var len = self.queue.length; + while (++i < len) { + self.queue[i].callRejected(error); + } + return self; +}; + +function getThen(obj) { + // Make sure we only access the accessor once as required by the spec + var then = obj && obj.then; + if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') { + return function appyThen() { + then.apply(obj, arguments); + }; + } +} + +function safelyResolveThenable(self, thenable) { + // Either fulfill, reject or reject with error + var called = false; + function onError(value) { + if (called) { + return; + } + called = true; + handlers.reject(self, value); + } + + function onSuccess(value) { + if (called) { + return; + } + called = true; + handlers.resolve(self, value); + } + + function tryToUnwrap() { + thenable(onSuccess, onError); + } + + var result = tryCatch(tryToUnwrap); + if (result.status === 'error') { + onError(result.value); + } +} + +function tryCatch(func, value) { + var out = {}; + try { + out.value = func(value); + out.status = 'success'; + } catch (e) { + out.status = 'error'; + out.value = e; + } + return out; +} + +Promise.resolve = resolve; +function resolve(value) { + if (value instanceof this) { + return value; + } + return handlers.resolve(new this(INTERNAL), value); +} + +Promise.reject = reject; +function reject(reason) { + var promise = new this(INTERNAL); + return handlers.reject(promise, reason); +} + +Promise.all = all; +function all(iterable) { + var self = this; + if (Object.prototype.toString.call(iterable) !== '[object Array]') { + return this.reject(new TypeError('must be an array')); + } + + var len = iterable.length; + var called = false; + if (!len) { + return this.resolve([]); + } + + var values = new Array(len); + var resolved = 0; + var i = -1; + var promise = new this(INTERNAL); + + while (++i < len) { + allResolver(iterable[i], i); + } + return promise; + function allResolver(value, i) { + self.resolve(value).then(resolveFromAll, function (error) { + if (!called) { + called = true; + handlers.reject(promise, error); + } + }); + function resolveFromAll(outValue) { + values[i] = outValue; + if (++resolved === len && !called) { + called = true; + handlers.resolve(promise, values); + } + } + } +} + +Promise.race = race; +function race(iterable) { + var self = this; + if (Object.prototype.toString.call(iterable) !== '[object Array]') { + return this.reject(new TypeError('must be an array')); + } + + var len = iterable.length; + var called = false; + if (!len) { + return this.resolve([]); + } + + var i = -1; + var promise = new this(INTERNAL); + + while (++i < len) { + resolver(iterable[i]); + } + return promise; + function resolver(value) { + self.resolve(value).then(function (response) { + if (!called) { + called = true; + handlers.resolve(promise, response); + } + }, function (error) { + if (!called) { + called = true; + handlers.reject(promise, error); + } + }); + } +} + +},{"1":1}],3:[function(_dereq_,module,exports){ +(function (global){ +'use strict'; +if (typeof global.Promise !== 'function') { + global.Promise = _dereq_(2); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"2":2}],4:[function(_dereq_,module,exports){ +'use strict'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function getIDB() { + /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */ + try { + if (typeof indexedDB !== 'undefined') { + return indexedDB; + } + if (typeof webkitIndexedDB !== 'undefined') { + return webkitIndexedDB; + } + if (typeof mozIndexedDB !== 'undefined') { + return mozIndexedDB; + } + if (typeof OIndexedDB !== 'undefined') { + return OIndexedDB; + } + if (typeof msIndexedDB !== 'undefined') { + return msIndexedDB; + } + } catch (e) { + return; + } +} + +var idb = getIDB(); + +function isIndexedDBValid() { + try { + // Initialize IndexedDB; fall back to vendor-prefixed versions + // if needed. + if (!idb || !idb.open) { + return false; + } + // We mimic PouchDB here; + // + // We test for openDatabase because IE Mobile identifies itself + // as Safari. Oh the lulz... + var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform); + + var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1; + + // Safari <10.1 does not meet our requirements for IDB support + // (see: https://github.com/pouchdb/pouchdb/issues/5572). + // Safari 10.1 shipped with fetch, we can use that to detect it. + // Note: this creates issues with `window.fetch` polyfills and + // overrides; see: + // https://github.com/localForage/localForage/issues/856 + return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' && + // some outdated implementations of IDB that appear on Samsung + // and HTC Android devices <4.4 are missing IDBKeyRange + // See: https://github.com/mozilla/localForage/issues/128 + // See: https://github.com/mozilla/localForage/issues/272 + typeof IDBKeyRange !== 'undefined'; + } catch (e) { + return false; + } +} + +// Abstracts constructing a Blob object, so it also works in older +// browsers that don't support the native Blob constructor. (i.e. +// old QtWebKit versions, at least). +// Abstracts constructing a Blob object, so it also works in older +// browsers that don't support the native Blob constructor. (i.e. +// old QtWebKit versions, at least). +function createBlob(parts, properties) { + /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */ + parts = parts || []; + properties = properties || {}; + try { + return new Blob(parts, properties); + } catch (e) { + if (e.name !== 'TypeError') { + throw e; + } + var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder; + var builder = new Builder(); + for (var i = 0; i < parts.length; i += 1) { + builder.append(parts[i]); + } + return builder.getBlob(properties.type); + } +} + +// This is CommonJS because lie is an external dependency, so Rollup +// can just ignore it. +if (typeof Promise === 'undefined') { + // In the "nopromises" build this will just throw if you don't have + // a global promise object, but it would throw anyway later. + _dereq_(3); +} +var Promise$1 = Promise; + +function executeCallback(promise, callback) { + if (callback) { + promise.then(function (result) { + callback(null, result); + }, function (error) { + callback(error); + }); + } +} + +function executeTwoCallbacks(promise, callback, errorCallback) { + if (typeof callback === 'function') { + promise.then(callback); + } + + if (typeof errorCallback === 'function') { + promise["catch"](errorCallback); + } +} + +function normalizeKey(key) { + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + return key; +} + +function getCallback() { + if (arguments.length && typeof arguments[arguments.length - 1] === 'function') { + return arguments[arguments.length - 1]; + } +} + +// Some code originally from async_storage.js in +// [Gaia](https://github.com/mozilla-b2g/gaia). + +var DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support'; +var supportsBlobs = void 0; +var dbContexts = {}; +var toString = Object.prototype.toString; + +// Transaction Modes +var READ_ONLY = 'readonly'; +var READ_WRITE = 'readwrite'; + +// Transform a binary string to an array buffer, because otherwise +// weird stuff happens when you try to work with the binary string directly. +// It is known. +// From http://stackoverflow.com/questions/14967647/ (continues on next line) +// encode-decode-image-with-base64-breaks-image (2013-04-21) +function _binStringToArrayBuffer(bin) { + var length = bin.length; + var buf = new ArrayBuffer(length); + var arr = new Uint8Array(buf); + for (var i = 0; i < length; i++) { + arr[i] = bin.charCodeAt(i); + } + return buf; +} + +// +// Blobs are not supported in all versions of IndexedDB, notably +// Chrome <37 and Android <5. In those versions, storing a blob will throw. +// +// Various other blob bugs exist in Chrome v37-42 (inclusive). +// Detecting them is expensive and confusing to users, and Chrome 37-42 +// is at very low usage worldwide, so we do a hacky userAgent check instead. +// +// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120 +// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916 +// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836 +// +// Code borrowed from PouchDB. See: +// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js +// +function _checkBlobSupportWithoutCaching(idb) { + return new Promise$1(function (resolve) { + var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, READ_WRITE); + var blob = createBlob(['']); + txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key'); + + txn.onabort = function (e) { + // If the transaction aborts now its due to not being able to + // write to the database, likely due to the disk being full + e.preventDefault(); + e.stopPropagation(); + resolve(false); + }; + + txn.oncomplete = function () { + var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/); + var matchedEdge = navigator.userAgent.match(/Edge\//); + // MS Edge pretends to be Chrome 42: + // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx + resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43); + }; + })["catch"](function () { + return false; // error, so assume unsupported + }); +} + +function _checkBlobSupport(idb) { + if (typeof supportsBlobs === 'boolean') { + return Promise$1.resolve(supportsBlobs); + } + return _checkBlobSupportWithoutCaching(idb).then(function (value) { + supportsBlobs = value; + return supportsBlobs; + }); +} + +function _deferReadiness(dbInfo) { + var dbContext = dbContexts[dbInfo.name]; + + // Create a deferred object representing the current database operation. + var deferredOperation = {}; + + deferredOperation.promise = new Promise$1(function (resolve, reject) { + deferredOperation.resolve = resolve; + deferredOperation.reject = reject; + }); + + // Enqueue the deferred operation. + dbContext.deferredOperations.push(deferredOperation); + + // Chain its promise to the database readiness. + if (!dbContext.dbReady) { + dbContext.dbReady = deferredOperation.promise; + } else { + dbContext.dbReady = dbContext.dbReady.then(function () { + return deferredOperation.promise; + }); + } +} + +function _advanceReadiness(dbInfo) { + var dbContext = dbContexts[dbInfo.name]; + + // Dequeue a deferred operation. + var deferredOperation = dbContext.deferredOperations.pop(); + + // Resolve its promise (which is part of the database readiness + // chain of promises). + if (deferredOperation) { + deferredOperation.resolve(); + return deferredOperation.promise; + } +} + +function _rejectReadiness(dbInfo, err) { + var dbContext = dbContexts[dbInfo.name]; + + // Dequeue a deferred operation. + var deferredOperation = dbContext.deferredOperations.pop(); + + // Reject its promise (which is part of the database readiness + // chain of promises). + if (deferredOperation) { + deferredOperation.reject(err); + return deferredOperation.promise; + } +} + +function _getConnection(dbInfo, upgradeNeeded) { + return new Promise$1(function (resolve, reject) { + dbContexts[dbInfo.name] = dbContexts[dbInfo.name] || createDbContext(); + + if (dbInfo.db) { + if (upgradeNeeded) { + _deferReadiness(dbInfo); + dbInfo.db.close(); + } else { + return resolve(dbInfo.db); + } + } + + var dbArgs = [dbInfo.name]; + + if (upgradeNeeded) { + dbArgs.push(dbInfo.version); + } + + var openreq = idb.open.apply(idb, dbArgs); + + if (upgradeNeeded) { + openreq.onupgradeneeded = function (e) { + var db = openreq.result; + try { + db.createObjectStore(dbInfo.storeName); + if (e.oldVersion <= 1) { + // Added when support for blob shims was added + db.createObjectStore(DETECT_BLOB_SUPPORT_STORE); + } + } catch (ex) { + if (ex.name === 'ConstraintError') { + console.warn('The database "' + dbInfo.name + '"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage "' + dbInfo.storeName + '" already exists.'); + } else { + throw ex; + } + } + }; + } + + openreq.onerror = function (e) { + e.preventDefault(); + reject(openreq.error); + }; + + openreq.onsuccess = function () { + resolve(openreq.result); + _advanceReadiness(dbInfo); + }; + }); +} + +function _getOriginalConnection(dbInfo) { + return _getConnection(dbInfo, false); +} + +function _getUpgradedConnection(dbInfo) { + return _getConnection(dbInfo, true); +} + +function _isUpgradeNeeded(dbInfo, defaultVersion) { + if (!dbInfo.db) { + return true; + } + + var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName); + var isDowngrade = dbInfo.version < dbInfo.db.version; + var isUpgrade = dbInfo.version > dbInfo.db.version; + + if (isDowngrade) { + // If the version is not the default one + // then warn for impossible downgrade. + if (dbInfo.version !== defaultVersion) { + console.warn('The database "' + dbInfo.name + '"' + " can't be downgraded from version " + dbInfo.db.version + ' to version ' + dbInfo.version + '.'); + } + // Align the versions to prevent errors. + dbInfo.version = dbInfo.db.version; + } + + if (isUpgrade || isNewStore) { + // If the store is new then increment the version (if needed). + // This will trigger an "upgradeneeded" event which is required + // for creating a store. + if (isNewStore) { + var incVersion = dbInfo.db.version + 1; + if (incVersion > dbInfo.version) { + dbInfo.version = incVersion; + } + } + + return true; + } + + return false; +} + +// encode a blob for indexeddb engines that don't support blobs +function _encodeBlob(blob) { + return new Promise$1(function (resolve, reject) { + var reader = new FileReader(); + reader.onerror = reject; + reader.onloadend = function (e) { + var base64 = btoa(e.target.result || ''); + resolve({ + __local_forage_encoded_blob: true, + data: base64, + type: blob.type + }); + }; + reader.readAsBinaryString(blob); + }); +} + +// decode an encoded blob +function _decodeBlob(encodedBlob) { + var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data)); + return createBlob([arrayBuff], { type: encodedBlob.type }); +} + +// is this one of our fancy encoded blobs? +function _isEncodedBlob(value) { + return value && value.__local_forage_encoded_blob; +} + +// Specialize the default `ready()` function by making it dependent +// on the current database operations. Thus, the driver will be actually +// ready when it's been initialized (default) *and* there are no pending +// operations on the database (initiated by some other instances). +function _fullyReady(callback) { + var self = this; + + var promise = self._initReady().then(function () { + var dbContext = dbContexts[self._dbInfo.name]; + + if (dbContext && dbContext.dbReady) { + return dbContext.dbReady; + } + }); + + executeTwoCallbacks(promise, callback, callback); + return promise; +} + +// Try to establish a new db connection to replace the +// current one which is broken (i.e. experiencing +// InvalidStateError while creating a transaction). +function _tryReconnect(dbInfo) { + _deferReadiness(dbInfo); + + var dbContext = dbContexts[dbInfo.name]; + var forages = dbContext.forages; + + for (var i = 0; i < forages.length; i++) { + var forage = forages[i]; + if (forage._dbInfo.db) { + forage._dbInfo.db.close(); + forage._dbInfo.db = null; + } + } + dbInfo.db = null; + + return _getOriginalConnection(dbInfo).then(function (db) { + dbInfo.db = db; + if (_isUpgradeNeeded(dbInfo)) { + // Reopen the database for upgrading. + return _getUpgradedConnection(dbInfo); + } + return db; + }).then(function (db) { + // store the latest db reference + // in case the db was upgraded + dbInfo.db = dbContext.db = db; + for (var i = 0; i < forages.length; i++) { + forages[i]._dbInfo.db = db; + } + })["catch"](function (err) { + _rejectReadiness(dbInfo, err); + throw err; + }); +} + +// FF doesn't like Promises (micro-tasks) and IDDB store operations, +// so we have to do it with callbacks +function createTransaction(dbInfo, mode, callback, retries) { + if (retries === undefined) { + retries = 1; + } + + try { + var tx = dbInfo.db.transaction(dbInfo.storeName, mode); + callback(null, tx); + } catch (err) { + if (retries > 0 && (!dbInfo.db || err.name === 'InvalidStateError' || err.name === 'NotFoundError')) { + return Promise$1.resolve().then(function () { + if (!dbInfo.db || err.name === 'NotFoundError' && !dbInfo.db.objectStoreNames.contains(dbInfo.storeName) && dbInfo.version <= dbInfo.db.version) { + // increase the db version, to create the new ObjectStore + if (dbInfo.db) { + dbInfo.version = dbInfo.db.version + 1; + } + // Reopen the database for upgrading. + return _getUpgradedConnection(dbInfo); + } + }).then(function () { + return _tryReconnect(dbInfo).then(function () { + createTransaction(dbInfo, mode, callback, retries - 1); + }); + })["catch"](callback); + } + + callback(err); + } +} + +function createDbContext() { + return { + // Running localForages sharing a database. + forages: [], + // Shared database. + db: null, + // Database readiness (promise). + dbReady: null, + // Deferred operations on the database. + deferredOperations: [] + }; +} + +// Open the IndexedDB database (automatically creates one if one didn't +// previously exist), using any options set in the config. +function _initStorage(options) { + var self = this; + var dbInfo = { + db: null + }; + + if (options) { + for (var i in options) { + dbInfo[i] = options[i]; + } + } + + // Get the current context of the database; + var dbContext = dbContexts[dbInfo.name]; + + // ...or create a new context. + if (!dbContext) { + dbContext = createDbContext(); + // Register the new context in the global container. + dbContexts[dbInfo.name] = dbContext; + } + + // Register itself as a running localForage in the current context. + dbContext.forages.push(self); + + // Replace the default `ready()` function with the specialized one. + if (!self._initReady) { + self._initReady = self.ready; + self.ready = _fullyReady; + } + + // Create an array of initialization states of the related localForages. + var initPromises = []; + + function ignoreErrors() { + // Don't handle errors here, + // just makes sure related localForages aren't pending. + return Promise$1.resolve(); + } + + for (var j = 0; j < dbContext.forages.length; j++) { + var forage = dbContext.forages[j]; + if (forage !== self) { + // Don't wait for itself... + initPromises.push(forage._initReady()["catch"](ignoreErrors)); + } + } + + // Take a snapshot of the related localForages. + var forages = dbContext.forages.slice(0); + + // Initialize the connection process only when + // all the related localForages aren't pending. + return Promise$1.all(initPromises).then(function () { + dbInfo.db = dbContext.db; + // Get the connection or open a new one without upgrade. + return _getOriginalConnection(dbInfo); + }).then(function (db) { + dbInfo.db = db; + if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) { + // Reopen the database for upgrading. + return _getUpgradedConnection(dbInfo); + } + return db; + }).then(function (db) { + dbInfo.db = dbContext.db = db; + self._dbInfo = dbInfo; + // Share the final connection amongst related localForages. + for (var k = 0; k < forages.length; k++) { + var forage = forages[k]; + if (forage !== self) { + // Self is already up-to-date. + forage._dbInfo.db = dbInfo.db; + forage._dbInfo.version = dbInfo.version; + } + } + }); +} + +function getItem(key, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + var req = store.get(key); + + req.onsuccess = function () { + var value = req.result; + if (value === undefined) { + value = null; + } + if (_isEncodedBlob(value)) { + value = _decodeBlob(value); + } + resolve(value); + }; + + req.onerror = function () { + reject(req.error); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Iterate over all items stored in database. +function iterate(iterator, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + var req = store.openCursor(); + var iterationNumber = 1; + + req.onsuccess = function () { + var cursor = req.result; + + if (cursor) { + var value = cursor.value; + if (_isEncodedBlob(value)) { + value = _decodeBlob(value); + } + var result = iterator(value, cursor.key, iterationNumber++); + + // when the iterator callback returns any + // (non-`undefined`) value, then we stop + // the iteration immediately + if (result !== void 0) { + resolve(result); + } else { + cursor["continue"](); + } + } else { + resolve(); + } + }; + + req.onerror = function () { + reject(req.error); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + + return promise; +} + +function setItem(key, value, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = new Promise$1(function (resolve, reject) { + var dbInfo; + self.ready().then(function () { + dbInfo = self._dbInfo; + if (toString.call(value) === '[object Blob]') { + return _checkBlobSupport(dbInfo.db).then(function (blobSupport) { + if (blobSupport) { + return value; + } + return _encodeBlob(value); + }); + } + return value; + }).then(function (value) { + createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + + // The reason we don't _save_ null is because IE 10 does + // not support saving the `null` type in IndexedDB. How + // ironic, given the bug below! + // See: https://github.com/mozilla/localForage/issues/161 + if (value === null) { + value = undefined; + } + + var req = store.put(value, key); + + transaction.oncomplete = function () { + // Cast to undefined so the value passed to + // callback/promise is the same as what one would get out + // of `getItem()` later. This leads to some weirdness + // (setItem('foo', undefined) will return `null`), but + // it's not my fault localStorage is our baseline and that + // it's weird. + if (value === undefined) { + value = null; + } + + resolve(value); + }; + transaction.onabort = transaction.onerror = function () { + var err = req.error ? req.error : req.transaction.error; + reject(err); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function removeItem(key, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + // We use a Grunt task to make this safe for IE and some + // versions of Android (including those used by Cordova). + // Normally IE won't like `.delete()` and will insist on + // using `['delete']()`, but we have a build step that + // fixes this for us now. + var req = store["delete"](key); + transaction.oncomplete = function () { + resolve(); + }; + + transaction.onerror = function () { + reject(req.error); + }; + + // The request will be also be aborted if we've exceeded our storage + // space. + transaction.onabort = function () { + var err = req.error ? req.error : req.transaction.error; + reject(err); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function clear(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + createTransaction(self._dbInfo, READ_WRITE, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + var req = store.clear(); + + transaction.oncomplete = function () { + resolve(); + }; + + transaction.onabort = transaction.onerror = function () { + var err = req.error ? req.error : req.transaction.error; + reject(err); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function length(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + var req = store.count(); + + req.onsuccess = function () { + resolve(req.result); + }; + + req.onerror = function () { + reject(req.error); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function key(n, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + if (n < 0) { + resolve(null); + + return; + } + + self.ready().then(function () { + createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + var advanced = false; + var req = store.openKeyCursor(); + + req.onsuccess = function () { + var cursor = req.result; + if (!cursor) { + // this means there weren't enough keys + resolve(null); + + return; + } + + if (n === 0) { + // We have the first key, return it if that's what they + // wanted. + resolve(cursor.key); + } else { + if (!advanced) { + // Otherwise, ask the cursor to skip ahead n + // records. + advanced = true; + cursor.advance(n); + } else { + // When we get here, we've got the nth key. + resolve(cursor.key); + } + } + }; + + req.onerror = function () { + reject(req.error); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function keys(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + createTransaction(self._dbInfo, READ_ONLY, function (err, transaction) { + if (err) { + return reject(err); + } + + try { + var store = transaction.objectStore(self._dbInfo.storeName); + var req = store.openKeyCursor(); + var keys = []; + + req.onsuccess = function () { + var cursor = req.result; + + if (!cursor) { + resolve(keys); + return; + } + + keys.push(cursor.key); + cursor["continue"](); + }; + + req.onerror = function () { + reject(req.error); + }; + } catch (e) { + reject(e); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function dropInstance(options, callback) { + callback = getCallback.apply(this, arguments); + + var currentConfig = this.config(); + options = typeof options !== 'function' && options || {}; + if (!options.name) { + options.name = options.name || currentConfig.name; + options.storeName = options.storeName || currentConfig.storeName; + } + + var self = this; + var promise; + if (!options.name) { + promise = Promise$1.reject('Invalid arguments'); + } else { + var isCurrentDb = options.name === currentConfig.name && self._dbInfo.db; + + var dbPromise = isCurrentDb ? Promise$1.resolve(self._dbInfo.db) : _getOriginalConnection(options).then(function (db) { + var dbContext = dbContexts[options.name]; + var forages = dbContext.forages; + dbContext.db = db; + for (var i = 0; i < forages.length; i++) { + forages[i]._dbInfo.db = db; + } + return db; + }); + + if (!options.storeName) { + promise = dbPromise.then(function (db) { + _deferReadiness(options); + + var dbContext = dbContexts[options.name]; + var forages = dbContext.forages; + + db.close(); + for (var i = 0; i < forages.length; i++) { + var forage = forages[i]; + forage._dbInfo.db = null; + } + + var dropDBPromise = new Promise$1(function (resolve, reject) { + var req = idb.deleteDatabase(options.name); + + req.onerror = req.onblocked = function (err) { + var db = req.result; + if (db) { + db.close(); + } + reject(err); + }; + + req.onsuccess = function () { + var db = req.result; + if (db) { + db.close(); + } + resolve(db); + }; + }); + + return dropDBPromise.then(function (db) { + dbContext.db = db; + for (var i = 0; i < forages.length; i++) { + var _forage = forages[i]; + _advanceReadiness(_forage._dbInfo); + } + })["catch"](function (err) { + (_rejectReadiness(options, err) || Promise$1.resolve())["catch"](function () {}); + throw err; + }); + }); + } else { + promise = dbPromise.then(function (db) { + if (!db.objectStoreNames.contains(options.storeName)) { + return; + } + + var newVersion = db.version + 1; + + _deferReadiness(options); + + var dbContext = dbContexts[options.name]; + var forages = dbContext.forages; + + db.close(); + for (var i = 0; i < forages.length; i++) { + var forage = forages[i]; + forage._dbInfo.db = null; + forage._dbInfo.version = newVersion; + } + + var dropObjectPromise = new Promise$1(function (resolve, reject) { + var req = idb.open(options.name, newVersion); + + req.onerror = function (err) { + var db = req.result; + db.close(); + reject(err); + }; + + req.onupgradeneeded = function () { + var db = req.result; + db.deleteObjectStore(options.storeName); + }; + + req.onsuccess = function () { + var db = req.result; + db.close(); + resolve(db); + }; + }); + + return dropObjectPromise.then(function (db) { + dbContext.db = db; + for (var j = 0; j < forages.length; j++) { + var _forage2 = forages[j]; + _forage2._dbInfo.db = db; + _advanceReadiness(_forage2._dbInfo); + } + })["catch"](function (err) { + (_rejectReadiness(options, err) || Promise$1.resolve())["catch"](function () {}); + throw err; + }); + }); + } + } + + executeCallback(promise, callback); + return promise; +} + +var asyncStorage = { + _driver: 'asyncStorage', + _initStorage: _initStorage, + _support: isIndexedDBValid(), + iterate: iterate, + getItem: getItem, + setItem: setItem, + removeItem: removeItem, + clear: clear, + length: length, + key: key, + keys: keys, + dropInstance: dropInstance +}; + +function isWebSQLValid() { + return typeof openDatabase === 'function'; +} + +// Sadly, the best way to save binary data in WebSQL/localStorage is serializing +// it to Base64, so this is how we store it to prevent very strange errors with less +// verbose ways of binary <-> string data storage. +var BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +var BLOB_TYPE_PREFIX = '~~local_forage_type~'; +var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/; + +var SERIALIZED_MARKER = '__lfsc__:'; +var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; + +// OMG the serializations! +var TYPE_ARRAYBUFFER = 'arbf'; +var TYPE_BLOB = 'blob'; +var TYPE_INT8ARRAY = 'si08'; +var TYPE_UINT8ARRAY = 'ui08'; +var TYPE_UINT8CLAMPEDARRAY = 'uic8'; +var TYPE_INT16ARRAY = 'si16'; +var TYPE_INT32ARRAY = 'si32'; +var TYPE_UINT16ARRAY = 'ur16'; +var TYPE_UINT32ARRAY = 'ui32'; +var TYPE_FLOAT32ARRAY = 'fl32'; +var TYPE_FLOAT64ARRAY = 'fl64'; +var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; + +var toString$1 = Object.prototype.toString; + +function stringToBuffer(serializedString) { + // Fill the string into a ArrayBuffer. + var bufferLength = serializedString.length * 0.75; + var len = serializedString.length; + var i; + var p = 0; + var encoded1, encoded2, encoded3, encoded4; + + if (serializedString[serializedString.length - 1] === '=') { + bufferLength--; + if (serializedString[serializedString.length - 2] === '=') { + bufferLength--; + } + } + + var buffer = new ArrayBuffer(bufferLength); + var bytes = new Uint8Array(buffer); + + for (i = 0; i < len; i += 4) { + encoded1 = BASE_CHARS.indexOf(serializedString[i]); + encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]); + encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]); + encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]); + + /*jslint bitwise: true */ + bytes[p++] = encoded1 << 2 | encoded2 >> 4; + bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; + bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; + } + return buffer; +} + +// Converts a buffer to a string to store, serialized, in the backend +// storage library. +function bufferToString(buffer) { + // base64-arraybuffer + var bytes = new Uint8Array(buffer); + var base64String = ''; + var i; + + for (i = 0; i < bytes.length; i += 3) { + /*jslint bitwise: true */ + base64String += BASE_CHARS[bytes[i] >> 2]; + base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; + base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; + base64String += BASE_CHARS[bytes[i + 2] & 63]; + } + + if (bytes.length % 3 === 2) { + base64String = base64String.substring(0, base64String.length - 1) + '='; + } else if (bytes.length % 3 === 1) { + base64String = base64String.substring(0, base64String.length - 2) + '=='; + } + + return base64String; +} + +// Serialize a value, afterwards executing a callback (which usually +// instructs the `setItem()` callback/promise to be executed). This is how +// we store binary data with localStorage. +function serialize(value, callback) { + var valueType = ''; + if (value) { + valueType = toString$1.call(value); + } + + // Cannot use `value instanceof ArrayBuffer` or such here, as these + // checks fail when running the tests using casper.js... + // + // TODO: See why those tests fail and use a better solution. + if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) { + // Convert binary arrays to a string and prefix the string with + // a special marker. + var buffer; + var marker = SERIALIZED_MARKER; + + if (value instanceof ArrayBuffer) { + buffer = value; + marker += TYPE_ARRAYBUFFER; + } else { + buffer = value.buffer; + + if (valueType === '[object Int8Array]') { + marker += TYPE_INT8ARRAY; + } else if (valueType === '[object Uint8Array]') { + marker += TYPE_UINT8ARRAY; + } else if (valueType === '[object Uint8ClampedArray]') { + marker += TYPE_UINT8CLAMPEDARRAY; + } else if (valueType === '[object Int16Array]') { + marker += TYPE_INT16ARRAY; + } else if (valueType === '[object Uint16Array]') { + marker += TYPE_UINT16ARRAY; + } else if (valueType === '[object Int32Array]') { + marker += TYPE_INT32ARRAY; + } else if (valueType === '[object Uint32Array]') { + marker += TYPE_UINT32ARRAY; + } else if (valueType === '[object Float32Array]') { + marker += TYPE_FLOAT32ARRAY; + } else if (valueType === '[object Float64Array]') { + marker += TYPE_FLOAT64ARRAY; + } else { + callback(new Error('Failed to get type for BinaryArray')); + } + } + + callback(marker + bufferToString(buffer)); + } else if (valueType === '[object Blob]') { + // Conver the blob to a binaryArray and then to a string. + var fileReader = new FileReader(); + + fileReader.onload = function () { + // Backwards-compatible prefix for the blob type. + var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result); + + callback(SERIALIZED_MARKER + TYPE_BLOB + str); + }; + + fileReader.readAsArrayBuffer(value); + } else { + try { + callback(JSON.stringify(value)); + } catch (e) { + console.error("Couldn't convert value into a JSON string: ", value); + + callback(null, e); + } + } +} + +// Deserialize data we've inserted into a value column/field. We place +// special markers into our strings to mark them as encoded; this isn't +// as nice as a meta field, but it's the only sane thing we can do whilst +// keeping localStorage support intact. +// +// Oftentimes this will just deserialize JSON content, but if we have a +// special marker (SERIALIZED_MARKER, defined above), we will extract +// some kind of arraybuffer/binary data/typed array out of the string. +function deserialize(value) { + // If we haven't marked this string as being specially serialized (i.e. + // something other than serialized JSON), we can just return it and be + // done with it. + if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { + return JSON.parse(value); + } + + // The following code deals with deserializing some kind of Blob or + // TypedArray. First we separate out the type of data we're dealing + // with from the data itself. + var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); + var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); + + var blobType; + // Backwards-compatible blob type serialization strategy. + // DBs created with older versions of localForage will simply not have the blob type. + if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) { + var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX); + blobType = matcher[1]; + serializedString = serializedString.substring(matcher[0].length); + } + var buffer = stringToBuffer(serializedString); + + // Return the right type based on the code/type set during + // serialization. + switch (type) { + case TYPE_ARRAYBUFFER: + return buffer; + case TYPE_BLOB: + return createBlob([buffer], { type: blobType }); + case TYPE_INT8ARRAY: + return new Int8Array(buffer); + case TYPE_UINT8ARRAY: + return new Uint8Array(buffer); + case TYPE_UINT8CLAMPEDARRAY: + return new Uint8ClampedArray(buffer); + case TYPE_INT16ARRAY: + return new Int16Array(buffer); + case TYPE_UINT16ARRAY: + return new Uint16Array(buffer); + case TYPE_INT32ARRAY: + return new Int32Array(buffer); + case TYPE_UINT32ARRAY: + return new Uint32Array(buffer); + case TYPE_FLOAT32ARRAY: + return new Float32Array(buffer); + case TYPE_FLOAT64ARRAY: + return new Float64Array(buffer); + default: + throw new Error('Unkown type: ' + type); + } +} + +var localforageSerializer = { + serialize: serialize, + deserialize: deserialize, + stringToBuffer: stringToBuffer, + bufferToString: bufferToString +}; + +/* + * Includes code from: + * + * base64-arraybuffer + * https://github.com/niklasvh/base64-arraybuffer + * + * Copyright (c) 2012 Niklas von Hertzen + * Licensed under the MIT license. + */ + +function createDbTable(t, dbInfo, callback, errorCallback) { + t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' ' + '(id INTEGER PRIMARY KEY, key unique, value)', [], callback, errorCallback); +} + +// Open the WebSQL database (automatically creates one if one didn't +// previously exist), using any options set in the config. +function _initStorage$1(options) { + var self = this; + var dbInfo = { + db: null + }; + + if (options) { + for (var i in options) { + dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i]; + } + } + + var dbInfoPromise = new Promise$1(function (resolve, reject) { + // Open the database; the openDatabase API will automatically + // create it for us if it doesn't exist. + try { + dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size); + } catch (e) { + return reject(e); + } + + // Create our key/value table if it doesn't exist. + dbInfo.db.transaction(function (t) { + createDbTable(t, dbInfo, function () { + self._dbInfo = dbInfo; + resolve(); + }, function (t, error) { + reject(error); + }); + }, reject); + }); + + dbInfo.serializer = localforageSerializer; + return dbInfoPromise; +} + +function tryExecuteSql(t, dbInfo, sqlStatement, args, callback, errorCallback) { + t.executeSql(sqlStatement, args, callback, function (t, error) { + if (error.code === error.SYNTAX_ERR) { + t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name = ?", [dbInfo.storeName], function (t, results) { + if (!results.rows.length) { + // if the table is missing (was deleted) + // re-create it table and retry + createDbTable(t, dbInfo, function () { + t.executeSql(sqlStatement, args, callback, errorCallback); + }, errorCallback); + } else { + errorCallback(t, error); + } + }, errorCallback); + } else { + errorCallback(t, error); + } + }, errorCallback); +} + +function getItem$1(key, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) { + var result = results.rows.length ? results.rows.item(0).value : null; + + // Check to see if this is serialized content we need to + // unpack. + if (result) { + result = dbInfo.serializer.deserialize(result); + } + + resolve(result); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function iterate$1(iterator, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + + dbInfo.db.transaction(function (t) { + tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName, [], function (t, results) { + var rows = results.rows; + var length = rows.length; + + for (var i = 0; i < length; i++) { + var item = rows.item(i); + var result = item.value; + + // Check to see if this is serialized content + // we need to unpack. + if (result) { + result = dbInfo.serializer.deserialize(result); + } + + result = iterator(result, item.key, i + 1); + + // void(0) prevents problems with redefinition + // of `undefined`. + if (result !== void 0) { + resolve(result); + return; + } + } + + resolve(); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function _setItem(key, value, callback, retriesLeft) { + var self = this; + + key = normalizeKey(key); + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + // The localStorage API doesn't return undefined values in an + // "expected" way, so undefined is always cast to null in all + // drivers. See: https://github.com/mozilla/localForage/pull/42 + if (value === undefined) { + value = null; + } + + // Save the original value to pass to the callback. + var originalValue = value; + + var dbInfo = self._dbInfo; + dbInfo.serializer.serialize(value, function (value, error) { + if (error) { + reject(error); + } else { + dbInfo.db.transaction(function (t) { + tryExecuteSql(t, dbInfo, 'INSERT OR REPLACE INTO ' + dbInfo.storeName + ' ' + '(key, value) VALUES (?, ?)', [key, value], function () { + resolve(originalValue); + }, function (t, error) { + reject(error); + }); + }, function (sqlError) { + // The transaction failed; check + // to see if it's a quota error. + if (sqlError.code === sqlError.QUOTA_ERR) { + // We reject the callback outright for now, but + // it's worth trying to re-run the transaction. + // Even if the user accepts the prompt to use + // more storage on Safari, this error will + // be called. + // + // Try to re-run the transaction. + if (retriesLeft > 0) { + resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1])); + return; + } + reject(sqlError); + } + }); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function setItem$1(key, value, callback) { + return _setItem.apply(this, [key, value, callback, 1]); +} + +function removeItem$1(key, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () { + resolve(); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Deletes every item in the table. +// TODO: Find out if this resets the AUTO_INCREMENT number. +function clear$1(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName, [], function () { + resolve(); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Does a simple `COUNT(key)` to get the number of items stored in +// localForage. +function length$1(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + // Ahhh, SQL makes this one soooooo easy. + tryExecuteSql(t, dbInfo, 'SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) { + var result = results.rows.item(0).c; + resolve(result); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Return the key located at key index X; essentially gets the key from a +// `WHERE id = ?`. This is the most efficient way I can think to implement +// this rarely-used (in my experience) part of the API, but it can seem +// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so +// the ID of each key will change every time it's updated. Perhaps a stored +// procedure for the `setItem()` SQL would solve this problem? +// TODO: Don't change ID on `setItem()`. +function key$1(n, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) { + var result = results.rows.length ? results.rows.item(0).key : null; + resolve(result); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function keys$1(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName, [], function (t, results) { + var keys = []; + + for (var i = 0; i < results.rows.length; i++) { + keys.push(results.rows.item(i).key); + } + + resolve(keys); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// https://www.w3.org/TR/webdatabase/#databases +// > There is no way to enumerate or delete the databases available for an origin from this API. +function getAllStoreNames(db) { + return new Promise$1(function (resolve, reject) { + db.transaction(function (t) { + t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'", [], function (t, results) { + var storeNames = []; + + for (var i = 0; i < results.rows.length; i++) { + storeNames.push(results.rows.item(i).name); + } + + resolve({ + db: db, + storeNames: storeNames + }); + }, function (t, error) { + reject(error); + }); + }, function (sqlError) { + reject(sqlError); + }); + }); +} + +function dropInstance$1(options, callback) { + callback = getCallback.apply(this, arguments); + + var currentConfig = this.config(); + options = typeof options !== 'function' && options || {}; + if (!options.name) { + options.name = options.name || currentConfig.name; + options.storeName = options.storeName || currentConfig.storeName; + } + + var self = this; + var promise; + if (!options.name) { + promise = Promise$1.reject('Invalid arguments'); + } else { + promise = new Promise$1(function (resolve) { + var db; + if (options.name === currentConfig.name) { + // use the db reference of the current instance + db = self._dbInfo.db; + } else { + db = openDatabase(options.name, '', '', 0); + } + + if (!options.storeName) { + // drop all database tables + resolve(getAllStoreNames(db)); + } else { + resolve({ + db: db, + storeNames: [options.storeName] + }); + } + }).then(function (operationInfo) { + return new Promise$1(function (resolve, reject) { + operationInfo.db.transaction(function (t) { + function dropTable(storeName) { + return new Promise$1(function (resolve, reject) { + t.executeSql('DROP TABLE IF EXISTS ' + storeName, [], function () { + resolve(); + }, function (t, error) { + reject(error); + }); + }); + } + + var operations = []; + for (var i = 0, len = operationInfo.storeNames.length; i < len; i++) { + operations.push(dropTable(operationInfo.storeNames[i])); + } + + Promise$1.all(operations).then(function () { + resolve(); + })["catch"](function (e) { + reject(e); + }); + }, function (sqlError) { + reject(sqlError); + }); + }); + }); + } + + executeCallback(promise, callback); + return promise; +} + +var webSQLStorage = { + _driver: 'webSQLStorage', + _initStorage: _initStorage$1, + _support: isWebSQLValid(), + iterate: iterate$1, + getItem: getItem$1, + setItem: setItem$1, + removeItem: removeItem$1, + clear: clear$1, + length: length$1, + key: key$1, + keys: keys$1, + dropInstance: dropInstance$1 +}; + +function isLocalStorageValid() { + try { + return typeof localStorage !== 'undefined' && 'setItem' in localStorage && + // in IE8 typeof localStorage.setItem === 'object' + !!localStorage.setItem; + } catch (e) { + return false; + } +} + +function _getKeyPrefix(options, defaultConfig) { + var keyPrefix = options.name + '/'; + + if (options.storeName !== defaultConfig.storeName) { + keyPrefix += options.storeName + '/'; + } + return keyPrefix; +} + +// Check if localStorage throws when saving an item +function checkIfLocalStorageThrows() { + var localStorageTestKey = '_localforage_support_test'; + + try { + localStorage.setItem(localStorageTestKey, true); + localStorage.removeItem(localStorageTestKey); + + return false; + } catch (e) { + return true; + } +} + +// Check if localStorage is usable and allows to save an item +// This method checks if localStorage is usable in Safari Private Browsing +// mode, or in any other case where the available quota for localStorage +// is 0 and there wasn't any saved items yet. +function _isLocalStorageUsable() { + return !checkIfLocalStorageThrows() || localStorage.length > 0; +} + +// Config the localStorage backend, using options set in the config. +function _initStorage$2(options) { + var self = this; + var dbInfo = {}; + if (options) { + for (var i in options) { + dbInfo[i] = options[i]; + } + } + + dbInfo.keyPrefix = _getKeyPrefix(options, self._defaultConfig); + + if (!_isLocalStorageUsable()) { + return Promise$1.reject(); + } + + self._dbInfo = dbInfo; + dbInfo.serializer = localforageSerializer; + + return Promise$1.resolve(); +} + +// Remove all keys from the datastore, effectively destroying all data in +// the app's key/value store! +function clear$2(callback) { + var self = this; + var promise = self.ready().then(function () { + var keyPrefix = self._dbInfo.keyPrefix; + + for (var i = localStorage.length - 1; i >= 0; i--) { + var key = localStorage.key(i); + + if (key.indexOf(keyPrefix) === 0) { + localStorage.removeItem(key); + } + } + }); + + executeCallback(promise, callback); + return promise; +} + +// Retrieve an item from the store. Unlike the original async_storage +// library in Gaia, we don't modify return values at all. If a key's value +// is `undefined`, we pass that value to the callback function. +function getItem$2(key, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var result = localStorage.getItem(dbInfo.keyPrefix + key); + + // If a result was found, parse it from the serialized + // string into a JS object. If result isn't truthy, the key + // is likely undefined and we'll pass it straight to the + // callback. + if (result) { + result = dbInfo.serializer.deserialize(result); + } + + return result; + }); + + executeCallback(promise, callback); + return promise; +} + +// Iterate over all items in the store. +function iterate$2(iterator, callback) { + var self = this; + + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var keyPrefix = dbInfo.keyPrefix; + var keyPrefixLength = keyPrefix.length; + var length = localStorage.length; + + // We use a dedicated iterator instead of the `i` variable below + // so other keys we fetch in localStorage aren't counted in + // the `iterationNumber` argument passed to the `iterate()` + // callback. + // + // See: github.com/mozilla/localForage/pull/435#discussion_r38061530 + var iterationNumber = 1; + + for (var i = 0; i < length; i++) { + var key = localStorage.key(i); + if (key.indexOf(keyPrefix) !== 0) { + continue; + } + var value = localStorage.getItem(key); + + // If a result was found, parse it from the serialized + // string into a JS object. If result isn't truthy, the + // key is likely undefined and we'll pass it straight + // to the iterator. + if (value) { + value = dbInfo.serializer.deserialize(value); + } + + value = iterator(value, key.substring(keyPrefixLength), iterationNumber++); + + if (value !== void 0) { + return value; + } + } + }); + + executeCallback(promise, callback); + return promise; +} + +// Same as localStorage's key() method, except takes a callback. +function key$2(n, callback) { + var self = this; + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var result; + try { + result = localStorage.key(n); + } catch (error) { + result = null; + } + + // Remove the prefix from the key, if a key is found. + if (result) { + result = result.substring(dbInfo.keyPrefix.length); + } + + return result; + }); + + executeCallback(promise, callback); + return promise; +} + +function keys$2(callback) { + var self = this; + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var length = localStorage.length; + var keys = []; + + for (var i = 0; i < length; i++) { + var itemKey = localStorage.key(i); + if (itemKey.indexOf(dbInfo.keyPrefix) === 0) { + keys.push(itemKey.substring(dbInfo.keyPrefix.length)); + } + } + + return keys; + }); + + executeCallback(promise, callback); + return promise; +} + +// Supply the number of keys in the datastore to the callback function. +function length$2(callback) { + var self = this; + var promise = self.keys().then(function (keys) { + return keys.length; + }); + + executeCallback(promise, callback); + return promise; +} + +// Remove an item from the store, nice and simple. +function removeItem$2(key, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + localStorage.removeItem(dbInfo.keyPrefix + key); + }); + + executeCallback(promise, callback); + return promise; +} + +// Set a key's value and run an optional callback once the value is set. +// Unlike Gaia's implementation, the callback function is passed the value, +// in case you want to operate on that value only after you're sure it +// saved, or something like that. +function setItem$2(key, value, callback) { + var self = this; + + key = normalizeKey(key); + + var promise = self.ready().then(function () { + // Convert undefined values to null. + // https://github.com/mozilla/localForage/pull/42 + if (value === undefined) { + value = null; + } + + // Save the original value to pass to the callback. + var originalValue = value; + + return new Promise$1(function (resolve, reject) { + var dbInfo = self._dbInfo; + dbInfo.serializer.serialize(value, function (value, error) { + if (error) { + reject(error); + } else { + try { + localStorage.setItem(dbInfo.keyPrefix + key, value); + resolve(originalValue); + } catch (e) { + // localStorage capacity exceeded. + // TODO: Make this a specific error/event. + if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { + reject(e); + } + reject(e); + } + } + }); + }); + }); + + executeCallback(promise, callback); + return promise; +} + +function dropInstance$2(options, callback) { + callback = getCallback.apply(this, arguments); + + options = typeof options !== 'function' && options || {}; + if (!options.name) { + var currentConfig = this.config(); + options.name = options.name || currentConfig.name; + options.storeName = options.storeName || currentConfig.storeName; + } + + var self = this; + var promise; + if (!options.name) { + promise = Promise$1.reject('Invalid arguments'); + } else { + promise = new Promise$1(function (resolve) { + if (!options.storeName) { + resolve(options.name + '/'); + } else { + resolve(_getKeyPrefix(options, self._defaultConfig)); + } + }).then(function (keyPrefix) { + for (var i = localStorage.length - 1; i >= 0; i--) { + var key = localStorage.key(i); + + if (key.indexOf(keyPrefix) === 0) { + localStorage.removeItem(key); + } + } + }); + } + + executeCallback(promise, callback); + return promise; +} + +var localStorageWrapper = { + _driver: 'localStorageWrapper', + _initStorage: _initStorage$2, + _support: isLocalStorageValid(), + iterate: iterate$2, + getItem: getItem$2, + setItem: setItem$2, + removeItem: removeItem$2, + clear: clear$2, + length: length$2, + key: key$2, + keys: keys$2, + dropInstance: dropInstance$2 +}; + +var sameValue = function sameValue(x, y) { + return x === y || typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y); +}; + +var includes = function includes(array, searchElement) { + var len = array.length; + var i = 0; + while (i < len) { + if (sameValue(array[i], searchElement)) { + return true; + } + i++; + } + + return false; +}; + +var isArray = Array.isArray || function (arg) { + return Object.prototype.toString.call(arg) === '[object Array]'; +}; + +// Drivers are stored here when `defineDriver()` is called. +// They are shared across all instances of localForage. +var DefinedDrivers = {}; + +var DriverSupport = {}; + +var DefaultDrivers = { + INDEXEDDB: asyncStorage, + WEBSQL: webSQLStorage, + LOCALSTORAGE: localStorageWrapper +}; + +var DefaultDriverOrder = [DefaultDrivers.INDEXEDDB._driver, DefaultDrivers.WEBSQL._driver, DefaultDrivers.LOCALSTORAGE._driver]; + +var OptionalDriverMethods = ['dropInstance']; + +var LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'].concat(OptionalDriverMethods); + +var DefaultConfig = { + description: '', + driver: DefaultDriverOrder.slice(), + name: 'localforage', + // Default DB size is _JUST UNDER_ 5MB, as it's the highest size + // we can use without a prompt. + size: 4980736, + storeName: 'keyvaluepairs', + version: 1.0 +}; + +function callWhenReady(localForageInstance, libraryMethod) { + localForageInstance[libraryMethod] = function () { + var _args = arguments; + return localForageInstance.ready().then(function () { + return localForageInstance[libraryMethod].apply(localForageInstance, _args); + }); + }; +} + +function extend() { + for (var i = 1; i < arguments.length; i++) { + var arg = arguments[i]; + + if (arg) { + for (var _key in arg) { + if (arg.hasOwnProperty(_key)) { + if (isArray(arg[_key])) { + arguments[0][_key] = arg[_key].slice(); + } else { + arguments[0][_key] = arg[_key]; + } + } + } + } + } + + return arguments[0]; +} + +var LocalForage = function () { + function LocalForage(options) { + _classCallCheck(this, LocalForage); + + for (var driverTypeKey in DefaultDrivers) { + if (DefaultDrivers.hasOwnProperty(driverTypeKey)) { + var driver = DefaultDrivers[driverTypeKey]; + var driverName = driver._driver; + this[driverTypeKey] = driverName; + + if (!DefinedDrivers[driverName]) { + // we don't need to wait for the promise, + // since the default drivers can be defined + // in a blocking manner + this.defineDriver(driver); + } + } + } + + this._defaultConfig = extend({}, DefaultConfig); + this._config = extend({}, this._defaultConfig, options); + this._driverSet = null; + this._initDriver = null; + this._ready = false; + this._dbInfo = null; + + this._wrapLibraryMethodsWithReady(); + this.setDriver(this._config.driver)["catch"](function () {}); + } + + // Set any config values for localForage; can be called anytime before + // the first API call (e.g. `getItem`, `setItem`). + // We loop through options so we don't overwrite existing config + // values. + + + LocalForage.prototype.config = function config(options) { + // If the options argument is an object, we use it to set values. + // Otherwise, we return either a specified config value or all + // config values. + if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { + // If localforage is ready and fully initialized, we can't set + // any new configuration values. Instead, we return an error. + if (this._ready) { + return new Error("Can't call config() after localforage " + 'has been used.'); + } + + for (var i in options) { + if (i === 'storeName') { + options[i] = options[i].replace(/\W/g, '_'); + } + + if (i === 'version' && typeof options[i] !== 'number') { + return new Error('Database version must be a number.'); + } + + this._config[i] = options[i]; + } + + // after all config options are set and + // the driver option is used, try setting it + if ('driver' in options && options.driver) { + return this.setDriver(this._config.driver); + } + + return true; + } else if (typeof options === 'string') { + return this._config[options]; + } else { + return this._config; + } + }; + + // Used to define a custom driver, shared across all instances of + // localForage. + + + LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) { + var promise = new Promise$1(function (resolve, reject) { + try { + var driverName = driverObject._driver; + var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver'); + + // A driver name should be defined and not overlap with the + // library-defined, default drivers. + if (!driverObject._driver) { + reject(complianceError); + return; + } + + var driverMethods = LibraryMethods.concat('_initStorage'); + for (var i = 0, len = driverMethods.length; i < len; i++) { + var driverMethodName = driverMethods[i]; + + // when the property is there, + // it should be a method even when optional + var isRequired = !includes(OptionalDriverMethods, driverMethodName); + if ((isRequired || driverObject[driverMethodName]) && typeof driverObject[driverMethodName] !== 'function') { + reject(complianceError); + return; + } + } + + var configureMissingMethods = function configureMissingMethods() { + var methodNotImplementedFactory = function methodNotImplementedFactory(methodName) { + return function () { + var error = new Error('Method ' + methodName + ' is not implemented by the current driver'); + var promise = Promise$1.reject(error); + executeCallback(promise, arguments[arguments.length - 1]); + return promise; + }; + }; + + for (var _i = 0, _len = OptionalDriverMethods.length; _i < _len; _i++) { + var optionalDriverMethod = OptionalDriverMethods[_i]; + if (!driverObject[optionalDriverMethod]) { + driverObject[optionalDriverMethod] = methodNotImplementedFactory(optionalDriverMethod); + } + } + }; + + configureMissingMethods(); + + var setDriverSupport = function setDriverSupport(support) { + if (DefinedDrivers[driverName]) { + console.info('Redefining LocalForage driver: ' + driverName); + } + DefinedDrivers[driverName] = driverObject; + DriverSupport[driverName] = support; + // don't use a then, so that we can define + // drivers that have simple _support methods + // in a blocking manner + resolve(); + }; + + if ('_support' in driverObject) { + if (driverObject._support && typeof driverObject._support === 'function') { + driverObject._support().then(setDriverSupport, reject); + } else { + setDriverSupport(!!driverObject._support); + } + } else { + setDriverSupport(true); + } + } catch (e) { + reject(e); + } + }); + + executeTwoCallbacks(promise, callback, errorCallback); + return promise; + }; + + LocalForage.prototype.driver = function driver() { + return this._driver || null; + }; + + LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) { + var getDriverPromise = DefinedDrivers[driverName] ? Promise$1.resolve(DefinedDrivers[driverName]) : Promise$1.reject(new Error('Driver not found.')); + + executeTwoCallbacks(getDriverPromise, callback, errorCallback); + return getDriverPromise; + }; + + LocalForage.prototype.getSerializer = function getSerializer(callback) { + var serializerPromise = Promise$1.resolve(localforageSerializer); + executeTwoCallbacks(serializerPromise, callback); + return serializerPromise; + }; + + LocalForage.prototype.ready = function ready(callback) { + var self = this; + + var promise = self._driverSet.then(function () { + if (self._ready === null) { + self._ready = self._initDriver(); + } + + return self._ready; + }); + + executeTwoCallbacks(promise, callback, callback); + return promise; + }; + + LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) { + var self = this; + + if (!isArray(drivers)) { + drivers = [drivers]; + } + + var supportedDrivers = this._getSupportedDrivers(drivers); + + function setDriverToConfig() { + self._config.driver = self.driver(); + } + + function extendSelfWithDriver(driver) { + self._extend(driver); + setDriverToConfig(); + + self._ready = self._initStorage(self._config); + return self._ready; + } + + function initDriver(supportedDrivers) { + return function () { + var currentDriverIndex = 0; + + function driverPromiseLoop() { + while (currentDriverIndex < supportedDrivers.length) { + var driverName = supportedDrivers[currentDriverIndex]; + currentDriverIndex++; + + self._dbInfo = null; + self._ready = null; + + return self.getDriver(driverName).then(extendSelfWithDriver)["catch"](driverPromiseLoop); + } + + setDriverToConfig(); + var error = new Error('No available storage method found.'); + self._driverSet = Promise$1.reject(error); + return self._driverSet; + } + + return driverPromiseLoop(); + }; + } + + // There might be a driver initialization in progress + // so wait for it to finish in order to avoid a possible + // race condition to set _dbInfo + var oldDriverSetDone = this._driverSet !== null ? this._driverSet["catch"](function () { + return Promise$1.resolve(); + }) : Promise$1.resolve(); + + this._driverSet = oldDriverSetDone.then(function () { + var driverName = supportedDrivers[0]; + self._dbInfo = null; + self._ready = null; + + return self.getDriver(driverName).then(function (driver) { + self._driver = driver._driver; + setDriverToConfig(); + self._wrapLibraryMethodsWithReady(); + self._initDriver = initDriver(supportedDrivers); + }); + })["catch"](function () { + setDriverToConfig(); + var error = new Error('No available storage method found.'); + self._driverSet = Promise$1.reject(error); + return self._driverSet; + }); + + executeTwoCallbacks(this._driverSet, callback, errorCallback); + return this._driverSet; + }; + + LocalForage.prototype.supports = function supports(driverName) { + return !!DriverSupport[driverName]; + }; + + LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) { + extend(this, libraryMethodsAndProperties); + }; + + LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) { + var supportedDrivers = []; + for (var i = 0, len = drivers.length; i < len; i++) { + var driverName = drivers[i]; + if (this.supports(driverName)) { + supportedDrivers.push(driverName); + } + } + return supportedDrivers; + }; + + LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() { + // Add a stub for each driver API method that delays the call to the + // corresponding driver method until localForage is ready. These stubs + // will be replaced by the driver methods as soon as the driver is + // loaded, so there is no performance impact. + for (var i = 0, len = LibraryMethods.length; i < len; i++) { + callWhenReady(this, LibraryMethods[i]); + } + }; + + LocalForage.prototype.createInstance = function createInstance(options) { + return new LocalForage(options); + }; + + return LocalForage; +}(); + +// The actual localForage object that we expose as a module or via a +// global. It's extended by pulling in one of our other libraries. + + +var localforage_js = new LocalForage(); + +module.exports = localforage_js; + +},{"3":3}]},{},[4])(4) +}); + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(12))) + +/***/ }), +/* 28 */, +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { + +var isFunction = __webpack_require__(62), + isLength = __webpack_require__(71); + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +module.exports = isArrayLike; + + +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(13); +var core = __webpack_require__(19); +var ctx = __webpack_require__(58); +var hide = __webpack_require__(31); +var has = __webpack_require__(60); +var PROTOTYPE = 'prototype'; + +var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var IS_WRAP = type & $export.W; + var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); + var expProto = exports[PROTOTYPE]; + var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; + var key, own, out; + if (IS_GLOBAL) source = name; + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if (own && has(exports, key)) continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function (C) { + var F = function (a, b, c) { + if (this instanceof C) { + switch (arguments.length) { + case 0: return new C(); + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if (IS_PROTO) { + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); + } + } +}; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; + + +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { + +var dP = __webpack_require__(40); +var createDesc = __webpack_require__(140); +module.exports = __webpack_require__(32) ? function (object, key, value) { + return dP.f(object, key, createDesc(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; + + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + +// Thank's IE8 for his funny defineProperty +module.exports = !__webpack_require__(82)(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; +}); + + +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +var arrayLikeKeys = __webpack_require__(98), + baseKeys = __webpack_require__(102), + isArrayLike = __webpack_require__(29); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +module.exports = keys; + + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Native Javascript for Bootstrap 4 v2.0.27 | © dnp_theme | MIT-License +(function (root, factory) { + if (true) { + // AMD support: + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else { var bsn; } +}(this, function () { + + /* Native Javascript for Bootstrap 4 | Internal Utility Functions + ----------------------------------------------------------------*/ + "use strict"; + + // globals + var globalObject = typeof global !== 'undefined' ? global : this||window, + DOC = document, HTML = DOC.documentElement, body = 'body', // allow the library to be used in + + // Native Javascript for Bootstrap Global Object + BSN = globalObject.BSN = {}, + supports = BSN.supports = [], + + // function toggle attributes + dataToggle = 'data-toggle', + dataDismiss = 'data-dismiss', + dataSpy = 'data-spy', + dataRide = 'data-ride', + + // components + stringAlert = 'Alert', + stringButton = 'Button', + stringCarousel = 'Carousel', + stringCollapse = 'Collapse', + stringDropdown = 'Dropdown', + stringModal = 'Modal', + stringPopover = 'Popover', + stringScrollSpy = 'ScrollSpy', + stringTab = 'Tab', + stringTooltip = 'Tooltip', + stringToast = 'Toast', + + // options DATA API + dataAutohide = 'data-autohide', + databackdrop = 'data-backdrop', + dataKeyboard = 'data-keyboard', + dataTarget = 'data-target', + dataInterval = 'data-interval', + dataHeight = 'data-height', + dataPause = 'data-pause', + dataTitle = 'data-title', + dataOriginalTitle = 'data-original-title', + dataDismissible = 'data-dismissible', + dataTrigger = 'data-trigger', + dataAnimation = 'data-animation', + dataContainer = 'data-container', + dataPlacement = 'data-placement', + dataDelay = 'data-delay', + + // option keys + backdrop = 'backdrop', keyboard = 'keyboard', delay = 'delay', + content = 'content', target = 'target', currentTarget = 'currentTarget', + interval = 'interval', pause = 'pause', animation = 'animation', + placement = 'placement', container = 'container', + + // box model + offsetTop = 'offsetTop', offsetBottom = 'offsetBottom', + offsetLeft = 'offsetLeft', + scrollTop = 'scrollTop', scrollLeft = 'scrollLeft', + clientWidth = 'clientWidth', clientHeight = 'clientHeight', + offsetWidth = 'offsetWidth', offsetHeight = 'offsetHeight', + innerWidth = 'innerWidth', innerHeight = 'innerHeight', + scrollHeight = 'scrollHeight', scrollWidth = 'scrollWidth', + height = 'height', + + // aria + ariaExpanded = 'aria-expanded', + ariaHidden = 'aria-hidden', + ariaSelected = 'aria-selected', + + // event names + clickEvent = 'click', + focusEvent = 'focus', + hoverEvent = 'hover', + keydownEvent = 'keydown', + keyupEvent = 'keyup', + resizeEvent = 'resize', // passive + scrollEvent = 'scroll', // passive + mouseHover = ('onmouseleave' in DOC) ? [ 'mouseenter', 'mouseleave'] : [ 'mouseover', 'mouseout' ], + // touch since 2.0.26 + touchEvents = { start: 'touchstart', end: 'touchend', move:'touchmove' }, // passive + // originalEvents + showEvent = 'show', + shownEvent = 'shown', + hideEvent = 'hide', + hiddenEvent = 'hidden', + closeEvent = 'close', + closedEvent = 'closed', + slidEvent = 'slid', + slideEvent = 'slide', + changeEvent = 'change', + + // other + getAttribute = 'getAttribute', + setAttribute = 'setAttribute', + hasAttribute = 'hasAttribute', + createElement = 'createElement', + appendChild = 'appendChild', + innerHTML = 'innerHTML', + getElementsByTagName = 'getElementsByTagName', + preventDefault = 'preventDefault', + getBoundingClientRect = 'getBoundingClientRect', + querySelectorAll = 'querySelectorAll', + getElementsByCLASSNAME = 'getElementsByClassName', + getComputedStyle = 'getComputedStyle', + + indexOf = 'indexOf', + parentNode = 'parentNode', + length = 'length', + toLowerCase = 'toLowerCase', + Transition = 'Transition', + Duration = 'Duration', + Webkit = 'Webkit', + style = 'style', + push = 'push', + tabindex = 'tabindex', + contains = 'contains', + + active = 'active', + showClass = 'show', + collapsing = 'collapsing', + disabled = 'disabled', + loading = 'loading', + left = 'left', + right = 'right', + top = 'top', + bottom = 'bottom', + + // tooltip / popover + tipPositions = /\b(top|bottom|left|right)+/, + + // modal + modalOverlay = 0, + fixedTop = 'fixed-top', + fixedBottom = 'fixed-bottom', + + // transitionEnd since 2.0.4 + supportTransitions = Webkit+Transition in HTML[style] || Transition[toLowerCase]() in HTML[style], + transitionEndEvent = Webkit+Transition in HTML[style] ? Webkit[toLowerCase]()+Transition+'End' : Transition[toLowerCase]()+'end', + transitionDuration = Webkit+Duration in HTML[style] ? Webkit[toLowerCase]()+Transition+Duration : Transition[toLowerCase]()+Duration, + + // set new focus element since 2.0.3 + setFocus = function(element){ + element.focus ? element.focus() : element.setActive(); + }, + + // class manipulation, since 2.0.0 requires polyfill.js + addClass = function(element,classNAME) { + element.classList.add(classNAME); + }, + removeClass = function(element,classNAME) { + element.classList.remove(classNAME); + }, + hasClass = function(element,classNAME){ // since 2.0.0 + return element.classList[contains](classNAME); + }, + + // selection methods + getElementsByClassName = function(element,classNAME) { // returns Array + return [].slice.call(element[getElementsByCLASSNAME]( classNAME )); + }, + queryElement = function (selector, parent) { + var lookUp = parent ? parent : DOC; + return typeof selector === 'object' ? selector : lookUp.querySelector(selector); + }, + getClosest = function (element, selector) { //element is the element and selector is for the closest parent element to find + // source http://gomakethings.com/climbing-up-and-down-the-dom-tree-with-vanilla-javascript/ + var firstChar = selector.charAt(0), selectorSubstring = selector.substr(1); + if ( firstChar === '.' ) {// If selector is a class + for ( ; element && element !== DOC; element = element[parentNode] ) { // Get closest match + if ( queryElement(selector,element[parentNode]) !== null && hasClass(element,selectorSubstring) ) { return element; } + } + } else if ( firstChar === '#' ) { // If selector is an ID + for ( ; element && element !== DOC; element = element[parentNode] ) { // Get closest match + if ( element.id === selectorSubstring ) { return element; } + } + } + return false; + }, + + // event attach jQuery style / trigger since 1.2.0 + on = function (element, event, handler, options) { + options = options || false; + element.addEventListener(event, handler, options); + }, + off = function(element, event, handler, options) { + options = options || false; + element.removeEventListener(event, handler, options); + }, + one = function (element, event, handler, options) { // one since 2.0.4 + on(element, event, function handlerWrapper(e){ + handler(e); + off(element, event, handlerWrapper, options); + }, options); + }, + // determine support for passive events + supportPassive = (function(){ + // Test via a getter in the options object to see if the passive property is accessed + var result = false; + try { + var opts = Object.defineProperty({}, 'passive', { + get: function() { + result = true; + } + }); + one(globalObject, 'testPassive', null, opts); + } catch (e) {} + + return result; + }()), + // event options + // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection + passiveHandler = supportPassive ? { passive: true } : false, + // transitions + getTransitionDurationFromElement = function(element) { + var duration = supportTransitions ? globalObject[getComputedStyle](element)[transitionDuration] : 0; + duration = parseFloat(duration); + duration = typeof duration === 'number' && !isNaN(duration) ? duration * 1000 : 0; + return duration; // we take a short offset to make sure we fire on the next frame after animation + }, + emulateTransitionEnd = function(element,handler){ // emulateTransitionEnd since 2.0.4 + var called = 0, duration = getTransitionDurationFromElement(element); + duration ? one(element, transitionEndEvent, function(e){ !called && handler(e), called = 1; }) + : setTimeout(function() { !called && handler(), called = 1; }, 17); + }, + bootstrapCustomEvent = function (eventName, componentName, related) { + var OriginalCustomEvent = new CustomEvent( eventName + '.bs.' + componentName); + OriginalCustomEvent.relatedTarget = related; + this.dispatchEvent(OriginalCustomEvent); + }, + + // tooltip / popover stuff + getScroll = function() { // also Affix and ScrollSpy uses it + return { + y : globalObject.pageYOffset || HTML[scrollTop], + x : globalObject.pageXOffset || HTML[scrollLeft] + } + }, + styleTip = function(link,element,position,parent) { // both popovers and tooltips (target,tooltip,placement,elementToAppendTo) + var elementDimensions = { w : element[offsetWidth], h: element[offsetHeight] }, + windowWidth = (HTML[clientWidth] || DOC[body][clientWidth]), + windowHeight = (HTML[clientHeight] || DOC[body][clientHeight]), + rect = link[getBoundingClientRect](), + scroll = parent === DOC[body] ? getScroll() : { x: parent[offsetLeft] + parent[scrollLeft], y: parent[offsetTop] + parent[scrollTop] }, + linkDimensions = { w: rect[right] - rect[left], h: rect[bottom] - rect[top] }, + isPopover = hasClass(element,'popover'), + topPosition, leftPosition, + + arrow = queryElement('.arrow',element), + arrowTop, arrowLeft, arrowWidth, arrowHeight, + + halfTopExceed = rect[top] + linkDimensions.h/2 - elementDimensions.h/2 < 0, + halfLeftExceed = rect[left] + linkDimensions.w/2 - elementDimensions.w/2 < 0, + halfRightExceed = rect[left] + elementDimensions.w/2 + linkDimensions.w/2 >= windowWidth, + halfBottomExceed = rect[top] + elementDimensions.h/2 + linkDimensions.h/2 >= windowHeight, + topExceed = rect[top] - elementDimensions.h < 0, + leftExceed = rect[left] - elementDimensions.w < 0, + bottomExceed = rect[top] + elementDimensions.h + linkDimensions.h >= windowHeight, + rightExceed = rect[left] + elementDimensions.w + linkDimensions.w >= windowWidth; + + // recompute position + position = (position === left || position === right) && leftExceed && rightExceed ? top : position; // first, when both left and right limits are exceeded, we fall back to top|bottom + position = position === top && topExceed ? bottom : position; + position = position === bottom && bottomExceed ? top : position; + position = position === left && leftExceed ? right : position; + position = position === right && rightExceed ? left : position; + + // update tooltip/popover class + element.className[indexOf](position) === -1 && (element.className = element.className.replace(tipPositions,position)); + + // we check the computed width & height and update here + arrowWidth = arrow[offsetWidth]; arrowHeight = arrow[offsetHeight]; + + // apply styling to tooltip or popover + if ( position === left || position === right ) { // secondary|side positions + if ( position === left ) { // LEFT + leftPosition = rect[left] + scroll.x - elementDimensions.w - ( isPopover ? arrowWidth : 0 ); + } else { // RIGHT + leftPosition = rect[left] + scroll.x + linkDimensions.w; + } + + // adjust top and arrow + if (halfTopExceed) { + topPosition = rect[top] + scroll.y; + arrowTop = linkDimensions.h/2 - arrowWidth; + } else if (halfBottomExceed) { + topPosition = rect[top] + scroll.y - elementDimensions.h + linkDimensions.h; + arrowTop = elementDimensions.h - linkDimensions.h/2 - arrowWidth; + } else { + topPosition = rect[top] + scroll.y - elementDimensions.h/2 + linkDimensions.h/2; + arrowTop = elementDimensions.h/2 - (isPopover ? arrowHeight*0.9 : arrowHeight/2); + } + } else if ( position === top || position === bottom ) { // primary|vertical positions + if ( position === top) { // TOP + topPosition = rect[top] + scroll.y - elementDimensions.h - ( isPopover ? arrowHeight : 0 ); + } else { // BOTTOM + topPosition = rect[top] + scroll.y + linkDimensions.h; + } + // adjust left | right and also the arrow + if (halfLeftExceed) { + leftPosition = 0; + arrowLeft = rect[left] + linkDimensions.w/2 - arrowWidth; + } else if (halfRightExceed) { + leftPosition = windowWidth - elementDimensions.w*1.01; + arrowLeft = elementDimensions.w - ( windowWidth - rect[left] ) + linkDimensions.w/2 - arrowWidth/2; + } else { + leftPosition = rect[left] + scroll.x - elementDimensions.w/2 + linkDimensions.w/2; + arrowLeft = elementDimensions.w/2 - ( isPopover ? arrowWidth : arrowWidth/2 ); + } + } + + // apply style to tooltip/popover and its arrow + element[style][top] = topPosition + 'px'; + element[style][left] = leftPosition + 'px'; + + arrowTop && (arrow[style][top] = arrowTop + 'px'); + arrowLeft && (arrow[style][left] = arrowLeft + 'px'); + }; + + BSN.version = '2.0.27'; + + /* Native Javascript for Bootstrap 4 | Alert + -------------------------------------------*/ + + // ALERT DEFINITION + // ================ + var Alert = function( element ) { + + // initialization element + element = queryElement(element); + + // bind, target alert, duration and stuff + var self = this, component = 'alert', + alert = getClosest(element,'.'+component), + triggerHandler = function(){ hasClass(alert,'fade') ? emulateTransitionEnd(alert,transitionEndHandler) : transitionEndHandler(); }, + // handlers + clickHandler = function(e){ + alert = getClosest(e[target],'.'+component); + element = queryElement('['+dataDismiss+'="'+component+'"]',alert); + element && alert && (element === e[target] || element[contains](e[target])) && self.close(); + }, + transitionEndHandler = function(){ + bootstrapCustomEvent.call(alert, closedEvent, component); + off(element, clickEvent, clickHandler); // detach it's listener + alert[parentNode].removeChild(alert); + }; + + // public method + this.close = function() { + if ( alert && element && hasClass(alert,showClass) ) { + bootstrapCustomEvent.call(alert, closeEvent, component); + removeClass(alert,showClass); + alert && triggerHandler(); + } + }; + + // init + if ( !(stringAlert in element ) ) { // prevent adding event handlers twice + on(element, clickEvent, clickHandler); + } + element[stringAlert] = self; + }; + + // ALERT DATA API + // ============== + supports[push]([stringAlert, Alert, '['+dataDismiss+'="alert"]']); + + + /* Native Javascript for Bootstrap 4 | Button + ---------------------------------------------*/ + + // BUTTON DEFINITION + // =================== + var Button = function( element ) { + + // initialization element + element = queryElement(element); + + // constant + var toggled = false, // toggled makes sure to prevent triggering twice the change.bs.button events + + // strings + component = 'button', + checked = 'checked', + LABEL = 'LABEL', + INPUT = 'INPUT', + + // private methods + keyHandler = function(e){ + var key = e.which || e.keyCode; + key === 32 && e[target] === DOC.activeElement && toggle(e); + }, + preventScroll = function(e){ + var key = e.which || e.keyCode; + key === 32 && e[preventDefault](); + }, + toggle = function(e) { + var label = e[target].tagName === LABEL ? e[target] : e[target][parentNode].tagName === LABEL ? e[target][parentNode] : null; // the .btn label + + if ( !label ) return; //react if a label or its immediate child is clicked + + var labels = getElementsByClassName(label[parentNode],'btn'), // all the button group buttons + input = label[getElementsByTagName](INPUT)[0]; + + if ( !input ) return; // return if no input found + + // manage the dom manipulation + if ( input.type === 'checkbox' ) { //checkboxes + if ( !input[checked] ) { + addClass(label,active); + input[getAttribute](checked); + input[setAttribute](checked,checked); + input[checked] = true; + } else { + removeClass(label,active); + input[getAttribute](checked); + input.removeAttribute(checked); + input[checked] = false; + } + + if (!toggled) { // prevent triggering the event twice + toggled = true; + bootstrapCustomEvent.call(input, changeEvent, component); //trigger the change for the input + bootstrapCustomEvent.call(element, changeEvent, component); //trigger the change for the btn-group + } + } + + if ( input.type === 'radio' && !toggled ) { // radio buttons + // don't trigger if already active (the OR condition is a hack to check if the buttons were selected with key press and NOT mouse click) + if ( !input[checked] || (e.screenX === 0 && e.screenY == 0) ) { + addClass(label,active); + addClass(label,focusEvent); + input[setAttribute](checked,checked); + input[checked] = true; + bootstrapCustomEvent.call(input, changeEvent, component); //trigger the change for the input + bootstrapCustomEvent.call(element, changeEvent, component); //trigger the change for the btn-group + + toggled = true; + for (var i = 0, ll = labels[length]; i1?idx-1:0) + : key === 40 ? (idx 1 ) { + activeTab = activeTabs[activeTabs[length]-1]; + } + return activeTab; + }, + getActiveContent = function() { + return queryElement(getActiveTab()[getAttribute]('href')); + }, + // handler + clickHandler = function(e) { + e[preventDefault](); + next = e[currentTarget]; + !tabs[isAnimating] && !hasClass(next,active) && self.show(); + }; + + // public method + this.show = function() { // the tab we clicked is now the next tab + next = next || element; + nextContent = queryElement(next[getAttribute]('href')); //this is the actual object, the next tab content to activate + activeTab = getActiveTab(); + activeContent = getActiveContent(); + + tabs[isAnimating] = true; + removeClass(activeTab,active); + activeTab[setAttribute](ariaSelected,'false'); + addClass(next,active); + next[setAttribute](ariaSelected,'true'); + + if ( dropdown ) { + if ( !hasClass(element[parentNode],'dropdown-menu') ) { + if (hasClass(dropdown,active)) removeClass(dropdown,active); + } else { + if (!hasClass(dropdown,active)) addClass(dropdown,active); + } + } + + bootstrapCustomEvent.call(activeTab, hideEvent, component, next); + + if (hasClass(activeContent, 'fade')) { + removeClass(activeContent,showClass); + emulateTransitionEnd(activeContent, triggerHide); + } else { triggerHide(); } + }; + + // init + if ( !(stringTab in element) ) { // prevent adding event handlers twice + on(element, clickEvent, clickHandler); + } + if (self[height]) { tabsContentContainer = getActiveContent()[parentNode]; } + element[stringTab] = self; + }; + + // TAB DATA API + // ============ + supports[push]( [ stringTab, Tab, '['+dataToggle+'="tab"]' ] ); + + + /* Native Javascript for Bootstrap 4 | Toast + ---------------------------------------------*/ + + // TOAST DEFINITION + // ================== + var Toast = function( element,options ) { + + // initialization element + element = queryElement(element); + + // set options + options = options || {}; + + // DATA API + var animationData = element[getAttribute](dataAnimation), + autohideData = element[getAttribute](dataAutohide), + delayData = element[getAttribute](dataDelay), + + // strings + component = 'toast', + autohide = 'autohide', + animation = 'animation', + showing = 'showing', + hide = 'hide', + fade = 'fade'; + + // set instance options + this[animation] = options[animation] === false || animationData === 'false' ? 0 : 1; // true by default + this[autohide] = options[autohide] === false || autohideData === 'false' ? 0 : 1; // true by default + this[delay] = parseInt(options[delay] || delayData) || 500; // 500ms default + + // bind,toast and timer + var self = this, timer = 0, + // get the toast element + toast = getClosest(element,'.toast'); + + // private methods + // animation complete + var showComplete = function() { + removeClass( toast, showing ); + addClass( toast, showClass ); + bootstrapCustomEvent.call(toast, shownEvent, component); + if (self[autohide]) { self.hide(); } + }, + hideComplete = function() { + addClass( toast, hide ); + bootstrapCustomEvent.call(toast, hiddenEvent, component); + }, + close = function() { + removeClass( toast,showClass ); + self[animation] ? emulateTransitionEnd(toast, hideComplete) : hideComplete(); + }, + disposeComplete = function(){ + clearTimeout(timer); timer = null; + addClass( toast, hide ); + off(element, clickEvent, self.hide); + element[stringToast] = null; + element = null; + toast = null; + }; + + // public methods + this.show = function() { + if (toast) { + bootstrapCustomEvent.call(toast, showEvent, component); + self[animation] && addClass( toast,fade ); + removeClass( toast,hide ); + addClass( toast,showing ); + + self[animation] ? emulateTransitionEnd(toast, showComplete) : showComplete(); + } + }; + this.hide = function(noTimer) { + if (toast && hasClass(toast,showClass)) { + bootstrapCustomEvent.call(toast, hideEvent, component); + + if (noTimer) { + close(); + } else { + timer = setTimeout( close, self[delay]); + } + } + }; + this.dispose = function() { + if ( toast && hasClass(toast,showClass) ) { + removeClass( toast,showClass ); + self[animation] ? emulateTransitionEnd(toast, disposeComplete) : disposeComplete(); + } + }; + + // init + if ( !(stringToast in element) ) { // prevent adding event handlers twice + on(element, clickEvent, self.hide); + } + element[stringToast] = self; + }; + + // TOAST DATA API + // ================= + supports[push]( [ stringToast, Toast, '['+dataDismiss+'="toast"]' ] ); + + + /* Native Javascript for Bootstrap 4 | Tooltip + ---------------------------------------------*/ + + // TOOLTIP DEFINITION + // ================== + var Tooltip = function( element,options ) { + + // initialization element + element = queryElement(element); + + // set options + options = options || {}; + + // DATA API + var animationData = element[getAttribute](dataAnimation), + placementData = element[getAttribute](dataPlacement), + delayData = element[getAttribute](dataDelay), + containerData = element[getAttribute](dataContainer), + + // strings + component = 'tooltip', + classString = 'class', + title = 'title', + fade = 'fade', + div = 'div', + + // check container + containerElement = queryElement(options[container]), + containerDataElement = queryElement(containerData), + + // maybe the element is inside a modal + modal = getClosest(element,'.modal'), + + // maybe the element is inside a fixed navbar + navbarFixedTop = getClosest(element,'.'+fixedTop), + navbarFixedBottom = getClosest(element,'.'+fixedBottom); + + // set instance options + this[animation] = options[animation] && options[animation] !== fade ? options[animation] : animationData || fade; + this[placement] = options[placement] ? options[placement] : placementData || top; + this[delay] = parseInt(options[delay] || delayData) || 200; + this[container] = containerElement ? containerElement + : containerDataElement ? containerDataElement + : navbarFixedTop ? navbarFixedTop + : navbarFixedBottom ? navbarFixedBottom + : modal ? modal : DOC[body]; + + // bind, event targets, title and constants + var self = this, timer = 0, placementSetting = this[placement], tooltip = null, + titleString = element[getAttribute](title) || element[getAttribute](dataTitle) || element[getAttribute](dataOriginalTitle); + + if ( !titleString || titleString == "" ) return; // invalidate + + // private methods + var removeToolTip = function() { + self[container].removeChild(tooltip); + tooltip = null; timer = null; + }, + createToolTip = function() { + titleString = element[getAttribute](title) || element[getAttribute](dataTitle) || element[getAttribute](dataOriginalTitle); // read the title again + + if ( titleString && titleString !== "" ) { // invalidate, maybe markup changed + tooltip = DOC[createElement](div); + tooltip[setAttribute]('role',component); + tooltip[style][left] = '0'; + tooltip[style][top] = '0'; + + // tooltip arrow + var tooltipArrow = DOC[createElement](div); + tooltipArrow[setAttribute](classString,'arrow'); + tooltip[appendChild](tooltipArrow); + + var tooltipInner = DOC[createElement](div); + tooltipInner[setAttribute](classString,component+'-inner'); + tooltip[appendChild](tooltipInner); + tooltipInner[innerHTML] = titleString; + + self[container][appendChild](tooltip); + tooltip[setAttribute](classString, component + ' bs-' + component+'-'+placementSetting + ' ' + self[animation]); + } + }, + updateTooltip = function () { + styleTip(element, tooltip, placementSetting, self[container]); + }, + showTooltip = function () { + !hasClass(tooltip,showClass) && ( addClass(tooltip,showClass) ); + }, + // triggers + showTrigger = function() { + on( globalObject, resizeEvent, self.hide, passiveHandler ); + bootstrapCustomEvent.call(element, shownEvent, component); + }, + hideTrigger = function() { + off( globalObject, resizeEvent, self.hide, passiveHandler ); + removeToolTip(); + bootstrapCustomEvent.call(element, hiddenEvent, component); + }; + + // public methods + this.show = function() { + clearTimeout(timer); + timer = setTimeout( function() { + if (tooltip === null) { + placementSetting = self[placement]; // we reset placement in all cases + // if(createToolTip() == false) return; + if(createToolTip() !== false) { + updateTooltip(); + showTooltip(); + bootstrapCustomEvent.call(element, showEvent, component); + !!self[animation] ? emulateTransitionEnd(tooltip, showTrigger) : showTrigger(); + } + } + }, 20 ); + }; + this.hide = function() { + clearTimeout(timer); + timer = setTimeout( function() { + if (tooltip && hasClass(tooltip,showClass)) { + bootstrapCustomEvent.call(element, hideEvent, component); + removeClass(tooltip,showClass); + !!self[animation] ? emulateTransitionEnd(tooltip, hideTrigger) : hideTrigger(); + } + }, self[delay]); + }; + this.toggle = function() { + if (!tooltip) { self.show(); } + else { self.hide(); } + }; + + // init + if ( !(stringTooltip in element) ) { // prevent adding event handlers twice + element[setAttribute](dataOriginalTitle,titleString); + element.removeAttribute(title); + on(element, mouseHover[0], self.show); + on(element, mouseHover[1], self.hide); + } + element[stringTooltip] = self; + }; + + // TOOLTIP DATA API + // ================= + supports[push]( [ stringTooltip, Tooltip, '['+dataToggle+'="tooltip"]' ] ); + + + + /* Native Javascript for Bootstrap | Initialize Data API + --------------------------------------------------------*/ + var initializeDataAPI = function( constructor, collection ){ + for (var i=0, l=collection[length]; i= 1; + + var _baseSupplied = arguments.length >= 2; // Allow instantiation without the 'new' keyword + + + if (!(this instanceof URI)) { + if (_urlSupplied) { + if (_baseSupplied) { + return new URI(url, base); + } + + return new URI(url); + } + + return new URI(); + } + + if (url === undefined) { + if (_urlSupplied) { + throw new TypeError('undefined is not a valid argument for URI'); + } + + if (typeof location !== 'undefined') { + url = location.href + ''; + } else { + url = ''; + } + } + + if (url === null) { + if (_urlSupplied) { + throw new TypeError('null is not a valid argument for URI'); + } + } + + this.href(url); // resolve to base according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor + + if (base !== undefined) { + return this.absoluteTo(base); + } + + return this; + } + + function isInteger(value) { + return /^[0-9]+$/.test(value); + } + + URI.version = '1.19.2'; + var p = URI.prototype; + var hasOwn = Object.prototype.hasOwnProperty; + + function escapeRegEx(string) { + // https://github.com/medialize/URI.js/commit/85ac21783c11f8ccab06106dba9735a31a86924d#commitcomment-821963 + return string.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); + } + + function getType(value) { + // IE8 doesn't return [Object Undefined] but [Object Object] for undefined value + if (value === undefined) { + return 'Undefined'; + } + + return String(Object.prototype.toString.call(value)).slice(8, -1); + } + + function isArray(obj) { + return getType(obj) === 'Array'; + } + + function filterArrayValues(data, value) { + var lookup = {}; + var i, length; + + if (getType(value) === 'RegExp') { + lookup = null; + } else if (isArray(value)) { + for (i = 0, length = value.length; i < length; i++) { + lookup[value[i]] = true; + } + } else { + lookup[value] = true; + } + + for (i = 0, length = data.length; i < length; i++) { + /*jshint laxbreak: true */ + var _match = lookup && lookup[data[i]] !== undefined || !lookup && value.test(data[i]); + /*jshint laxbreak: false */ + + + if (_match) { + data.splice(i, 1); + length--; + i--; + } + } + + return data; + } + + function arrayContains(list, value) { + var i, length; // value may be string, number, array, regexp + + if (isArray(value)) { + // Note: this can be optimized to O(n) (instead of current O(m * n)) + for (i = 0, length = value.length; i < length; i++) { + if (!arrayContains(list, value[i])) { + return false; + } + } + + return true; + } + + var _type = getType(value); + + for (i = 0, length = list.length; i < length; i++) { + if (_type === 'RegExp') { + if (typeof list[i] === 'string' && list[i].match(value)) { + return true; + } + } else if (list[i] === value) { + return true; + } + } + + return false; + } + + function arraysEqual(one, two) { + if (!isArray(one) || !isArray(two)) { + return false; + } // arrays can't be equal if they have different amount of content + + + if (one.length !== two.length) { + return false; + } + + one.sort(); + two.sort(); + + for (var i = 0, l = one.length; i < l; i++) { + if (one[i] !== two[i]) { + return false; + } + } + + return true; + } + + function trimSlashes(text) { + var trim_expression = /^\/+|\/+$/g; + return text.replace(trim_expression, ''); + } + + URI._parts = function () { + return { + protocol: null, + username: null, + password: null, + hostname: null, + urn: null, + port: null, + path: null, + query: null, + fragment: null, + // state + preventInvalidHostname: URI.preventInvalidHostname, + duplicateQueryParameters: URI.duplicateQueryParameters, + escapeQuerySpace: URI.escapeQuerySpace + }; + }; // state: throw on invalid hostname + // see https://github.com/medialize/URI.js/pull/345 + // and https://github.com/medialize/URI.js/issues/354 + + + URI.preventInvalidHostname = false; // state: allow duplicate query parameters (a=1&a=1) + + URI.duplicateQueryParameters = false; // state: replaces + with %20 (space in query strings) + + URI.escapeQuerySpace = true; // static properties + + URI.protocol_expression = /^[a-z][a-z0-9.+-]*$/i; + URI.idn_expression = /[^a-z0-9\._-]/i; + URI.punycode_expression = /(xn--)/i; // well, 333.444.555.666 matches, but it sure ain't no IPv4 - do we care? + + URI.ip4_expression = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; // credits to Rich Brown + // source: http://forums.intermapper.com/viewtopic.php?p=1096#1096 + // specification: http://www.ietf.org/rfc/rfc4291.txt + + URI.ip6_expression = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/; // expression used is "gruber revised" (@gruber v2) determined to be the + // best solution in a regex-golf we did a couple of ages ago at + // * http://mathiasbynens.be/demo/url-regex + // * http://rodneyrehm.de/t/url-regex.html + + URI.find_uri_expression = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig; + URI.findUri = { + // valid "scheme://" or "www." + start: /\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi, + // everything up to the next whitespace + end: /[\s\r\n]|$/, + // trim trailing punctuation captured by end RegExp + trim: /[`!()\[\]{};:'".,<>?«»“”„‘’]+$/, + // balanced parens inclusion (), [], {}, <> + parens: /(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g + }; // http://www.iana.org/assignments/uri-schemes.html + // http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports + + URI.defaultPorts = { + http: '80', + https: '443', + ftp: '21', + gopher: '70', + ws: '80', + wss: '443' + }; // list of protocols which always require a hostname + + URI.hostProtocols = ['http', 'https']; // allowed hostname characters according to RFC 3986 + // ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded + // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . - _ + + URI.invalid_hostname_characters = /[^a-zA-Z0-9\.\-:_]/; // map DOM Elements to their URI attribute + + URI.domAttributes = { + 'a': 'href', + 'blockquote': 'cite', + 'link': 'href', + 'base': 'href', + 'script': 'src', + 'form': 'action', + 'img': 'src', + 'area': 'href', + 'iframe': 'src', + 'embed': 'src', + 'source': 'src', + 'track': 'src', + 'input': 'src', + // but only if type="image" + 'audio': 'src', + 'video': 'src' + }; + + URI.getDomAttribute = function (node) { + if (!node || !node.nodeName) { + return undefined; + } + + var nodeName = node.nodeName.toLowerCase(); // should only expose src for type="image" + + if (nodeName === 'input' && node.type !== 'image') { + return undefined; + } + + return URI.domAttributes[nodeName]; + }; + + function escapeForDumbFirefox36(value) { + // https://github.com/medialize/URI.js/issues/91 + return escape(value); + } // encoding / decoding according to RFC3986 + + + function strictEncodeURIComponent(string) { + // see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent + return encodeURIComponent(string).replace(/[!'()*]/g, escapeForDumbFirefox36).replace(/\*/g, '%2A'); + } + + URI.encode = strictEncodeURIComponent; + URI.decode = decodeURIComponent; + + URI.iso8859 = function () { + URI.encode = escape; + URI.decode = unescape; + }; + + URI.unicode = function () { + URI.encode = strictEncodeURIComponent; + URI.decode = decodeURIComponent; + }; + + URI.characters = { + pathname: { + encode: { + // RFC3986 2.1: For consistency, URI producers and normalizers should + // use uppercase hexadecimal digits for all percent-encodings. + expression: /%(24|26|2B|2C|3B|3D|3A|40)/ig, + map: { + // -._~!'()* + '%24': '$', + '%26': '&', + '%2B': '+', + '%2C': ',', + '%3B': ';', + '%3D': '=', + '%3A': ':', + '%40': '@' + } + }, + decode: { + expression: /[\/\?#]/g, + map: { + '/': '%2F', + '?': '%3F', + '#': '%23' + } + } + }, + reserved: { + encode: { + // RFC3986 2.1: For consistency, URI producers and normalizers should + // use uppercase hexadecimal digits for all percent-encodings. + expression: /%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig, + map: { + // gen-delims + '%3A': ':', + '%2F': '/', + '%3F': '?', + '%23': '#', + '%5B': '[', + '%5D': ']', + '%40': '@', + // sub-delims + '%21': '!', + '%24': '$', + '%26': '&', + '%27': '\'', + '%28': '(', + '%29': ')', + '%2A': '*', + '%2B': '+', + '%2C': ',', + '%3B': ';', + '%3D': '=' + } + } + }, + urnpath: { + // The characters under `encode` are the characters called out by RFC 2141 as being acceptable + // for usage in a URN. RFC2141 also calls out "-", ".", and "_" as acceptable characters, but + // these aren't encoded by encodeURIComponent, so we don't have to call them out here. Also + // note that the colon character is not featured in the encoding map; this is because URI.js + // gives the colons in URNs semantic meaning as the delimiters of path segements, and so it + // should not appear unencoded in a segment itself. + // See also the note above about RFC3986 and capitalalized hex digits. + encode: { + expression: /%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/ig, + map: { + '%21': '!', + '%24': '$', + '%27': '\'', + '%28': '(', + '%29': ')', + '%2A': '*', + '%2B': '+', + '%2C': ',', + '%3B': ';', + '%3D': '=', + '%40': '@' + } + }, + // These characters are the characters called out by RFC2141 as "reserved" characters that + // should never appear in a URN, plus the colon character (see note above). + decode: { + expression: /[\/\?#:]/g, + map: { + '/': '%2F', + '?': '%3F', + '#': '%23', + ':': '%3A' + } + } + } + }; + + URI.encodeQuery = function (string, escapeQuerySpace) { + var escaped = URI.encode(string + ''); + + if (escapeQuerySpace === undefined) { + escapeQuerySpace = URI.escapeQuerySpace; + } + + return escapeQuerySpace ? escaped.replace(/%20/g, '+') : escaped; + }; + + URI.decodeQuery = function (string, escapeQuerySpace) { + string += ''; + + if (escapeQuerySpace === undefined) { + escapeQuerySpace = URI.escapeQuerySpace; + } + + try { + return URI.decode(escapeQuerySpace ? string.replace(/\+/g, '%20') : string); + } catch (e) { + // we're not going to mess with weird encodings, + // give up and return the undecoded original string + // see https://github.com/medialize/URI.js/issues/87 + // see https://github.com/medialize/URI.js/issues/92 + return string; + } + }; // generate encode/decode path functions + + + var _parts = { + 'encode': 'encode', + 'decode': 'decode' + }; + + var _part; + + var generateAccessor = function generateAccessor(_group, _part) { + return function (string) { + try { + return URI[_part](string + '').replace(URI.characters[_group][_part].expression, function (c) { + return URI.characters[_group][_part].map[c]; + }); + } catch (e) { + // we're not going to mess with weird encodings, + // give up and return the undecoded original string + // see https://github.com/medialize/URI.js/issues/87 + // see https://github.com/medialize/URI.js/issues/92 + return string; + } + }; + }; + + for (_part in _parts) { + URI[_part + 'PathSegment'] = generateAccessor('pathname', _parts[_part]); + URI[_part + 'UrnPathSegment'] = generateAccessor('urnpath', _parts[_part]); + } + + var generateSegmentedPathFunction = function generateSegmentedPathFunction(_sep, _codingFuncName, _innerCodingFuncName) { + return function (string) { + // Why pass in names of functions, rather than the function objects themselves? The + // definitions of some functions (but in particular, URI.decode) will occasionally change due + // to URI.js having ISO8859 and Unicode modes. Passing in the name and getting it will ensure + // that the functions we use here are "fresh". + var actualCodingFunc; + + if (!_innerCodingFuncName) { + actualCodingFunc = URI[_codingFuncName]; + } else { + actualCodingFunc = function actualCodingFunc(string) { + return URI[_codingFuncName](URI[_innerCodingFuncName](string)); + }; + } + + var segments = (string + '').split(_sep); + + for (var i = 0, length = segments.length; i < length; i++) { + segments[i] = actualCodingFunc(segments[i]); + } + + return segments.join(_sep); + }; + }; // This takes place outside the above loop because we don't want, e.g., encodeUrnPath functions. + + + URI.decodePath = generateSegmentedPathFunction('/', 'decodePathSegment'); + URI.decodeUrnPath = generateSegmentedPathFunction(':', 'decodeUrnPathSegment'); + URI.recodePath = generateSegmentedPathFunction('/', 'encodePathSegment', 'decode'); + URI.recodeUrnPath = generateSegmentedPathFunction(':', 'encodeUrnPathSegment', 'decode'); + URI.encodeReserved = generateAccessor('reserved', 'encode'); + + URI.parse = function (string, parts) { + var pos; + + if (!parts) { + parts = { + preventInvalidHostname: URI.preventInvalidHostname + }; + } // [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment] + // extract fragment + + + pos = string.indexOf('#'); + + if (pos > -1) { + // escaping? + parts.fragment = string.substring(pos + 1) || null; + string = string.substring(0, pos); + } // extract query + + + pos = string.indexOf('?'); + + if (pos > -1) { + // escaping? + parts.query = string.substring(pos + 1) || null; + string = string.substring(0, pos); + } // extract protocol + + + if (string.substring(0, 2) === '//') { + // relative-scheme + parts.protocol = null; + string = string.substring(2); // extract "user:pass@host:port" + + string = URI.parseAuthority(string, parts); + } else { + pos = string.indexOf(':'); + + if (pos > -1) { + parts.protocol = string.substring(0, pos) || null; + + if (parts.protocol && !parts.protocol.match(URI.protocol_expression)) { + // : may be within the path + parts.protocol = undefined; + } else if (string.substring(pos + 1, pos + 3) === '//') { + string = string.substring(pos + 3); // extract "user:pass@host:port" + + string = URI.parseAuthority(string, parts); + } else { + string = string.substring(pos + 1); + parts.urn = true; + } + } + } // what's left must be the path + + + parts.path = string; // and we're done + + return parts; + }; + + URI.parseHost = function (string, parts) { + if (!string) { + string = ''; + } // Copy chrome, IE, opera backslash-handling behavior. + // Back slashes before the query string get converted to forward slashes + // See: https://github.com/joyent/node/blob/386fd24f49b0e9d1a8a076592a404168faeecc34/lib/url.js#L115-L124 + // See: https://code.google.com/p/chromium/issues/detail?id=25916 + // https://github.com/medialize/URI.js/pull/233 + + + string = string.replace(/\\/g, '/'); // extract host:port + + var pos = string.indexOf('/'); + var bracketPos; + var t; + + if (pos === -1) { + pos = string.length; + } + + if (string.charAt(0) === '[') { + // IPv6 host - http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-04#section-6 + // I claim most client software breaks on IPv6 anyways. To simplify things, URI only accepts + // IPv6+port in the format [2001:db8::1]:80 (for the time being) + bracketPos = string.indexOf(']'); + parts.hostname = string.substring(1, bracketPos) || null; + parts.port = string.substring(bracketPos + 2, pos) || null; + + if (parts.port === '/') { + parts.port = null; + } + } else { + var firstColon = string.indexOf(':'); + var firstSlash = string.indexOf('/'); + var nextColon = string.indexOf(':', firstColon + 1); + + if (nextColon !== -1 && (firstSlash === -1 || nextColon < firstSlash)) { + // IPv6 host contains multiple colons - but no port + // this notation is actually not allowed by RFC 3986, but we're a liberal parser + parts.hostname = string.substring(0, pos) || null; + parts.port = null; + } else { + t = string.substring(0, pos).split(':'); + parts.hostname = t[0] || null; + parts.port = t[1] || null; + } + } + + if (parts.hostname && string.substring(pos).charAt(0) !== '/') { + pos++; + string = '/' + string; + } + + if (parts.preventInvalidHostname) { + URI.ensureValidHostname(parts.hostname, parts.protocol); + } + + if (parts.port) { + URI.ensureValidPort(parts.port); + } + + return string.substring(pos) || '/'; + }; + + URI.parseAuthority = function (string, parts) { + string = URI.parseUserinfo(string, parts); + return URI.parseHost(string, parts); + }; + + URI.parseUserinfo = function (string, parts) { + // extract username:password + var firstSlash = string.indexOf('/'); + var pos = string.lastIndexOf('@', firstSlash > -1 ? firstSlash : string.length - 1); + var t; // authority@ must come before /path + + if (pos > -1 && (firstSlash === -1 || pos < firstSlash)) { + t = string.substring(0, pos).split(':'); + parts.username = t[0] ? URI.decode(t[0]) : null; + t.shift(); + parts.password = t[0] ? URI.decode(t.join(':')) : null; + string = string.substring(pos + 1); + } else { + parts.username = null; + parts.password = null; + } + + return string; + }; + + URI.parseQuery = function (string, escapeQuerySpace) { + if (!string) { + return {}; + } // throw out the funky business - "?"[name"="value"&"]+ + + + string = string.replace(/&+/g, '&').replace(/^\?*&*|&+$/g, ''); + + if (!string) { + return {}; + } + + var items = {}; + var splits = string.split('&'); + var length = splits.length; + var v, name, value; + + for (var i = 0; i < length; i++) { + v = splits[i].split('='); + name = URI.decodeQuery(v.shift(), escapeQuerySpace); // no "=" is null according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters + + value = v.length ? URI.decodeQuery(v.join('='), escapeQuerySpace) : null; + + if (hasOwn.call(items, name)) { + if (typeof items[name] === 'string' || items[name] === null) { + items[name] = [items[name]]; + } + + items[name].push(value); + } else { + items[name] = value; + } + } + + return items; + }; + + URI.build = function (parts) { + var t = ''; + var requireAbsolutePath = false; + + if (parts.protocol) { + t += parts.protocol + ':'; + } + + if (!parts.urn && (t || parts.hostname)) { + t += '//'; + requireAbsolutePath = true; + } + + t += URI.buildAuthority(parts) || ''; + + if (typeof parts.path === 'string') { + if (parts.path.charAt(0) !== '/' && requireAbsolutePath) { + t += '/'; + } + + t += parts.path; + } + + if (typeof parts.query === 'string' && parts.query) { + t += '?' + parts.query; + } + + if (typeof parts.fragment === 'string' && parts.fragment) { + t += '#' + parts.fragment; + } + + return t; + }; + + URI.buildHost = function (parts) { + var t = ''; + + if (!parts.hostname) { + return ''; + } else if (URI.ip6_expression.test(parts.hostname)) { + t += '[' + parts.hostname + ']'; + } else { + t += parts.hostname; + } + + if (parts.port) { + t += ':' + parts.port; + } + + return t; + }; + + URI.buildAuthority = function (parts) { + return URI.buildUserinfo(parts) + URI.buildHost(parts); + }; + + URI.buildUserinfo = function (parts) { + var t = ''; + + if (parts.username) { + t += URI.encode(parts.username); + } + + if (parts.password) { + t += ':' + URI.encode(parts.password); + } + + if (t) { + t += '@'; + } + + return t; + }; + + URI.buildQuery = function (data, duplicateQueryParameters, escapeQuerySpace) { + // according to http://tools.ietf.org/html/rfc3986 or http://labs.apache.org/webarch/uri/rfc/rfc3986.html + // being »-._~!$&'()*+,;=:@/?« %HEX and alnum are allowed + // the RFC explicitly states ?/foo being a valid use case, no mention of parameter syntax! + // URI.js treats the query string as being application/x-www-form-urlencoded + // see http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type + var t = ''; + var unique, key, i, length; + + for (key in data) { + if (hasOwn.call(data, key)) { + if (isArray(data[key])) { + unique = {}; + + for (i = 0, length = data[key].length; i < length; i++) { + if (data[key][i] !== undefined && unique[data[key][i] + ''] === undefined) { + t += '&' + URI.buildQueryParameter(key, data[key][i], escapeQuerySpace); + + if (duplicateQueryParameters !== true) { + unique[data[key][i] + ''] = true; + } + } + } + } else if (data[key] !== undefined) { + t += '&' + URI.buildQueryParameter(key, data[key], escapeQuerySpace); + } + } + } + + return t.substring(1); + }; + + URI.buildQueryParameter = function (name, value, escapeQuerySpace) { + // http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type -- application/x-www-form-urlencoded + // don't append "=" for null values, according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#url-parameter-serialization + return URI.encodeQuery(name, escapeQuerySpace) + (value !== null ? '=' + URI.encodeQuery(value, escapeQuerySpace) : ''); + }; + + URI.addQuery = function (data, name, value) { + if (typeof name === 'object') { + for (var key in name) { + if (hasOwn.call(name, key)) { + URI.addQuery(data, key, name[key]); + } + } + } else if (typeof name === 'string') { + if (data[name] === undefined) { + data[name] = value; + return; + } else if (typeof data[name] === 'string') { + data[name] = [data[name]]; + } + + if (!isArray(value)) { + value = [value]; + } + + data[name] = (data[name] || []).concat(value); + } else { + throw new TypeError('URI.addQuery() accepts an object, string as the name parameter'); + } + }; + + URI.setQuery = function (data, name, value) { + if (typeof name === 'object') { + for (var key in name) { + if (hasOwn.call(name, key)) { + URI.setQuery(data, key, name[key]); + } + } + } else if (typeof name === 'string') { + data[name] = value === undefined ? null : value; + } else { + throw new TypeError('URI.setQuery() accepts an object, string as the name parameter'); + } + }; + + URI.removeQuery = function (data, name, value) { + var i, length, key; + + if (isArray(name)) { + for (i = 0, length = name.length; i < length; i++) { + data[name[i]] = undefined; + } + } else if (getType(name) === 'RegExp') { + for (key in data) { + if (name.test(key)) { + data[key] = undefined; + } + } + } else if (typeof name === 'object') { + for (key in name) { + if (hasOwn.call(name, key)) { + URI.removeQuery(data, key, name[key]); + } + } + } else if (typeof name === 'string') { + if (value !== undefined) { + if (getType(value) === 'RegExp') { + if (!isArray(data[name]) && value.test(data[name])) { + data[name] = undefined; + } else { + data[name] = filterArrayValues(data[name], value); + } + } else if (data[name] === String(value) && (!isArray(value) || value.length === 1)) { + data[name] = undefined; + } else if (isArray(data[name])) { + data[name] = filterArrayValues(data[name], value); + } + } else { + data[name] = undefined; + } + } else { + throw new TypeError('URI.removeQuery() accepts an object, string, RegExp as the first parameter'); + } + }; + + URI.hasQuery = function (data, name, value, withinArray) { + switch (getType(name)) { + case 'String': + // Nothing to do here + break; + + case 'RegExp': + for (var key in data) { + if (hasOwn.call(data, key)) { + if (name.test(key) && (value === undefined || URI.hasQuery(data, key, value))) { + return true; + } + } + } + + return false; + + case 'Object': + for (var _key in name) { + if (hasOwn.call(name, _key)) { + if (!URI.hasQuery(data, _key, name[_key])) { + return false; + } + } + } + + return true; + + default: + throw new TypeError('URI.hasQuery() accepts a string, regular expression or object as the name parameter'); + } + + switch (getType(value)) { + case 'Undefined': + // true if exists (but may be empty) + return name in data; + // data[name] !== undefined; + + case 'Boolean': + // true if exists and non-empty + var _booly = Boolean(isArray(data[name]) ? data[name].length : data[name]); + + return value === _booly; + + case 'Function': + // allow complex comparison + return !!value(data[name], name, data); + + case 'Array': + if (!isArray(data[name])) { + return false; + } + + var op = withinArray ? arrayContains : arraysEqual; + return op(data[name], value); + + case 'RegExp': + if (!isArray(data[name])) { + return Boolean(data[name] && data[name].match(value)); + } + + if (!withinArray) { + return false; + } + + return arrayContains(data[name], value); + + case 'Number': + value = String(value); + + /* falls through */ + + case 'String': + if (!isArray(data[name])) { + return data[name] === value; + } + + if (!withinArray) { + return false; + } + + return arrayContains(data[name], value); + + default: + throw new TypeError('URI.hasQuery() accepts undefined, boolean, string, number, RegExp, Function as the value parameter'); + } + }; + + URI.joinPaths = function () { + var input = []; + var segments = []; + var nonEmptySegments = 0; + + for (var i = 0; i < arguments.length; i++) { + var url = new URI(arguments[i]); + input.push(url); + + var _segments = url.segment(); + + for (var s = 0; s < _segments.length; s++) { + if (typeof _segments[s] === 'string') { + segments.push(_segments[s]); + } + + if (_segments[s]) { + nonEmptySegments++; + } + } + } + + if (!segments.length || !nonEmptySegments) { + return new URI(''); + } + + var uri = new URI('').segment(segments); + + if (input[0].path() === '' || input[0].path().slice(0, 1) === '/') { + uri.path('/' + uri.path()); + } + + return uri.normalize(); + }; + + URI.commonPath = function (one, two) { + var length = Math.min(one.length, two.length); + var pos; // find first non-matching character + + for (pos = 0; pos < length; pos++) { + if (one.charAt(pos) !== two.charAt(pos)) { + pos--; + break; + } + } + + if (pos < 1) { + return one.charAt(0) === two.charAt(0) && one.charAt(0) === '/' ? '/' : ''; + } // revert to last / + + + if (one.charAt(pos) !== '/' || two.charAt(pos) !== '/') { + pos = one.substring(0, pos).lastIndexOf('/'); + } + + return one.substring(0, pos + 1); + }; + + URI.withinString = function (string, callback, options) { + options || (options = {}); + + var _start = options.start || URI.findUri.start; + + var _end = options.end || URI.findUri.end; + + var _trim = options.trim || URI.findUri.trim; + + var _parens = options.parens || URI.findUri.parens; + + var _attributeOpen = /[a-z0-9-]=["']?$/i; + _start.lastIndex = 0; + + while (true) { + var match = _start.exec(string); + + if (!match) { + break; + } + + var start = match.index; + + if (options.ignoreHtml) { + // attribut(e=["']?$) + var attributeOpen = string.slice(Math.max(start - 3, 0), start); + + if (attributeOpen && _attributeOpen.test(attributeOpen)) { + continue; + } + } + + var end = start + string.slice(start).search(_end); + var slice = string.slice(start, end); // make sure we include well balanced parens + + var parensEnd = -1; + + while (true) { + var parensMatch = _parens.exec(slice); + + if (!parensMatch) { + break; + } + + var parensMatchEnd = parensMatch.index + parensMatch[0].length; + parensEnd = Math.max(parensEnd, parensMatchEnd); + } + + if (parensEnd > -1) { + slice = slice.slice(0, parensEnd) + slice.slice(parensEnd).replace(_trim, ''); + } else { + slice = slice.replace(_trim, ''); + } + + if (slice.length <= match[0].length) { + // the extract only contains the starting marker of a URI, + // e.g. "www" or "http://" + continue; + } + + if (options.ignore && options.ignore.test(slice)) { + continue; + } + + end = start + slice.length; + var result = callback(slice, start, end, string); + + if (result === undefined) { + _start.lastIndex = end; + continue; + } + + result = String(result); + string = string.slice(0, start) + result + string.slice(end); + _start.lastIndex = start + result.length; + } + + _start.lastIndex = 0; + return string; + }; + + URI.ensureValidHostname = function (v, protocol) { + // Theoretically URIs allow percent-encoding in Hostnames (according to RFC 3986) + // they are not part of DNS and therefore ignored by URI.js + var hasHostname = !!v; // not null and not an empty string + + var hasProtocol = !!protocol; + var rejectEmptyHostname = false; + + if (hasProtocol) { + rejectEmptyHostname = arrayContains(URI.hostProtocols, protocol); + } + + if (rejectEmptyHostname && !hasHostname) { + throw new TypeError('Hostname cannot be empty, if protocol is ' + protocol); + } else if (v && v.match(URI.invalid_hostname_characters)) { + // test punycode + if (!punycode) { + throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available'); + } + + if (punycode.toASCII(v).match(URI.invalid_hostname_characters)) { + throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_]'); + } + } + }; + + URI.ensureValidPort = function (v) { + if (!v) { + return; + } + + var port = Number(v); + + if (isInteger(port) && port > 0 && port < 65536) { + return; + } + + throw new TypeError('Port "' + v + '" is not a valid port'); + }; // noConflict + + + URI.noConflict = function (removeAll) { + if (removeAll) { + var unconflicted = { + URI: this.noConflict() + }; + + if (root.URITemplate && typeof root.URITemplate.noConflict === 'function') { + unconflicted.URITemplate = root.URITemplate.noConflict(); + } + + if (root.IPv6 && typeof root.IPv6.noConflict === 'function') { + unconflicted.IPv6 = root.IPv6.noConflict(); + } + + if (root.SecondLevelDomains && typeof root.SecondLevelDomains.noConflict === 'function') { + unconflicted.SecondLevelDomains = root.SecondLevelDomains.noConflict(); + } + + return unconflicted; + } else if (root.URI === this) { + root.URI = _URI; + } + + return this; + }; + + p.build = function (deferBuild) { + if (deferBuild === true) { + this._deferred_build = true; + } else if (deferBuild === undefined || this._deferred_build) { + this._string = URI.build(this._parts); + this._deferred_build = false; + } + + return this; + }; + + p.clone = function () { + return new URI(this); + }; + + p.valueOf = p.toString = function () { + return this.build(false)._string; + }; + + function generateSimpleAccessor(_part) { + return function (v, build) { + if (v === undefined) { + return this._parts[_part] || ''; + } else { + this._parts[_part] = v || null; + this.build(!build); + return this; + } + }; + } + + function generatePrefixAccessor(_part, _key) { + return function (v, build) { + if (v === undefined) { + return this._parts[_part] || ''; + } else { + if (v !== null) { + v = v + ''; + + if (v.charAt(0) === _key) { + v = v.substring(1); + } + } + + this._parts[_part] = v; + this.build(!build); + return this; + } + }; + } + + p.protocol = generateSimpleAccessor('protocol'); + p.username = generateSimpleAccessor('username'); + p.password = generateSimpleAccessor('password'); + p.hostname = generateSimpleAccessor('hostname'); + p.port = generateSimpleAccessor('port'); + p.query = generatePrefixAccessor('query', '?'); + p.fragment = generatePrefixAccessor('fragment', '#'); + + p.search = function (v, build) { + var t = this.query(v, build); + return typeof t === 'string' && t.length ? '?' + t : t; + }; + + p.hash = function (v, build) { + var t = this.fragment(v, build); + return typeof t === 'string' && t.length ? '#' + t : t; + }; + + p.pathname = function (v, build) { + if (v === undefined || v === true) { + var res = this._parts.path || (this._parts.hostname ? '/' : ''); + return v ? (this._parts.urn ? URI.decodeUrnPath : URI.decodePath)(res) : res; + } else { + if (this._parts.urn) { + this._parts.path = v ? URI.recodeUrnPath(v) : ''; + } else { + this._parts.path = v ? URI.recodePath(v) : '/'; + } + + this.build(!build); + return this; + } + }; + + p.path = p.pathname; + + p.href = function (href, build) { + var key; + + if (href === undefined) { + return this.toString(); + } + + this._string = ''; + this._parts = URI._parts(); + + var _URI = href instanceof URI; + + var _object = typeof href === 'object' && (href.hostname || href.path || href.pathname); + + if (href.nodeName) { + var attribute = URI.getDomAttribute(href); + href = href[attribute] || ''; + _object = false; + } // window.location is reported to be an object, but it's not the sort + // of object we're looking for: + // * location.protocol ends with a colon + // * location.query != object.search + // * location.hash != object.fragment + // simply serializing the unknown object should do the trick + // (for location, not for everything...) + + + if (!_URI && _object && href.pathname !== undefined) { + href = href.toString(); + } + + if (typeof href === 'string' || href instanceof String) { + this._parts = URI.parse(String(href), this._parts); + } else if (_URI || _object) { + var src = _URI ? href._parts : href; + + for (key in src) { + if (key === 'query') { + continue; + } + + if (hasOwn.call(this._parts, key)) { + this._parts[key] = src[key]; + } + } + + if (src.query) { + this.query(src.query, false); + } + } else { + throw new TypeError('invalid input'); + } + + this.build(!build); + return this; + }; // identification accessors + + + p.is = function (what) { + var ip = false; + var ip4 = false; + var ip6 = false; + var name = false; + var sld = false; + var idn = false; + var punycode = false; + var relative = !this._parts.urn; + + if (this._parts.hostname) { + relative = false; + ip4 = URI.ip4_expression.test(this._parts.hostname); + ip6 = URI.ip6_expression.test(this._parts.hostname); + ip = ip4 || ip6; + name = !ip; + sld = name && SLD && SLD.has(this._parts.hostname); + idn = name && URI.idn_expression.test(this._parts.hostname); + punycode = name && URI.punycode_expression.test(this._parts.hostname); + } + + switch (what.toLowerCase()) { + case 'relative': + return relative; + + case 'absolute': + return !relative; + // hostname identification + + case 'domain': + case 'name': + return name; + + case 'sld': + return sld; + + case 'ip': + return ip; + + case 'ip4': + case 'ipv4': + case 'inet4': + return ip4; + + case 'ip6': + case 'ipv6': + case 'inet6': + return ip6; + + case 'idn': + return idn; + + case 'url': + return !this._parts.urn; + + case 'urn': + return !!this._parts.urn; + + case 'punycode': + return punycode; + } + + return null; + }; // component specific input validation + + + var _protocol = p.protocol; + var _port = p.port; + var _hostname = p.hostname; + + p.protocol = function (v, build) { + if (v) { + // accept trailing :// + v = v.replace(/:(\/\/)?$/, ''); + + if (!v.match(URI.protocol_expression)) { + throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]'); + } + } + + return _protocol.call(this, v, build); + }; + + p.scheme = p.protocol; + + p.port = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v !== undefined) { + if (v === 0) { + v = null; + } + + if (v) { + v += ''; + + if (v.charAt(0) === ':') { + v = v.substring(1); + } + + URI.ensureValidPort(v); + } + } + + return _port.call(this, v, build); + }; + + p.hostname = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v !== undefined) { + var x = { + preventInvalidHostname: this._parts.preventInvalidHostname + }; + var res = URI.parseHost(v, x); + + if (res !== '/') { + throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]'); + } + + v = x.hostname; + + if (this._parts.preventInvalidHostname) { + URI.ensureValidHostname(v, this._parts.protocol); + } + } + + return _hostname.call(this, v, build); + }; // compound accessors + + + p.origin = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v === undefined) { + var protocol = this.protocol(); + var authority = this.authority(); + + if (!authority) { + return ''; + } + + return (protocol ? protocol + '://' : '') + this.authority(); + } else { + var origin = URI(v); + this.protocol(origin.protocol()).authority(origin.authority()).build(!build); + return this; + } + }; + + p.host = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v === undefined) { + return this._parts.hostname ? URI.buildHost(this._parts) : ''; + } else { + var res = URI.parseHost(v, this._parts); + + if (res !== '/') { + throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]'); + } + + this.build(!build); + return this; + } + }; + + p.authority = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v === undefined) { + return this._parts.hostname ? URI.buildAuthority(this._parts) : ''; + } else { + var res = URI.parseAuthority(v, this._parts); + + if (res !== '/') { + throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]'); + } + + this.build(!build); + return this; + } + }; + + p.userinfo = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v === undefined) { + var t = URI.buildUserinfo(this._parts); + return t ? t.substring(0, t.length - 1) : t; + } else { + if (v[v.length - 1] !== '@') { + v += '@'; + } + + URI.parseUserinfo(v, this._parts); + this.build(!build); + return this; + } + }; + + p.resource = function (v, build) { + var parts; + + if (v === undefined) { + return this.path() + this.search() + this.hash(); + } + + parts = URI.parse(v); + this._parts.path = parts.path; + this._parts.query = parts.query; + this._parts.fragment = parts.fragment; + this.build(!build); + return this; + }; // fraction accessors + + + p.subdomain = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } // convenience, return "www" from "www.example.org" + + + if (v === undefined) { + if (!this._parts.hostname || this.is('IP')) { + return ''; + } // grab domain and add another segment + + + var end = this._parts.hostname.length - this.domain().length - 1; + return this._parts.hostname.substring(0, end) || ''; + } else { + var e = this._parts.hostname.length - this.domain().length; + + var sub = this._parts.hostname.substring(0, e); + + var replace = new RegExp('^' + escapeRegEx(sub)); + + if (v && v.charAt(v.length - 1) !== '.') { + v += '.'; + } + + if (v.indexOf(':') !== -1) { + throw new TypeError('Domains cannot contain colons'); + } + + if (v) { + URI.ensureValidHostname(v, this._parts.protocol); + } + + this._parts.hostname = this._parts.hostname.replace(replace, v); + this.build(!build); + return this; + } + }; + + p.domain = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (typeof v === 'boolean') { + build = v; + v = undefined; + } // convenience, return "example.org" from "www.example.org" + + + if (v === undefined) { + if (!this._parts.hostname || this.is('IP')) { + return ''; + } // if hostname consists of 1 or 2 segments, it must be the domain + + + var t = this._parts.hostname.match(/\./g); + + if (t && t.length < 2) { + return this._parts.hostname; + } // grab tld and add another segment + + + var end = this._parts.hostname.length - this.tld(build).length - 1; + end = this._parts.hostname.lastIndexOf('.', end - 1) + 1; + return this._parts.hostname.substring(end) || ''; + } else { + if (!v) { + throw new TypeError('cannot set domain empty'); + } + + if (v.indexOf(':') !== -1) { + throw new TypeError('Domains cannot contain colons'); + } + + URI.ensureValidHostname(v, this._parts.protocol); + + if (!this._parts.hostname || this.is('IP')) { + this._parts.hostname = v; + } else { + var replace = new RegExp(escapeRegEx(this.domain()) + '$'); + this._parts.hostname = this._parts.hostname.replace(replace, v); + } + + this.build(!build); + return this; + } + }; + + p.tld = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (typeof v === 'boolean') { + build = v; + v = undefined; + } // return "org" from "www.example.org" + + + if (v === undefined) { + if (!this._parts.hostname || this.is('IP')) { + return ''; + } + + var pos = this._parts.hostname.lastIndexOf('.'); + + var tld = this._parts.hostname.substring(pos + 1); + + if (build !== true && SLD && SLD.list[tld.toLowerCase()]) { + return SLD.get(this._parts.hostname) || tld; + } + + return tld; + } else { + var replace; + + if (!v) { + throw new TypeError('cannot set TLD empty'); + } else if (v.match(/[^a-zA-Z0-9-]/)) { + if (SLD && SLD.is(v)) { + replace = new RegExp(escapeRegEx(this.tld()) + '$'); + this._parts.hostname = this._parts.hostname.replace(replace, v); + } else { + throw new TypeError('TLD "' + v + '" contains characters other than [A-Z0-9]'); + } + } else if (!this._parts.hostname || this.is('IP')) { + throw new ReferenceError('cannot set TLD on non-domain host'); + } else { + replace = new RegExp(escapeRegEx(this.tld()) + '$'); + this._parts.hostname = this._parts.hostname.replace(replace, v); + } + + this.build(!build); + return this; + } + }; + + p.directory = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v === undefined || v === true) { + if (!this._parts.path && !this._parts.hostname) { + return ''; + } + + if (this._parts.path === '/') { + return '/'; + } + + var end = this._parts.path.length - this.filename().length - 1; + var res = this._parts.path.substring(0, end) || (this._parts.hostname ? '/' : ''); + return v ? URI.decodePath(res) : res; + } else { + var e = this._parts.path.length - this.filename().length; + + var directory = this._parts.path.substring(0, e); + + var replace = new RegExp('^' + escapeRegEx(directory)); // fully qualifier directories begin with a slash + + if (!this.is('relative')) { + if (!v) { + v = '/'; + } + + if (v.charAt(0) !== '/') { + v = '/' + v; + } + } // directories always end with a slash + + + if (v && v.charAt(v.length - 1) !== '/') { + v += '/'; + } + + v = URI.recodePath(v); + this._parts.path = this._parts.path.replace(replace, v); + this.build(!build); + return this; + } + }; + + p.filename = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (typeof v !== 'string') { + if (!this._parts.path || this._parts.path === '/') { + return ''; + } + + var pos = this._parts.path.lastIndexOf('/'); + + var res = this._parts.path.substring(pos + 1); + + return v ? URI.decodePathSegment(res) : res; + } else { + var mutatedDirectory = false; + + if (v.charAt(0) === '/') { + v = v.substring(1); + } + + if (v.match(/\.?\//)) { + mutatedDirectory = true; + } + + var replace = new RegExp(escapeRegEx(this.filename()) + '$'); + v = URI.recodePath(v); + this._parts.path = this._parts.path.replace(replace, v); + + if (mutatedDirectory) { + this.normalizePath(build); + } else { + this.build(!build); + } + + return this; + } + }; + + p.suffix = function (v, build) { + if (this._parts.urn) { + return v === undefined ? '' : this; + } + + if (v === undefined || v === true) { + if (!this._parts.path || this._parts.path === '/') { + return ''; + } + + var filename = this.filename(); + var pos = filename.lastIndexOf('.'); + var s, res; + + if (pos === -1) { + return ''; + } // suffix may only contain alnum characters (yup, I made this up.) + + + s = filename.substring(pos + 1); + res = /^[a-z0-9%]+$/i.test(s) ? s : ''; + return v ? URI.decodePathSegment(res) : res; + } else { + if (v.charAt(0) === '.') { + v = v.substring(1); + } + + var suffix = this.suffix(); + var replace; + + if (!suffix) { + if (!v) { + return this; + } + + this._parts.path += '.' + URI.recodePath(v); + } else if (!v) { + replace = new RegExp(escapeRegEx('.' + suffix) + '$'); + } else { + replace = new RegExp(escapeRegEx(suffix) + '$'); + } + + if (replace) { + v = URI.recodePath(v); + this._parts.path = this._parts.path.replace(replace, v); + } + + this.build(!build); + return this; + } + }; + + p.segment = function (segment, v, build) { + var separator = this._parts.urn ? ':' : '/'; + var path = this.path(); + var absolute = path.substring(0, 1) === '/'; + var segments = path.split(separator); + + if (segment !== undefined && typeof segment !== 'number') { + build = v; + v = segment; + segment = undefined; + } + + if (segment !== undefined && typeof segment !== 'number') { + throw new Error('Bad segment "' + segment + '", must be 0-based integer'); + } + + if (absolute) { + segments.shift(); + } + + if (segment < 0) { + // allow negative indexes to address from the end + segment = Math.max(segments.length + segment, 0); + } + + if (v === undefined) { + /*jshint laxbreak: true */ + return segment === undefined ? segments : segments[segment]; + /*jshint laxbreak: false */ + } else if (segment === null || segments[segment] === undefined) { + if (isArray(v)) { + segments = []; // collapse empty elements within array + + for (var i = 0, l = v.length; i < l; i++) { + if (!v[i].length && (!segments.length || !segments[segments.length - 1].length)) { + continue; + } + + if (segments.length && !segments[segments.length - 1].length) { + segments.pop(); + } + + segments.push(trimSlashes(v[i])); + } + } else if (v || typeof v === 'string') { + v = trimSlashes(v); + + if (segments[segments.length - 1] === '') { + // empty trailing elements have to be overwritten + // to prevent results such as /foo//bar + segments[segments.length - 1] = v; + } else { + segments.push(v); + } + } + } else { + if (v) { + segments[segment] = trimSlashes(v); + } else { + segments.splice(segment, 1); + } + } + + if (absolute) { + segments.unshift(''); + } + + return this.path(segments.join(separator), build); + }; + + p.segmentCoded = function (segment, v, build) { + var segments, i, l; + + if (typeof segment !== 'number') { + build = v; + v = segment; + segment = undefined; + } + + if (v === undefined) { + segments = this.segment(segment, v, build); + + if (!isArray(segments)) { + segments = segments !== undefined ? URI.decode(segments) : undefined; + } else { + for (i = 0, l = segments.length; i < l; i++) { + segments[i] = URI.decode(segments[i]); + } + } + + return segments; + } + + if (!isArray(v)) { + v = typeof v === 'string' || v instanceof String ? URI.encode(v) : v; + } else { + for (i = 0, l = v.length; i < l; i++) { + v[i] = URI.encode(v[i]); + } + } + + return this.segment(segment, v, build); + }; // mutating query string + + + var q = p.query; + + p.query = function (v, build) { + if (v === true) { + return URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace); + } else if (typeof v === 'function') { + var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace); + var result = v.call(this, data); + this._parts.query = URI.buildQuery(result || data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace); + this.build(!build); + return this; + } else if (v !== undefined && typeof v !== 'string') { + this._parts.query = URI.buildQuery(v, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace); + this.build(!build); + return this; + } else { + return q.call(this, v, build); + } + }; + + p.setQuery = function (name, value, build) { + var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace); + + if (typeof name === 'string' || name instanceof String) { + data[name] = value !== undefined ? value : null; + } else if (typeof name === 'object') { + for (var key in name) { + if (hasOwn.call(name, key)) { + data[key] = name[key]; + } + } + } else { + throw new TypeError('URI.addQuery() accepts an object, string as the name parameter'); + } + + this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace); + + if (typeof name !== 'string') { + build = value; + } + + this.build(!build); + return this; + }; + + p.addQuery = function (name, value, build) { + var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace); + URI.addQuery(data, name, value === undefined ? null : value); + this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace); + + if (typeof name !== 'string') { + build = value; + } + + this.build(!build); + return this; + }; + + p.removeQuery = function (name, value, build) { + var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace); + URI.removeQuery(data, name, value); + this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace); + + if (typeof name !== 'string') { + build = value; + } + + this.build(!build); + return this; + }; + + p.hasQuery = function (name, value, withinArray) { + var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace); + return URI.hasQuery(data, name, value, withinArray); + }; + + p.setSearch = p.setQuery; + p.addSearch = p.addQuery; + p.removeSearch = p.removeQuery; + p.hasSearch = p.hasQuery; // sanitizing URLs + + p.normalize = function () { + if (this._parts.urn) { + return this.normalizeProtocol(false).normalizePath(false).normalizeQuery(false).normalizeFragment(false).build(); + } + + return this.normalizeProtocol(false).normalizeHostname(false).normalizePort(false).normalizePath(false).normalizeQuery(false).normalizeFragment(false).build(); + }; + + p.normalizeProtocol = function (build) { + if (typeof this._parts.protocol === 'string') { + this._parts.protocol = this._parts.protocol.toLowerCase(); + this.build(!build); + } + + return this; + }; + + p.normalizeHostname = function (build) { + if (this._parts.hostname) { + if (this.is('IDN') && punycode) { + this._parts.hostname = punycode.toASCII(this._parts.hostname); + } else if (this.is('IPv6') && IPv6) { + this._parts.hostname = IPv6.best(this._parts.hostname); + } + + this._parts.hostname = this._parts.hostname.toLowerCase(); + this.build(!build); + } + + return this; + }; + + p.normalizePort = function (build) { + // remove port of it's the protocol's default + if (typeof this._parts.protocol === 'string' && this._parts.port === URI.defaultPorts[this._parts.protocol]) { + this._parts.port = null; + this.build(!build); + } + + return this; + }; + + p.normalizePath = function (build) { + var _path = this._parts.path; + + if (!_path) { + return this; + } + + if (this._parts.urn) { + this._parts.path = URI.recodeUrnPath(this._parts.path); + this.build(!build); + return this; + } + + if (this._parts.path === '/') { + return this; + } + + _path = URI.recodePath(_path); + + var _was_relative; + + var _leadingParents = ''; + + var _parent, _pos; // handle relative paths + + + if (_path.charAt(0) !== '/') { + _was_relative = true; + _path = '/' + _path; + } // handle relative files (as opposed to directories) + + + if (_path.slice(-3) === '/..' || _path.slice(-2) === '/.') { + _path += '/'; + } // resolve simples + + + _path = _path.replace(/(\/(\.\/)+)|(\/\.$)/g, '/').replace(/\/{2,}/g, '/'); // remember leading parents + + if (_was_relative) { + _leadingParents = _path.substring(1).match(/^(\.\.\/)+/) || ''; + + if (_leadingParents) { + _leadingParents = _leadingParents[0]; + } + } // resolve parents + + + while (true) { + _parent = _path.search(/\/\.\.(\/|$)/); + + if (_parent === -1) { + // no more ../ to resolve + break; + } else if (_parent === 0) { + // top level cannot be relative, skip it + _path = _path.substring(3); + continue; + } + + _pos = _path.substring(0, _parent).lastIndexOf('/'); + + if (_pos === -1) { + _pos = _parent; + } + + _path = _path.substring(0, _pos) + _path.substring(_parent + 3); + } // revert to relative + + + if (_was_relative && this.is('relative')) { + _path = _leadingParents + _path.substring(1); + } + + this._parts.path = _path; + this.build(!build); + return this; + }; + + p.normalizePathname = p.normalizePath; + + p.normalizeQuery = function (build) { + if (typeof this._parts.query === 'string') { + if (!this._parts.query.length) { + this._parts.query = null; + } else { + this.query(URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace)); + } + + this.build(!build); + } + + return this; + }; + + p.normalizeFragment = function (build) { + if (!this._parts.fragment) { + this._parts.fragment = null; + this.build(!build); + } + + return this; + }; + + p.normalizeSearch = p.normalizeQuery; + p.normalizeHash = p.normalizeFragment; + + p.iso8859 = function () { + // expect unicode input, iso8859 output + var e = URI.encode; + var d = URI.decode; + URI.encode = escape; + URI.decode = decodeURIComponent; + + try { + this.normalize(); + } finally { + URI.encode = e; + URI.decode = d; + } + + return this; + }; + + p.unicode = function () { + // expect iso8859 input, unicode output + var e = URI.encode; + var d = URI.decode; + URI.encode = strictEncodeURIComponent; + URI.decode = unescape; + + try { + this.normalize(); + } finally { + URI.encode = e; + URI.decode = d; + } + + return this; + }; + + p.readable = function () { + var uri = this.clone(); // removing username, password, because they shouldn't be displayed according to RFC 3986 + + uri.username('').password('').normalize(); + var t = ''; + + if (uri._parts.protocol) { + t += uri._parts.protocol + '://'; + } + + if (uri._parts.hostname) { + if (uri.is('punycode') && punycode) { + t += punycode.toUnicode(uri._parts.hostname); + + if (uri._parts.port) { + t += ':' + uri._parts.port; + } + } else { + t += uri.host(); + } + } + + if (uri._parts.hostname && uri._parts.path && uri._parts.path.charAt(0) !== '/') { + t += '/'; + } + + t += uri.path(true); + + if (uri._parts.query) { + var q = ''; + + for (var i = 0, qp = uri._parts.query.split('&'), l = qp.length; i < l; i++) { + var kv = (qp[i] || '').split('='); + q += '&' + URI.decodeQuery(kv[0], this._parts.escapeQuerySpace).replace(/&/g, '%26'); + + if (kv[1] !== undefined) { + q += '=' + URI.decodeQuery(kv[1], this._parts.escapeQuerySpace).replace(/&/g, '%26'); + } + } + + t += '?' + q.substring(1); + } + + t += URI.decodeQuery(uri.hash(), true); + return t; + }; // resolving relative and absolute URLs + + + p.absoluteTo = function (base) { + var resolved = this.clone(); + var properties = ['protocol', 'username', 'password', 'hostname', 'port']; + var basedir, i, p; + + if (this._parts.urn) { + throw new Error('URNs do not have any generally defined hierarchical components'); + } + + if (!(base instanceof URI)) { + base = new URI(base); + } + + if (resolved._parts.protocol) { + // Directly returns even if this._parts.hostname is empty. + return resolved; + } else { + resolved._parts.protocol = base._parts.protocol; + } + + if (this._parts.hostname) { + return resolved; + } + + for (i = 0; p = properties[i]; i++) { + resolved._parts[p] = base._parts[p]; + } + + if (!resolved._parts.path) { + resolved._parts.path = base._parts.path; + + if (!resolved._parts.query) { + resolved._parts.query = base._parts.query; + } + } else { + if (resolved._parts.path.substring(-2) === '..') { + resolved._parts.path += '/'; + } + + if (resolved.path().charAt(0) !== '/') { + basedir = base.directory(); + basedir = basedir ? basedir : base.path().indexOf('/') === 0 ? '/' : ''; + resolved._parts.path = (basedir ? basedir + '/' : '') + resolved._parts.path; + resolved.normalizePath(); + } + } + + resolved.build(); + return resolved; + }; + + p.relativeTo = function (base) { + var relative = this.clone().normalize(); + var relativeParts, baseParts, common, relativePath, basePath; + + if (relative._parts.urn) { + throw new Error('URNs do not have any generally defined hierarchical components'); + } + + base = new URI(base).normalize(); + relativeParts = relative._parts; + baseParts = base._parts; + relativePath = relative.path(); + basePath = base.path(); + + if (relativePath.charAt(0) !== '/') { + throw new Error('URI is already relative'); + } + + if (basePath.charAt(0) !== '/') { + throw new Error('Cannot calculate a URI relative to another relative URI'); + } + + if (relativeParts.protocol === baseParts.protocol) { + relativeParts.protocol = null; + } + + if (relativeParts.username !== baseParts.username || relativeParts.password !== baseParts.password) { + return relative.build(); + } + + if (relativeParts.protocol !== null || relativeParts.username !== null || relativeParts.password !== null) { + return relative.build(); + } + + if (relativeParts.hostname === baseParts.hostname && relativeParts.port === baseParts.port) { + relativeParts.hostname = null; + relativeParts.port = null; + } else { + return relative.build(); + } + + if (relativePath === basePath) { + relativeParts.path = ''; + return relative.build(); + } // determine common sub path + + + common = URI.commonPath(relativePath, basePath); // If the paths have nothing in common, return a relative URL with the absolute path. + + if (!common) { + return relative.build(); + } + + var parents = baseParts.path.substring(common.length).replace(/[^\/]*$/, '').replace(/.*?\//g, '../'); + relativeParts.path = parents + relativeParts.path.substring(common.length) || './'; + return relative.build(); + }; // comparing URIs + + + p.equals = function (uri) { + var one = this.clone(); + var two = new URI(uri); + var one_map = {}; + var two_map = {}; + var checked = {}; + var one_query, two_query, key; + one.normalize(); + two.normalize(); // exact match + + if (one.toString() === two.toString()) { + return true; + } // extract query string + + + one_query = one.query(); + two_query = two.query(); + one.query(''); + two.query(''); // definitely not equal if not even non-query parts match + + if (one.toString() !== two.toString()) { + return false; + } // query parameters have the same length, even if they're permuted + + + if (one_query.length !== two_query.length) { + return false; + } + + one_map = URI.parseQuery(one_query, this._parts.escapeQuerySpace); + two_map = URI.parseQuery(two_query, this._parts.escapeQuerySpace); + + for (key in one_map) { + if (hasOwn.call(one_map, key)) { + if (!isArray(one_map[key])) { + if (one_map[key] !== two_map[key]) { + return false; + } + } else if (!arraysEqual(one_map[key], two_map[key])) { + return false; + } + + checked[key] = true; + } + } + + for (key in two_map) { + if (hasOwn.call(two_map, key)) { + if (!checked[key]) { + // two contains a parameter not present in one + return false; + } + } + } + + return true; + }; // state + + + p.preventInvalidHostname = function (v) { + this._parts.preventInvalidHostname = !!v; + return this; + }; + + p.duplicateQueryParameters = function (v) { + this._parts.duplicateQueryParameters = !!v; + return this; + }; + + p.escapeQuerySpace = function (v) { + this._parts.escapeQuerySpace = !!v; + return this; + }; + + return URI; +}); + +/***/ }), +/* 36 */ +/***/ (function(module, exports, __webpack_require__) { + +var baseIndexOf = __webpack_require__(113), + isArrayLike = __webpack_require__(29), + isString = __webpack_require__(114), + toInteger = __webpack_require__(70), + values = __webpack_require__(92); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Checks if `value` is in `collection`. If `collection` is a string, it's + * checked for a substring of `value`, otherwise + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'a': 1, 'b': 2 }, 1); + * // => true + * + * _.includes('abcd', 'bc'); + * // => true + */ +function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); +} + +module.exports = includes; + + +/***/ }), +/* 37 */ +/***/ (function(module, exports) { + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); +} + +module.exports = isIndex; + + +/***/ }), +/* 38 */ +/***/ (function(module, exports) { + +/** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ +function identity(value) { + return value; +} + +module.exports = identity; + + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + +var isSymbol = __webpack_require__(48); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +module.exports = toKey; + + +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { + +var anObject = __webpack_require__(26); +var IE8_DOM_DEFINE = __webpack_require__(451); +var toPrimitive = __webpack_require__(452); +var dP = Object.defineProperty; + +exports.f = __webpack_require__(32) ? Object.defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; + + +/***/ }), +/* 41 */ +/***/ (function(module, exports) { + +module.exports = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; +}; + + +/***/ }), +/* 42 */ +/***/ (function(module, exports) { + +module.exports = {}; + + +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.17.20'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Error message constants. */ + var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', + FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** Used to compose bitmasks for cloning. */ + var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** Used to compose bitmasks for function metadata. */ + var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256, + WRAP_FLIP_FLAG = 512; + + /** Used as default options for `_.truncate`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** Used to associate wrap methods with their bit flags. */ + var wrapFlags = [ + ['ary', WRAP_ARY_FLAG], + ['bind', WRAP_BIND_FLAG], + ['bindKey', WRAP_BIND_KEY_FLAG], + ['curry', WRAP_CURRY_FLAG], + ['curryRight', WRAP_CURRY_RIGHT_FLAG], + ['flip', WRAP_FLIP_FLAG], + ['partial', WRAP_PARTIAL_FLAG], + ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], + ['rearg', WRAP_REARG_FLAG] + ]; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + domExcTag = '[object DOMException]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + undefinedTag = '[object Undefined]', + weakMapTag = '[object WeakMap]', + weakSetTag = '[object WeakSet]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, + reUnescapedHtml = /[&<>"']/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g, + reTrimStart = /^\s+/, + reTrimEnd = /\s+$/; + + /** Used to match wrap detail comments. */ + var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, + reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, + reSplitDetails = /,? & /; + + /** Used to match words composed of alphanumeric characters. */ + var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Used to match + * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to match Latin Unicode letters (excluding mathematical operators). */ + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsPunctuationRange = '\\u2000-\\u206f', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; + + /** Used to compose unicode capture groups. */ + var rsApos = "['\u2019]", + rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', + rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', + rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match apostrophes. */ + var reApos = RegExp(rsApos, 'g'); + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to match complex or compound words. */ + var reUnicodeWord = RegExp([ + rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', + rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, + rsUpper + '+' + rsOptContrUpper, + rsOrdUpper, + rsOrdLower, + rsDigits, + rsEmoji + ].join('|'), 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', + 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', + '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map Latin Unicode letters to basic Latin letters. */ + var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = true && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + /* Node.js helper references. */ + var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, + nodeIsDate = nodeUtil && nodeUtil.isDate, + nodeIsMap = nodeUtil && nodeUtil.isMap, + nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, + nodeIsSet = nodeUtil && nodeUtil.isSet, + nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /*--------------------------------------------------------------------------*/ + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array == null ? 0 : array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; + } + + /** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array == null ? 0 : array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + var asciiSize = baseProperty('length'); + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function asciiWords(string) { + return string.match(reAsciiWord) || []; + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * The base implementation of `_.mean` and `_.meanBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the mean. + */ + function baseMean(array, iteratee) { + var length = array == null ? 0 : array.length; + return length ? (baseSum(array, iteratee) / length) : NAN; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyOf(object) { + return function(key) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sum` and `_.sumBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the key-value pairs. + */ + function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ + function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + ++result; + } + } + return result; + } + + /** + * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A + * letters to basic Latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + var deburrLetter = basePropertyOf(deburredLetters); + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + var escapeHtmlChar = basePropertyOf(htmlEscapes); + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ + function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** + * Converts `set` to its value-value pairs. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the value-value pairs. + */ + function setToPairs(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = [value, value]; + }); + return result; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * A specialized version of `_.lastIndexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictLastIndexOf(array, value, fromIndex) { + var index = fromIndex + 1; + while (index--) { + if (array[index] === value) { + return index; + } + } + return index; + } + + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ + function stringSize(string) { + return hasUnicode(string) + ? unicodeSize(string) + : asciiSize(string); + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + var unescapeHtmlChar = basePropertyOf(htmlUnescapes); + + /** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; + } + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function unicodeWords(string) { + return string.match(reUnicodeWord) || []; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the `context` object. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Util + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // Create a suped-up `defer` in Node.js. + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + var runInContext = (function runInContext(context) { + context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); + + /** Built-in constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = context['__core-js_shared__']; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? context.Buffer : undefined, + Symbol = context.Symbol, + Uint8Array = context.Uint8Array, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice, + spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, + symIterator = Symbol ? Symbol.iterator : undefined, + symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** Mocked built-ins. */ + var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, + ctxNow = Date && Date.now !== root.Date.now && Date.now, + ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeIsFinite = context.isFinite, + nativeJoin = arrayProto.join, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = Date.now, + nativeParseInt = context.parseInt, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(context, 'DataView'), + Map = getNative(context, 'Map'), + Promise = getNative(context, 'Promise'), + Set = getNative(context, 'Set'), + WeakMap = getNative(context, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chain sequences. Methods that operate on and return arrays, collections, + * and functions can be chained together. Methods that retrieve a single value + * or may return a primitive value will automatically end the chain sequence + * and return the unwrapped value. Otherwise, the value must be unwrapped + * with `_#value`. + * + * Explicit chain sequences, which must be unwrapped with `_#value`, may be + * enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. + * Shortcut fusion is an optimization to merge iteratee calls; this avoids + * the creation of intermediate arrays and can greatly reduce the number of + * iteratee executions. Sections of a chain sequence qualify for shortcut + * fusion if the section is applied to an array and iteratees accept only + * one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, + * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, + * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, + * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, + * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, + * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, + * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, + * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, + * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, + * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, + * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, + * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, + * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, + * `zipObject`, `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, + * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, + * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, + * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, + * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, + * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, + * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, + * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, + * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * The function whose prototype chain sequence wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; + } + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB) as well as ES2015 template strings. Change the + * following template settings to use alternative delimiters. + * + * @static + * @memberOf _ + * @type {Object} + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type {string} + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type {Object} + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type {Function} + */ + '_': lodash + } + }; + + // Ensure wrappers are instances of `baseLodash`. + lodash.prototype = baseLodash.prototype; + lodash.prototype.constructor = lodash; + + LodashWrapper.prototype = baseCreate(baseLodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || (!isRight && arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + // Ensure `LazyWrapper` is an instance of `baseLodash`. + LazyWrapper.prototype = baseCreate(baseLodash.prototype); + LazyWrapper.prototype.constructor = LazyWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** + * A specialized version of `_.sample` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @returns {*} Returns the random element. + */ + function arraySample(array) { + var length = array.length; + return length ? array[baseRandom(0, length - 1)] : undefined; + } + + /** + * A specialized version of `_.sampleSize` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function arraySampleSize(array, n) { + return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); + } + + /** + * A specialized version of `_.shuffle` for arrays. + * + * @private + * @param {Array} array The array to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function arrayShuffle(array) { + return shuffleSelf(copyArray(array)); + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths to pick. + * @returns {Array} Returns the picked elements. + */ + function baseAt(object, paths) { + var index = -1, + length = paths.length, + result = Array(length), + skip = object == null; + + while (++index < length) { + result[index] = skip ? undefined : get(object, paths[index]); + } + return result; + } + + /** + * The base implementation of `_.clamp` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new spec function. + */ + function baseConforms(source) { + var props = keys(source); + return function(object) { + return baseConformsTo(object, source, props); + }; + } + + /** + * The base implementation of `_.conformsTo` which accepts `props` to check. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + */ + function baseConformsTo(object, source, props) { + var length = props.length; + if (object == null) { + return !length; + } + object = Object(object); + while (length--) { + var key = props[length], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in object)) || !predicate(value)) { + return false; + } + } + return true; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts `args` + * to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Array} args The arguments to provide to `func`. + * @returns {number|Object} Returns the timer id or timeout object. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of methods like `_.difference` without support + * for excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee == null ? value : iteratee(value); + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !isSymbol(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the function names. + */ + function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ + function baseGt(value, other) { + return value > other; + } + + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + return object != null && hasOwnProperty.call(object, key); + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * The base implementation of `_.inRange` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ + function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); + } + + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function baseInvoke(object, path, args) { + path = castPath(path, object); + object = parent(object, path); + var func = object == null ? object : object[toKey(last(path))]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** + * The base implementation of `_.isArrayBuffer` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + */ + function baseIsArrayBuffer(value) { + return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; + } + + /** + * The base implementation of `_.isDate` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + */ + function baseIsDate(value) { + return isObjectLike(value) && baseGetTag(value) == dateTag; + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ + function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ + function baseIsRegExp(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; + } + + /** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ + function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; + } + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ + function baseLt(value, other) { + return value < other; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + }; + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.nth` which doesn't coerce arguments. + * + * @private + * @param {Array} array The array to query. + * @param {number} n The index of the element to return. + * @returns {*} Returns the nth element of `array`. + */ + function baseNth(array, n) { + var length = array.length; + if (!length) { + return; + } + n += n < 0 ? length : 0; + return isIndex(n, length) ? array[n] : undefined; + } + + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = arrayMap(iteratees, function(iteratee) { + if (isArray(iteratee)) { + return function(value) { + return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity]; + } + + var index = -1; + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, paths) { + return basePickBy(object, paths, function(value, path) { + return hasIn(object, path); + }); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ + function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (array === values) { + values = copyArray(values); + } + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (length == lastIndex || index !== previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } else { + baseUnset(array, index); + } + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); + } + + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; + } + + /** + * The base implementation of `_.repeat` which doesn't coerce arguments. + * + * @private + * @param {string} string The string to repeat. + * @param {number} n The number of times to repeat the string. + * @returns {string} Returns the repeated string. + */ + function baseRepeat(string, n) { + var result = ''; + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + if (n) { + string += string; + } + } while (n); + + return result; + } + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * The base implementation of `_.sample`. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + */ + function baseSample(collection) { + return arraySample(values(collection)); + } + + /** + * The base implementation of `_.sampleSize` without param guards. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function baseSampleSize(collection, n) { + var array = values(collection); + return shuffleSelf(array, baseClamp(n, 0, array.length)); + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `setData` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** + * The base implementation of `_.shuffle`. + * + * @private + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function baseShuffle(collection) { + return shuffleSelf(values(collection)); + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array == null ? low : array.length; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if (computed !== null && !isSymbol(computed) && + (retHighest ? (computed <= value) : (computed < value))) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); + } + + /** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndexBy(array, value, iteratee, retHighest) { + var low = 0, + high = array == null ? 0 : array.length; + if (high === 0) { + return 0; + } + + value = iteratee(value); + var valIsNaN = value !== value, + valIsNull = value === null, + valIsSymbol = isSymbol(value), + valIsUndefined = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + othIsDefined = computed !== undefined, + othIsNull = computed === null, + othIsReflexive = computed === computed, + othIsSymbol = isSymbol(computed); + + if (valIsNaN) { + var setLow = retHighest || othIsReflexive; + } else if (valIsUndefined) { + setLow = othIsReflexive && (retHighest || othIsDefined); + } else if (valIsNull) { + setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); + } else if (valIsSymbol) { + setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); + } else if (othIsNull || othIsSymbol) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniq(array, iteratee) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!index || !eq(computed, seen)) { + var seen = computed; + result[resIndex++] = value === 0 ? 0 : value; + } + } + return result; + } + + /** + * The base implementation of `_.toNumber` which doesn't ensure correct + * conversions of binary, hexadecimal, or octal string values. + * + * @private + * @param {*} value The value to process. + * @returns {number} Returns the number. + */ + function baseToNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + return +value; + } + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ + function baseUnset(object, path) { + path = castPath(path, object); + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; + } + + /** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); + } + + /** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ + function baseXor(arrays, iteratee, comparator) { + var length = arrays.length; + if (length < 2) { + return length ? baseUniq(arrays[0]) : []; + } + var index = -1, + result = Array(length); + + while (++index < length) { + var array = arrays[index], + othIndex = -1; + + while (++othIndex < length) { + if (othIndex != index) { + result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); + } + } + } + return baseUniq(baseFlatten(result, 1), iteratee, comparator); + } + + /** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; + } + + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array|Object} Returns the cast array-like object. + */ + function castArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ + function castFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** + * A `baseRest` alias which can be replaced with `identity` by module + * replacement plugins. + * + * @private + * @type {Function} + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + var castRest = baseRest; + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** + * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). + * + * @private + * @param {number|Object} id The timer id or timeout object of the timer to clear. + */ + var clearTimeout = ctxClearTimeout || function(id) { + return root.clearTimeout(id); + }; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); + } + + /** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, getIteratee(iteratee, 2), accumulator); + }; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createBind(func, bitmask, thisArg) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; + } + + /** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. + */ + function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = hasUnicode(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols + ? strSymbols[0] + : string.charAt(0); + + var trailing = strSymbols + ? castSlice(strSymbols, 1).join('') + : string.slice(1); + + return chr[methodName]() + trailing; + }; + } + + /** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtor(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. See + // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createCurry(func, bitmask, arity) { + var Ctor = createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getHolder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ + function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!isArrayLike(collection)) { + var iteratee = getIteratee(predicate, 3); + collection = keys(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return flatRest(function(funcs) { + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) + ? wrapper[funcName]() + : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value)) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); + } + + /** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided + * to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & WRAP_ARY_FLAG, + isBind = bitmask & WRAP_BIND_FLAG, + isBindKey = bitmask & WRAP_BIND_KEY_FLAG, + isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), + isFlip = bitmask & WRAP_FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length; + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getHolder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtor(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ + function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + + /** + * Creates a function that performs a mathematical operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @param {number} [defaultValue] The value used for `undefined` arguments. + * @returns {Function} Returns the new mathematical operation function. + */ + function createMathOperation(operator, defaultValue) { + return function(value, other) { + var result; + if (value === undefined && other === undefined) { + return defaultValue; + } + if (value !== undefined) { + result = value; + } + if (other !== undefined) { + if (result === undefined) { + return other; + } + if (typeof value == 'string' || typeof other == 'string') { + value = baseToString(value); + other = baseToString(other); + } else { + value = baseToNumber(value); + other = baseToNumber(other); + } + result = operator(value, other); + } + return result; + }; + } + + /** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new over function. + */ + function createOver(arrayFunc) { + return flatRest(function(iteratees) { + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); + return baseRest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); + } + + /** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {number} length The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ + function createPadding(length, chars) { + chars = chars === undefined ? ' ' : baseToString(chars); + + var charsLength = chars.length; + if (charsLength < 2) { + return charsLength ? baseRepeat(chars, length) : chars; + } + var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); + return hasUnicode(chars) + ? castSlice(stringToArray(result), 0, length).join('') + : result.slice(0, length); + } + + /** + * Creates a function that wraps `func` to invoke it with the `this` binding + * of `thisArg` and `partials` prepended to the arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to + * the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartial(func, bitmask, thisArg, partials) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ + function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); + return baseRange(start, end, step, fromRight); + }; + } + + /** + * Creates a function that performs a relational operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @returns {Function} Returns the new relational operation function. + */ + function createRelationalOperation(operator) { + return function(value, other) { + if (!(typeof value == 'string' && typeof other == 'string')) { + value = toNumber(value); + other = toNumber(other); + } + return operator(value, other); + }; + } + + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & WRAP_CURRY_FLAG, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); + + if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { + bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, argPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return setWrapToString(result, func, bitmask); + } + + /** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); + if (precision && nativeIsFinite(number)) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; + } + + /** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { + return new Set(values); + }; + + /** + * Creates a `_.toPairs` or `_.toPairsIn` function. + * + * @private + * @param {Function} keysFunc The function to get the keys of a given object. + * @returns {Function} Returns the new pairs function. + */ + function createToPairs(keysFunc) { + return function(object) { + var tag = getTag(object); + if (tag == mapTag) { + return mapToArray(object); + } + if (tag == setTag) { + return setToPairs(object); + } + return baseToPairs(object, keysFunc(object)); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * 512 - `_.flip` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] === undefined + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { + bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == WRAP_BIND_FLAG) { + var result = createBind(func, bitmask, thisArg); + } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { + result = createCurry(func, bitmask, arity); + } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { + result = createPartial(func, bitmask, thisArg, partials); + } else { + result = createHybrid.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setWrapToString(setter(result, newData), func, bitmask); + } + + /** + * Used by `_.defaults` to customize its `_.assignIn` use to assign properties + * of source objects to the destination object for all destination properties + * that resolve to `undefined`. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ + function customDefaultsAssignIn(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source + * objects into destination objects that are passed thru. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + * @returns {*} Returns the value to assign. + */ + function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, objValue); + baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); + stack['delete'](srcValue); + } + return objValue; + } + + /** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ + function customOmitClone(value) { + return isPlainObject(value) ? undefined : value; + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getHolder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + + /** + * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, + * this function returns the custom method, otherwise it returns `baseIteratee`. + * If arguments are provided, the chosen function is invoked with them and + * its result is returned. + * + * @private + * @param {*} [value] The value to convert to an iteratee. + * @param {number} [arity] The arity of the created iteratee. + * @returns {Function} Returns the chosen function or its result. + */ + function getIteratee() { + var result = lodash.iteratee || iteratee; + result = result === iteratee ? baseIteratee : result; + return arguments.length ? result(arguments[0], arguments[1]) : result; + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); + }; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Extracts wrapper details from the `source` body comment. + * + * @private + * @param {string} source The source to inspect. + * @returns {Array} Returns the wrapper details. + */ + function getWrapDetails(source) { + var match = source.match(reWrapDetails); + return match ? match[1].split(reSplitDetails) : []; + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Inserts wrapper `details` in a comment at the top of the `source` body. + * + * @private + * @param {string} source The source to modify. + * @returns {Array} details The details to insert. + * @returns {string} Returns the modified source. + */ + function insertWrapDetails(source, details) { + var length = details.length; + if (!length) { + return source; + } + var lastIndex = length - 1; + details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; + details = details.join(length > 2 ? ', ' : ' '); + return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); + } + + /** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ + function isFlattenable(value) { + return isArray(value) || isArguments(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, + * else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `func` is capable of being masked. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `func` is maskable, else `false`. + */ + var isMaskable = coreJsData ? isFunction : stubFalse; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and + * `_.rearg` modify function arguments, making the order in which they are + * executed important, preventing the merging of metadata. However, we make + * an exception for a safe combined case where curried functions have `_.ary` + * and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); + + var isCombo = + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & WRAP_BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : value; + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = value; + } + // Use source `ary` if it's smaller. + if (srcBitmask & WRAP_ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ + function parent(object, path) { + return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity + * function to avoid garbage collection pauses in V8. See + * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = shortOut(baseSetData); + + /** + * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @returns {number|Object} Returns the timer id or timeout object. + */ + var setTimeout = ctxSetTimeout || function(func, wait) { + return root.setTimeout(func, wait); + }; + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * Sets the `toString` method of `wrapper` to mimic the source of `reference` + * with wrapper details in a comment at the top of the source body. + * + * @private + * @param {Function} wrapper The function to modify. + * @param {Function} reference The reference function. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Function} Returns `wrapper`. + */ + function setWrapToString(wrapper, reference, bitmask) { + var source = (reference + ''); + return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); + } + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * A specialized version of `_.shuffle` which mutates and sets the size of `array`. + * + * @private + * @param {Array} array The array to shuffle. + * @param {number} [size=array.length] The size of `array`. + * @returns {Array} Returns `array`. + */ + function shuffleSelf(array, size) { + var index = -1, + length = array.length, + lastIndex = length - 1; + + size = size === undefined ? length : size; + while (++index < size) { + var rand = baseRandom(index, lastIndex), + value = array[rand]; + + array[rand] = array[index]; + array[index] = value; + } + array.length = size; + return array; + } + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Updates wrapper `details` based on `bitmask` flags. + * + * @private + * @returns {Array} details The details to modify. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Array} Returns `details`. + */ + function updateWrapDetails(details, bitmask) { + arrayEach(wrapFlags, function(pair) { + var value = '_.' + pair[0]; + if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { + details.push(value); + } + }); + return details.sort(); + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the new array of chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array == null ? 0 : array.length; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + + while (index--) { + args[index - 1] = arguments[index]; + } + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); + } + + /** + * Creates an array of `array` values not included in the other given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * **Note:** Unlike `_.pullAll`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.without, _.xor + * @example + * + * _.difference([2, 1], [2, 3]); + * // => [1] + */ + var difference = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * **Note:** Unlike `_.pullAllBy`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var differenceBy = baseRest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. The order and + * references of result values are determined by the first array. The comparator + * is invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.pullAllWith`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ + var differenceWith = baseRest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ + function fill(array, value, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ + function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseFindIndex(array, getIteratee(predicate, 3), index); + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ + function findLastIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length - 1; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = fromIndex < 0 + ? nativeMax(length + index, 0) + : nativeMin(index, length - 1); + } + return baseFindIndex(array, getIteratee(predicate, 3), index, true); + } + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ + function flattenDepth(array, depth) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); + } + + /** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['a', 1], ['b', 2]]); + * // => { 'a': 1, 'b': 2 } + */ + function fromPairs(pairs) { + var index = -1, + length = pairs == null ? 0 : pairs.length, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return (array && array.length) ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the + * offset from the end of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseIndexOf(array, value, index); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 0, -1) : []; + } + + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [2, 3]); + * // => [2] + */ + var intersection = baseRest(function(arrays) { + var mapped = arrayMap(arrays, castArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ + var intersectionBy = baseRest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, getIteratee(iteratee, 2)) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. The order and references + * of result values are determined by the first array. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ + var intersectionWith = baseRest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + comparator = typeof comparator == 'function' ? comparator : undefined; + if (comparator) { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; + }); + + /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ + function join(array, separator) { + return array == null ? '' : nativeJoin.call(array, separator); + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); + } + return value === value + ? strictLastIndexOf(array, value, index) + : baseFindIndex(array, baseIsNaN, index, true); + } + + /** + * Gets the element at index `n` of `array`. If `n` is negative, the nth + * element from the end is returned. + * + * @static + * @memberOf _ + * @since 4.11.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=0] The index of the element to return. + * @returns {*} Returns the nth element of `array`. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * + * _.nth(array, 1); + * // => 'b' + * + * _.nth(array, -2); + * // => 'c'; + */ + function nth(array, n) { + return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; + } + + /** + * Removes all given values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` + * to remove elements from an array by predicate. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pull(array, 'a', 'c'); + * console.log(array); + * // => ['b', 'b'] + */ + var pull = baseRest(pullAll); + + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pullAll(array, ['a', 'c']); + * console.log(array); + * // => ['b', 'b'] + */ + function pullAll(array, values) { + return (array && array.length && values && values.length) + ? basePullAll(array, values) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ + function pullAllBy(array, values, iteratee) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, getIteratee(iteratee, 2)) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `comparator` which + * is invoked to compare elements of `array` to `values`. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ + function pullAllWith(array, values, comparator) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, undefined, comparator) + : array; + } + + /** + * Removes elements from `array` corresponding to `indexes` and returns an + * array of removed elements. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * var pulled = _.pullAt(array, [1, 3]); + * + * console.log(array); + * // => ['a', 'c'] + * + * console.log(pulled); + * // => ['b', 'd'] + */ + var pullAt = flatRest(function(array, indexes) { + var length = array == null ? 0 : array.length, + result = baseAt(array, indexes); + + basePullAt(array, arrayMap(indexes, function(index) { + return isIndex(index, length) ? +index : index; + }).sort(compareAscending)); + + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is invoked + * with three arguments: (value, index, array). + * + * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` + * to pull elements from an array by value. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getIteratee(predicate, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function reverse(array) { + return array == null ? array : nativeReverse.call(array); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of + * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are + * returned. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + */ + function sortedIndex(array, value) { + return baseSortedIndex(array, value); + } + + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); + * // => 0 + */ + function sortedIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); + } + + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([4, 5, 5, 5, 6], 5); + * // => 1 + */ + function sortedIndexOf(array, value) { + var length = array == null ? 0 : array.length; + if (length) { + var index = baseSortedIndex(array, value); + if (index < length && eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 5, 5, 5, 6], 5); + * // => 4 + */ + function sortedLastIndex(array, value) { + return baseSortedIndex(array, value, true); + } + + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 1 + * + * // The `_.property` iteratee shorthand. + * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); + * // => 1 + */ + function sortedLastIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); + } + + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); + * // => 3 + */ + function sortedLastIndexOf(array, value) { + var length = array == null ? 0 : array.length; + if (length) { + var index = baseSortedIndex(array, value, true) - 1; + if (eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ + function sortedUniq(array) { + return (array && array.length) + ? baseSortedUniq(array) + : []; + } + + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ + function sortedUniqBy(array, iteratee) { + return (array && array.length) + ? baseSortedUniq(array, getIteratee(iteratee, 2)) + : []; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.tail([1, 2, 3]); + * // => [2, 3] + */ + function tail(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 1, length) : []; + } + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + if (!(array && array.length)) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.takeRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeRightWhile(users, ['active', false]); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.takeRightWhile(users, 'active'); + * // => [] + */ + function takeRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.takeWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matches` iteratee shorthand. + * _.takeWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeWhile(users, ['active', false]); + * // => objects for ['barney', 'fred'] + * + * // The `_.property` iteratee shorthand. + * _.takeWhile(users, 'active'); + * // => [] + */ + function takeWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ + var union = baseRest(function(arrays) { + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); + }); + + /** + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which uniqueness is computed. Result values are chosen from the first + * array in which the value occurs. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.unionBy([2.1], [1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + var unionBy = baseRest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); + }); + + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. Result values are chosen from + * the first array in which the value occurs. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var unionWith = baseRest(function(arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined; + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) ? baseUniq(array) : []; + } + + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniqBy(array, iteratee) { + return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : []; + } + + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The order of result values is + * determined by the order they occur in the array.The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ + function uniqWith(array, comparator) { + comparator = typeof comparator == 'function' ? comparator : undefined; + return (array && array.length) ? baseUniq(array, undefined, comparator) : []; + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @since 1.2.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + * + * _.unzip(zipped); + * // => [['a', 'b'], [1, 2], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var length = 0; + array = arrayFilter(array, function(group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function(index) { + return arrayMap(array, baseProperty(index)); + }); + } + + /** + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee=_.identity] The function to combine + * regrouped values. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee) { + if (!(array && array.length)) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + return arrayMap(result, function(group) { + return apply(iteratee, undefined, group); + }); + } + + /** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.pull`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.xor + * @example + * + * _.without([2, 1, 2, 3], 1, 2); + * // => [3] + */ + var without = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the + * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the given arrays. The order of result values is determined by the order + * they occur in the arrays. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.without + * @example + * + * _.xor([2, 1], [2, 3]); + * // => [1, 3] + */ + var xor = baseRest(function(arrays) { + return baseXor(arrayFilter(arrays, isArrayLikeObject)); + }); + + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which by which they're compared. The order of result values is determined + * by the order they occur in the arrays. The iteratee is invoked with one + * argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2, 3.4] + * + * // The `_.property` iteratee shorthand. + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var xorBy = baseRest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); + }); + + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The order of result values is + * determined by the order they occur in the arrays. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var xorWith = baseRest(function(arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined; + return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); + }); + + /** + * Creates an array of grouped elements, the first of which contains the + * first elements of the given arrays, the second of which contains the + * second elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + */ + var zip = baseRest(unzip); + + /** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ + function zipObject(props, values) { + return baseZipObject(props || [], values || [], assignValue); + } + + /** + * This method is like `_.zipObject` except that it supports property paths. + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); + * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } + */ + function zipObjectDeep(props, values) { + return baseZipObject(props || [], values || [], baseSet); + } + + /** + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee=_.identity] The function to combine + * grouped values. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); + * // => [111, 222] + */ + var zipWith = baseRest(function(arrays) { + var length = arrays.length, + iteratee = length > 1 ? arrays[length - 1] : undefined; + + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; + return unzipWith(arrays, iteratee); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `_#value`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain sequence in order to modify intermediate results. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain sequence. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @since 1.0.0 + * @category Seq + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + */ + var wrapperAt = flatRest(function(paths) { + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function(object) { return baseAt(object, paths); }; + + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } + value = value.slice(start, +start + (length ? 1 : 0)); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); + return new LodashWrapper(value, this.__chain__).thru(function(array) { + if (length && !array.length) { + array.push(undefined); + } + return array; + }); + }); + + /** + * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. + * + * @name chain + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chain sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). + * + * @name next + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } + */ + function wrapperNext() { + if (this.__values__ === undefined) { + this.__values__ = toArray(this.value()); + } + var done = this.__index__ >= this.__values__.length, + value = done ? undefined : this.__values__[this.__index__++]; + + return { 'done': done, 'value': value }; + } + + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ + function wrapperToIterator() { + return this; + } + + /** + * Creates a clone of the chain sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @param {*} value The value to plant. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); + * + * other.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined; + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * This method is the wrapper version of `_.reverse`. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(reverse); + } + + /** + * Executes the chain sequence to resolve the unwrapped value. + * + * @name value + * @memberOf _ + * @since 0.1.0 + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the number of times the key was returned by `iteratee`. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': 1, '6': 2 } + * + * // The `_.property` iteratee shorthand. + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + ++result[key]; + } else { + baseAssignValue(result, key, 1); + } + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ + function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + var find = createFind(findIndex); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=collection.length-1] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(findLastIndex); + + /** + * Creates a flattened array of values by running each element in `collection` + * thru `iteratee` and flattening the mapped results. The iteratee is invoked + * with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); + } + + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDeep([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMapDeep(collection, iteratee) { + return baseFlatten(map(collection, iteratee), INFINITY); + } + + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDepth([1, 2], duplicate, 2); + * // => [[1, 1], [2, 2]] + */ + function flatMapDepth(collection, iteratee, depth) { + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(map(collection, iteratee), depth); + } + + /** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEach + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `2` then `1`. + */ + function forEachRight(collection, iteratee) { + var func = isArray(collection) ? arrayEachRight : baseEachRight; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + baseAssignValue(result, key, [value]); + } + }); + + /** + * Checks if `value` is in `collection`. If `collection` is a string, it's + * checked for a substring of `value`, otherwise + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'a': 1, 'b': 2 }, 1); + * // => true + * + * _.includes('abcd', 'bc'); + * // => true + */ + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); + } + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `path` is a function, it's invoked + * for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invokeMap = baseRest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); + }); + return result; + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ + var keyBy = createAggregator(function(result, value, key) { + baseAssignValue(result, key, value); + }); + + /** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] + * The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + */ + function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + orders = guard ? undefined : orders; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseOrderBy(collection, iteratees, orders); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] + * + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduce + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduceRight : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); + } + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.filter + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] + */ + function reject(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, negate(getIteratee(predicate, 3))); + } + + /** + * Gets a random element from `collection`. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + */ + function sample(collection) { + var func = isArray(collection) ? arraySample : baseSample; + return func(collection); + } + + /** + * Gets `n` random elements at unique keys from `collection` up to the + * size of `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @param {number} [n=1] The number of elements to sample. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the random elements. + * @example + * + * _.sampleSize([1, 2, 3], 2); + * // => [3, 1] + * + * _.sampleSize([1, 2, 3], 4); + * // => [2, 3, 1] + */ + function sampleSize(collection, n, guard) { + if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { + n = 1; + } else { + n = toInteger(n); + } + var func = isArray(collection) ? arraySampleSize : baseSampleSize; + return func(collection, n); + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + var func = isArray(collection) ? arrayShuffle : baseShuffle; + return func(collection); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + return isString(collection) ? stringSize(collection) : collection.length; + } + var tag = getTag(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return baseKeys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + var func = isArray(collection) ? arraySome : baseSome; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ + var sortBy = baseRest(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now = ctxNow || function() { + return root.Date.now(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => Logs 'done saving!' after the two async saves have completed. + */ + function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that invokes `func`, with up to `n` arguments, + * ignoring any additional arguments. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and `partials` prepended to the arguments it receives. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * function greet(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = baseRest(function(func, thisArg, partials) { + var bitmask = WRAP_BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bind)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(func, bitmask, thisArg, partials, holders); + }); + + /** + * Creates a function that invokes the method at `object[key]` with `partials` + * prepended to the arguments it receives. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. See + * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = baseRest(function(object, key, partials) { + var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bindKey)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; + } + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; + } + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => Logs 'deferred' after one millisecond. + */ + var defer = baseRest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => Logs 'later' after one second. + */ + var delay = baseRest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new flipped function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ + function flip(func) { + return createWrap(func, WRAP_FLIP_FLAG); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + var args = arguments; + switch (args.length) { + case 0: return !predicate.call(this); + case 1: return !predicate.call(this, args[0]); + case 2: return !predicate.call(this, args[0], args[1]); + case 3: return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // => `createApplication` is invoked once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with its arguments transformed. + * + * @static + * @since 4.0.0 + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms=[_.identity]] + * The argument transforms. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var func = _.overArgs(function(x, y) { + * return [x, y]; + * }, [square, doubled]); + * + * func(9, 3); + * // => [81, 6] + * + * func(10, 5); + * // => [100, 10] + */ + var overArgs = castRest(function(func, transforms) { + transforms = (transforms.length == 1 && isArray(transforms[0])) + ? arrayMap(transforms[0], baseUnary(getIteratee())) + : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); + + var funcsLength = transforms.length; + return baseRest(function(args) { + var index = -1, + length = nativeMin(args.length, funcsLength); + + while (++index < length) { + args[index] = transforms[index].call(this, args[index]); + } + return apply(func, this, args); + }); + }); + + /** + * Creates a function that invokes `func` with `partials` prepended to the + * arguments it receives. This method is like `_.bind` except it does **not** + * alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 0.2.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // Partially applied with placeholders. + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = baseRest(function(func, partials) { + var holders = replaceHolders(partials, getHolder(partial)); + return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); + }); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to the arguments it receives. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // Partially applied with placeholders. + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = baseRest(function(func, partials) { + var holders = replaceHolders(partials, getHolder(partialRight)); + return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders); + }); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified `indexes` where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, [2, 0, 1]); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + */ + var rearg = flatRest(function(func, indexes) { + return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as + * an array. + * + * **Note:** This method is based on the + * [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start === undefined ? start : toInteger(start); + return baseRest(func, start); + } + + /** + * Creates a function that invokes `func` with the `this` binding of the + * create function and an array of arguments much like + * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). + * + * **Note:** This method is based on the + * [spread operator](https://mdn.io/spread_operator). + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Function + * @param {Function} func The function to spread arguments over. + * @param {number} [start=0] The start position of the spread. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start == null ? 0 : nativeMax(toInteger(start), 0); + return baseRest(function(args) { + var array = args[start], + otherArgs = castSlice(args, 0, start); + + if (array) { + arrayPush(otherArgs, array); + } + return apply(func, this, otherArgs); + }); + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ + function unary(func) { + return ary(func, 1); + } + + /** + * Creates a function that provides `value` to `wrapper` as its first + * argument. Any additional arguments provided to the function are appended + * to those provided to the `wrapper`. The wrapper is invoked with the `this` + * binding of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {*} value The value to wrap. + * @param {Function} [wrapper=identity] The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' + */ + function wrap(value, wrapper) { + return partial(castFunction(wrapper), value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined`, + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @see _.cloneDeepWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ + function cloneWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @see _.cloneWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ + function cloneDeepWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * Checks if `object` conforms to `source` by invoking the predicate + * properties of `source` with the corresponding property values of `object`. + * + * **Note:** This method is equivalent to `_.conforms` when `source` is + * partially applied. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); + * // => true + * + * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); + * // => false + */ + function conformsTo(object, source) { + return source == null || baseConformsTo(object, source, keys(source)); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + * @see _.lt + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + var gt = createRelationalOperation(baseGt); + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to + * `other`, else `false`. + * @see _.lte + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + var gte = createRelationalOperation(function(value, other) { + return value >= other; + }); + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); + } + + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + if (!isObjectLike(value)) { + return false; + } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. + * + * **Note:** This method is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.isMatch(object, { 'b': 2 }); + * // => true + * + * _.isMatch(object, { 'b': 1 }); + * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the presence + * of the core-js package because core-js circumvents this kind of detection. + * Despite multiple requests, the core-js maintainer has made it clear: any + * attempt to fix the detection will be obstructed. As a result, we're left + * with little choice but to throw an error. Unfortunately, this also affects + * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on core-js. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (isMaskable(value)) { + throw new Error(CORE_ERROR_TEXT); + } + return baseIsNative(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on + * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && baseGetTag(value) == weakSetTag; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + * @see _.gt + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + var lt = createRelationalOperation(baseLt); + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to + * `other`, else `false`. + * @see _.gte + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + var lte = createRelationalOperation(function(value, other) { + return value <= other; + }); + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3.2); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3.2'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3.2); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3.2'); + * // => 3 + */ + function toSafeInteger(value) { + return value + ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) + : (value === 0 ? value : 0); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ + var assign = createAssigner(function(object, source) { + if (isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Array} Returns the picked values. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + */ + var at = flatRest(baseAt); + + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); + } + + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var defaults = baseRest(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ + var defaultsDeep = baseRest(function(args) { + args.push(undefined, customDefaultsMerge); + return apply(mergeWith, undefined, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); + } + + /** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forIn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. + */ + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forOwn(object, iteratee) { + return object && baseForOwn(object, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. + */ + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, getIteratee(iteratee, 3)); + } + + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functionsIn + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functions + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = baseRest(baseInvoke); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with six arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to omit. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = flatRest(function(object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function(path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); + } + return result; + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(getIteratee(predicate))); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = getIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + path = castPath(path, object); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + length = 1; + object = undefined; + } + while (++index < length) { + var value = object == null ? undefined : object[toKey(path[index])]; + if (value === undefined) { + index = length; + value = defaultValue; + } + object = isFunction(value) ? value.call(object) : value; + } + return object; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseSet(object, path, value, customizer); + } + + /** + * Creates an array of own enumerable string keyed-value pairs for `object` + * which can be consumed by `_.fromPairs`. If `object` is a map or set, its + * entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entries + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + var toPairs = createToPairs(keys); + + /** + * Creates an array of own and inherited enumerable string keyed-value pairs + * for `object` which can be consumed by `_.fromPairs`. If `object` is a map + * or set, its entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entriesIn + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) + */ + var toPairsIn = createToPairs(keysIn); + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable string keyed properties thru `iteratee`, with each invocation + * potentially mutating the `accumulator` object. If `accumulator` is not + * provided, a new object with the same `[[Prototype]]` will be used. The + * iteratee is invoked with four arguments: (accumulator, value, key, object). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function transform(object, iteratee, accumulator) { + var isArr = isArray(object), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + + iteratee = getIteratee(iteratee, 4); + if (accumulator == null) { + var Ctor = object && object.constructor; + if (isArrLike) { + accumulator = isArr ? new Ctor : []; + } + else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } + else { + accumulator = {}; + } + } + (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, ['a', '0', 'b', 'c']); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, castFunction(updater)); + } + + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable string keyed property + * values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Checks if `n` is between `start` and up to, but not including, `end`. If + * `end` is not specified, it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @since 3.3.0 + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @see _.range, _.rangeRight + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ + function inRange(number, start, end) { + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + number = toNumber(number); + return baseInRange(number, start, end); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are + * floats, a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined; + } + if (floating === undefined) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined; + } + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined; + } + } + if (lower === undefined && upper === undefined) { + lower = 0; + upper = 1; + } + else { + lower = toFinite(lower); + if (upper === undefined) { + upper = lower; + lower = 0; + } else { + upper = toFinite(upper); + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search up to. + * @returns {boolean} Returns `true` if `string` ends with `target`, + * else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = toString(string); + target = baseToString(target); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + var end = position; + position -= target.length; + return position >= 0 && string.slice(position, end) == target; + } + + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; + } + + /** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar--'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + if (!length || strLength >= length) { + return string; + } + var mid = (length - strLength) / 2; + return ( + createPadding(nativeFloor(mid), chars) + + string + + createPadding(nativeCeil(mid), chars) + ); + } + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ + function padEnd(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (string + createPadding(length - strLength, chars)) + : string; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ + function padStart(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (createPadding(length - strLength, chars) + string) + : string; + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a + * hexadecimal, in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the + * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=1] The number of times to repeat the string. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n, guard) { + if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { + n = 1; + } else { + n = toInteger(n); + } + return baseRepeat(toString(string), n); + } + + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on + * [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** + * Converts `string` to + * [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--FOO-BAR--'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on + * [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { + separator = limit = undefined; + } + limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; + if (!limit) { + return []; + } + string = toString(string); + if (string && ( + typeof separator == 'string' || + (separator != null && !isRegExp(separator)) + )) { + separator = baseToString(separator); + if (!separator && hasUnicode(string)) { + return castSlice(stringToArray(string), 0, limit); + } + } + return string.split(separator, limit); + } + + /** + * Converts `string` to + * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @since 3.1.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar--'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__FOO_BAR__'); + * // => 'FOO BAR' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + upperFirst(word); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, + * else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = toString(string); + position = position == null + ? 0 + : baseClamp(toInteger(position), 0, string.length); + + target = baseToString(target); + return string.slice(position, position + target.length) == target; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given, it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options={}] The options object. + * @param {RegExp} [options.escape=_.templateSettings.escape] + * The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] + * The "evaluate" delimiter. + * @param {Object} [options.imports=_.templateSettings.imports] + * An object to import into the template as free variables. + * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] + * The "interpolate" delimiter. + * @param {string} [options.sourceURL='lodash.templateSources[n]'] + * The sourceURL of the compiled template. + * @param {string} [options.variable='obj'] + * The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' + + + + + + + + +
+ + + diff --git a/images/bgbl.svg b/images/bgbl.svg new file mode 100644 index 0000000..d3e960b --- /dev/null +++ b/images/bgbl.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/bgtr.svg b/images/bgtr.svg new file mode 100644 index 0000000..b0b7d47 --- /dev/null +++ b/images/bgtr.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/custom_emojis/converse.png b/images/custom_emojis/converse.png new file mode 100644 index 0000000..2b069f4 Binary files /dev/null and b/images/custom_emojis/converse.png differ diff --git a/images/custom_emojis/xmpp.png b/images/custom_emojis/xmpp.png new file mode 100644 index 0000000..7f6b85c Binary files /dev/null and b/images/custom_emojis/xmpp.png differ diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 0000000..edadbfc Binary files /dev/null and b/images/favicon.ico differ diff --git a/images/header.jpg b/images/header.jpg new file mode 100644 index 0000000..1bab8ad Binary files /dev/null and b/images/header.jpg differ diff --git a/images/icons.svg b/images/icons.svg new file mode 100644 index 0000000..41238b5 --- /dev/null +++ b/images/icons.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/overlay.png b/images/overlay.png new file mode 100644 index 0000000..2141c78 Binary files /dev/null and b/images/overlay.png differ diff --git a/logo/blokt.png b/logo/blokt.png new file mode 100644 index 0000000..2a40902 Binary files /dev/null and b/logo/blokt.png differ diff --git a/logo/codefirst.png b/logo/codefirst.png new file mode 100644 index 0000000..0271112 Binary files /dev/null and b/logo/codefirst.png differ diff --git a/logo/conversejs-filled-192.png b/logo/conversejs-filled-192.png new file mode 100644 index 0000000..f85f008 Binary files /dev/null and b/logo/conversejs-filled-192.png differ diff --git a/logo/conversejs-filled-192.svg b/logo/conversejs-filled-192.svg new file mode 100644 index 0000000..f8e6c6c --- /dev/null +++ b/logo/conversejs-filled-192.svg @@ -0,0 +1,90 @@ + + + + diff --git a/logo/conversejs-filled-512.png b/logo/conversejs-filled-512.png new file mode 100644 index 0000000..b52f575 Binary files /dev/null and b/logo/conversejs-filled-512.png differ diff --git a/logo/conversejs-filled-512.svg b/logo/conversejs-filled-512.svg new file mode 100644 index 0000000..c0b5dbb --- /dev/null +++ b/logo/conversejs-filled-512.svg @@ -0,0 +1,310 @@ + + + + diff --git a/logo/conversejs-filled.svg b/logo/conversejs-filled.svg new file mode 100644 index 0000000..22feee5 --- /dev/null +++ b/logo/conversejs-filled.svg @@ -0,0 +1,19 @@ + diff --git a/logo/conversejs-gold-gradient.svg b/logo/conversejs-gold-gradient.svg new file mode 100644 index 0000000..68d1ac1 --- /dev/null +++ b/logo/conversejs-gold-gradient.svg @@ -0,0 +1,63 @@ + + + Logo Converse + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/logo/conversejs-with-byline.svg b/logo/conversejs-with-byline.svg new file mode 100644 index 0000000..8b40888 --- /dev/null +++ b/logo/conversejs-with-byline.svg @@ -0,0 +1,108 @@ + + diff --git a/logo/keycdn.png b/logo/keycdn.png new file mode 100644 index 0000000..5fccfc5 Binary files /dev/null and b/logo/keycdn.png differ diff --git a/logo/keycdn.svg b/logo/keycdn.svg new file mode 100644 index 0000000..4e7a568 --- /dev/null +++ b/logo/keycdn.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/logo/mastodon.svg b/logo/mastodon.svg new file mode 100644 index 0000000..beebd9d --- /dev/null +++ b/logo/mastodon.svg @@ -0,0 +1,77 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/logo/readme.png b/logo/readme.png new file mode 100644 index 0000000..95083f7 Binary files /dev/null and b/logo/readme.png differ diff --git a/logo/weblate-button.svg b/logo/weblate-button.svg new file mode 100644 index 0000000..af4ffa7 --- /dev/null +++ b/logo/weblate-button.svg @@ -0,0 +1 @@ + \ No newline at end of file