Browse Source

Merge branch 'master' into converse-omemo

JC Brand 7 years ago
parent
commit
6785eff4a7
100 changed files with 13502 additions and 19312 deletions
  1. 0 9
      .babelrc
  2. 1 0
      .eslintrc.json
  3. 2 0
      .gitignore
  4. 6 0
      CHANGES.md
  5. 33 43
      Makefile
  6. 0 210
      bootstrap.py
  7. 1 9
      buildout.cfg
  8. 0 3
      builds/README.md
  9. 503 147
      css/converse.css
  10. 26 0
      css/fullpage.css
  11. 0 8908
      css/inverse.css
  12. 21 2
      css/website.css
  13. 22 24
      dev.html
  14. 3933 2026
      dist/converse-no-dependencies.js
  15. 5614 5251
      dist/converse.js
  16. 97 83
      docs/source/configuration.rst
  17. 39 22
      docs/source/events.rst
  18. 9 12
      docs/source/features.rst
  19. 2 10
      docs/source/quickstart.rst
  20. 3 2
      fullscreen.html
  21. 101 12
      index.html
  22. 602 737
      locale/converse.pot
  23. BIN
      logo/hostpresto.png
  24. 1 1
      mockup/chatbox.html
  25. 2 3
      mockup/chatroom.html
  26. 1 1
      mockup/fullscreen-login.html
  27. 790 338
      package-lock.json
  28. 21 13
      package.json
  29. 18 0
      redirect.html
  30. 1 0
      requirements.txt
  31. 0 1
      sass/_awesomplete.scss
  32. 232 14
      sass/_chatbox.scss
  33. 157 32
      sass/_chatrooms.scss
  34. 131 12
      sass/_controlbox.scss
  35. 28 2
      sass/_core.scss
  36. 0 1
      sass/_embedded.scss
  37. 17 0
      sass/_headline.scss
  38. 1 1
      sass/_minimized_chats.scss
  39. 6 0
      sass/_roomslist.scss
  40. 0 4
      sass/_roster.scss
  41. 32 2
      sass/_variables.scss
  42. 54 26
      sass/_website.scss
  43. 2 6
      sass/converse.scss
  44. 0 71
      sass/converse/_chatbox.scss
  45. 0 22
      sass/converse/_chatrooms.scss
  46. 0 5
      sass/converse/_core.scss
  47. 0 26
      sass/converse/_variables.scss
  48. 0 58
      sass/inverse.scss
  49. 0 96
      sass/inverse/_chatbox.scss
  50. 0 64
      sass/inverse/_chatrooms.scss
  51. 0 102
      sass/inverse/_controlbox.scss
  52. 0 42
      sass/inverse/_core.scss
  53. 0 17
      sass/inverse/_headline.scss
  54. 0 58
      sass/inverse/_minimized_chats.scss
  55. 0 5
      sass/inverse/_roster.scss
  56. 0 34
      sass/inverse/_variables.scss
  57. 34 32
      spec/bookmarks.js
  58. 7 9
      spec/chatbox.js
  59. 190 133
      spec/chatroom.js
  60. 2 2
      spec/controlbox.js
  61. 1 2
      spec/converse.js
  62. 6 3
      spec/disco.js
  63. 2 2
      spec/eventemitter.js
  64. 3 4
      spec/headline.js
  65. 3 3
      spec/http-file-upload.js
  66. 2 2
      spec/login.js
  67. 2 2
      spec/mam.js
  68. 62 20
      spec/messages.js
  69. 2 2
      spec/minchats.js
  70. 2 2
      spec/notification.js
  71. 2 2
      spec/omemo.js
  72. 85 49
      spec/otr.js
  73. 1 1
      spec/ping.js
  74. 3 3
      spec/presence.js
  75. 3 2
      spec/profiling.js
  76. 2 3
      spec/protocol.js
  77. 164 0
      spec/push.js
  78. 20 6
      spec/register.js
  79. 106 5
      spec/roomslist.js
  80. 64 2
      spec/roster.js
  81. 2 9
      spec/spoilers.js
  82. 1 3
      spec/user-details-modal.js
  83. 2 2
      spec/utils.js
  84. 2 2
      spec/xmppstatus.js
  85. 0 9
      src/build-esnext.js
  86. 0 54
      src/build-no-dependencies.js
  87. 0 43
      src/build.js
  88. 0 168
      src/config.js
  89. 7 8
      src/converse-bookmarks.js
  90. 83 73
      src/converse-chatboxes.js
  91. 33 26
      src/converse-chatview.js
  92. 6 6
      src/converse-controlbox.js
  93. 6 8
      src/converse-core.js
  94. 53 13
      src/converse-disco.js
  95. 1 1
      src/converse-dragresize.js
  96. 1 1
      src/converse-fullscreen.js
  97. 2 2
      src/converse-headline.js
  98. 4 4
      src/converse-mam.js
  99. 9 8
      src/converse-message-view.js
  100. 13 14
      src/converse-minimize.js

+ 0 - 9
.babelrc

@@ -1,9 +0,0 @@
-{
-  "presets": [
-    ["@babel/preset-env", {
-      "targets": {
-		"browsers": ["last 2 versions", "safari >= 10", "IE >= 11"]
-      }
-    }]
-  ]
-}

+ 1 - 0
.eslintrc.json

@@ -10,6 +10,7 @@
     "extends": ["eslint:recommended", "plugin:lodash/canonical"],
     "globals": {
         "Promise": true,
+        "converse": true,
         "define": true,
         "require": true,
         "sinon": true,

+ 2 - 0
.gitignore

@@ -13,6 +13,8 @@
 .su?
 builds/*
 3rdparty/libsignal-protocol-javascript/
+*.map
+dist/converse-no-dependencies-es2015.js
 
 analytics.js
 inverse-analytics.js

+ 6 - 0
CHANGES.md

@@ -7,7 +7,11 @@
 - #161 XEP-0363: HTTP File Upload
 - #194 Include entity capabilities in outgoing presence stanzas
 - #337 API call to update a VCard
+- #968 Use nickname from VCard when joining a room
+- #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
+- #1081 Allow for shift-enter to insert newlines
 - 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
@@ -16,6 +20,8 @@
 - 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, specifically registering an "App Server".
+- Add support for logging in via OAuth (see the [oauth_providers](https://conversejs.org/docs/html/configurations.html#oauth-providers) setting)
 
 ### Bugfixes
 

+ 33 - 43
Makefile

@@ -8,15 +8,16 @@ CHROMIUM		?= ./node_modules/.bin/run-headless-chromium
 CLEANCSS		?= ./node_modules/clean-css-cli/bin/cleancss --skip-rebase
 ESLINT		  	?= ./node_modules/.bin/eslint
 HTTPSERVE	   	?= ./node_modules/.bin/http-server
-HTTPSERVE_PORT  ?= 8000
-INKSCAPE        ?= inkscape
+HTTPSERVE_PORT		?= 8000
+INKSCAPE		?= inkscape
 JSDOC			?=  ./node_modules/.bin/jsdoc
-OXIPNG          ?= oxipng
+OXIPNG			?= oxipng
 PAPER		   	=
 PO2JSON		 	?= ./node_modules/.bin/po2json
-RJS			 	?= ./node_modules/.bin/r.js
+RJS			?= ./node_modules/.bin/r.js
+WEBPACK 		?= ./node_modules/.bin/npx
 SASS			?= ./.bundle/bin/sass
-SED				?= sed
+SED			?= sed
 SPHINXBUILD	 	?= ./bin/sphinx-build
 SPHINXOPTS	  	=
 UGLIFYJS		?= node_modules/.bin/uglifyjs
@@ -73,7 +74,7 @@ serve_bg: dev
 GETTEXT = xgettext --language="JavaScript" --keyword=__ --keyword=___ --from-code=UTF-8 --output=locale/converse.pot dist/converse-no-dependencies.js --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=3.3.4 -c
 
 .PHONY: pot
-pot: dist/converse-no-dependencies.js
+pot: dist/converse-no-dependencies-es2015.js
 	$(GETTEXT) 2>&1 > /dev/null; exit $$?;
 
 .PHONY: po
@@ -121,7 +122,7 @@ stamp-bundler: Gemfile
 
 .PHONY: clean
 clean:
-	rm -rf node_modules .bundle stamp-npm
+	rm -rf node_modules .bundle stamp-npm stamp-bundler
 	rm dist/*.min.js
 	rm css/website.min.css
 	rm css/converse.min.css
@@ -134,10 +135,7 @@ dev: stamp-bundler stamp-npm
 ## Builds
 
 .PHONY: css
-css: dev sass/*.scss css/converse.css css/converse.min.css css/website.css css/website.min.css css/inverse.css css/inverse.min.css css/fonts.css
-
-css/inverse.css:: dev sass sass
-	$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/inverse.scss css/inverse.css
+css: dev sass/*.scss css/converse.css css/converse.min.css css/website.css css/website.min.css css/fonts.css
 
 css/converse.css:: dev sass
 	$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/converse.scss css/converse.css
@@ -158,12 +156,7 @@ watch: dev
 
 .PHONY: watchjs
 watchjs: dev
-	$(BABEL) --source-maps --watch=./src --out-dir=./builds
-
-transpile: dev src
-	$(BABEL) --source-maps --out-dir=./builds ./src
-	$(BABEL) --source-maps --out-dir=./builds ./node_modules/backbone.vdomview/backbone.vdomview.js
-	touch transpile
+	./node_modules/.bin/npx  webpack --mode=development  --watch
 
 .PHONY: logo
 logo: logo/conversejs-transparent16.png \
@@ -186,37 +179,34 @@ logo/conversejs-filled%.png:: logo/conversejs-filled.svg
 	$(OXIPNG) $@
 
 BUILDS = dist/converse.js \
-		 dist/converse.min.js \
-         dist/converse-headless.js \
-		 dist/converse-headless.min.js \
-		 dist/converse-no-dependencies.min.js \
-		 dist/converse-no-dependencies.js
-
-# dist/converse-esnext.js \
-# dist/converse-esnext.min.js \
-
-dist/converse.js: transpile src stamp-npm
-	$(RJS) -o src/build.js include=converse out=dist/converse.js optimize=none 
-dist/converse.min.js: transpile src stamp-npm
-	$(RJS) -o src/build.js include=converse out=dist/converse.min.js
-dist/converse-headless.js: transpile src stamp-npm
-	$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.js optimize=none 
-dist/converse-headless.min.js: transpile src stamp-npm
-	$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.min.js
-dist/converse-esnext.js: src stamp-npm
-	$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.js optimize=none 
-dist/converse-esnext.min.js: src stamp-npm
-	$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.min.js
-dist/converse-no-dependencies.js: transpile src stamp-npm
-	$(RJS) -o src/build-no-dependencies.js optimize=none out=dist/converse-no-dependencies.js
-dist/converse-no-dependencies.min.js: transpile src stamp-npm
-	$(RJS) -o src/build-no-dependencies.js out=dist/converse-no-dependencies.min.js
+	dist/converse.min.js \
+	dist/converse-headless.js \
+	dist/converse-headless.min.js \
+	dist/converse-no-dependencies.min.js \
+	dist/converse-no-dependencies.js \
+	dist/converse-no-dependencies-es2015.js
+
+dist/converse.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development
+dist/converse.min.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=production
+dist/converse-headless.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development --type=headless
+dist/converse-headless.min.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=production --type=headless
+dist/converse-no-dependencies.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development --type=nodeps
+dist/converse-no-dependencies.min.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=production --type=nodeps 
+dist/converse-no-dependencies-es2015.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development --type=nodeps --lang=es2015
+
 
 .PHONY: dist
 dist:: build
 
 .PHONY: build
-build:: dev css transpile $(BUILDS)
+build:: dev css $(BUILDS)
 
 ########################################################################
 ## Tests

+ 0 - 210
bootstrap.py

@@ -1,210 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Bootstrap a buildout-based project
-
-Simply run this script in a directory containing a buildout.cfg.
-The script accepts buildout command-line options, so you can
-use the -c option to specify an alternate configuration file.
-"""
-
-import os
-import shutil
-import sys
-import tempfile
-
-from optparse import OptionParser
-
-__version__ = '2015-07-01'
-# See zc.buildout's changelog if this version is up to date.
-
-tmpeggs = tempfile.mkdtemp(prefix='bootstrap-')
-
-usage = '''\
-[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
-
-Bootstraps a buildout-based project.
-
-Simply run this script in a directory containing a buildout.cfg, using the
-Python that you want bin/buildout to use.
-
-Note that by using --find-links to point to local resources, you can keep
-this script from going over the network.
-'''
-
-parser = OptionParser(usage=usage)
-parser.add_option("--version",
-                  action="store_true", default=False,
-                  help=("Return bootstrap.py version."))
-parser.add_option("-t", "--accept-buildout-test-releases",
-                  dest='accept_buildout_test_releases',
-                  action="store_true", default=False,
-                  help=("Normally, if you do not specify a --version, the "
-                        "bootstrap script and buildout gets the newest "
-                        "*final* versions of zc.buildout and its recipes and "
-                        "extensions for you.  If you use this flag, "
-                        "bootstrap and buildout will get the newest releases "
-                        "even if they are alphas or betas."))
-parser.add_option("-c", "--config-file",
-                  help=("Specify the path to the buildout configuration "
-                        "file to be used."))
-parser.add_option("-f", "--find-links",
-                  help=("Specify a URL to search for buildout releases"))
-parser.add_option("--allow-site-packages",
-                  action="store_true", default=False,
-                  help=("Let bootstrap.py use existing site packages"))
-parser.add_option("--buildout-version",
-                  help="Use a specific zc.buildout version")
-parser.add_option("--setuptools-version",
-                  help="Use a specific setuptools version")
-parser.add_option("--setuptools-to-dir",
-                  help=("Allow for re-use of existing directory of "
-                        "setuptools versions"))
-
-options, args = parser.parse_args()
-if options.version:
-    print("bootstrap.py version %s" % __version__)
-    sys.exit(0)
-
-
-######################################################################
-# load/install setuptools
-
-try:
-    from urllib.request import urlopen
-except ImportError:
-    from urllib2 import urlopen
-
-ez = {}
-if os.path.exists('ez_setup.py'):
-    exec(open('ez_setup.py').read(), ez)
-else:
-    exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
-
-if not options.allow_site_packages:
-    # ez_setup imports site, which adds site packages
-    # this will remove them from the path to ensure that incompatible versions
-    # of setuptools are not in the path
-    import site
-    # inside a virtualenv, there is no 'getsitepackages'.
-    # We can't remove these reliably
-    if hasattr(site, 'getsitepackages'):
-        for sitepackage_path in site.getsitepackages():
-            # Strip all site-packages directories from sys.path that
-            # are not sys.prefix; this is because on Windows
-            # sys.prefix is a site-package directory.
-            if sitepackage_path != sys.prefix:
-                sys.path[:] = [x for x in sys.path
-                               if sitepackage_path not in x]
-
-setup_args = dict(to_dir=tmpeggs, download_delay=0)
-
-if options.setuptools_version is not None:
-    setup_args['version'] = options.setuptools_version
-if options.setuptools_to_dir is not None:
-    setup_args['to_dir'] = options.setuptools_to_dir
-
-ez['use_setuptools'](**setup_args)
-import setuptools
-import pkg_resources
-
-# This does not (always?) update the default working set.  We will
-# do it.
-for path in sys.path:
-    if path not in pkg_resources.working_set.entries:
-        pkg_resources.working_set.add_entry(path)
-
-######################################################################
-# Install buildout
-
-ws = pkg_resources.working_set
-
-setuptools_path = ws.find(
-    pkg_resources.Requirement.parse('setuptools')).location
-
-# Fix sys.path here as easy_install.pth added before PYTHONPATH
-cmd = [sys.executable, '-c',
-       'import sys; sys.path[0:0] = [%r]; ' % setuptools_path +
-       'from setuptools.command.easy_install import main; main()',
-       '-mZqNxd', tmpeggs]
-
-find_links = os.environ.get(
-    'bootstrap-testing-find-links',
-    options.find_links or
-    ('http://downloads.buildout.org/'
-     if options.accept_buildout_test_releases else None)
-    )
-if find_links:
-    cmd.extend(['-f', find_links])
-
-requirement = 'zc.buildout'
-version = options.buildout_version
-if version is None and not options.accept_buildout_test_releases:
-    # Figure out the most recent final version of zc.buildout.
-    import setuptools.package_index
-    _final_parts = '*final-', '*final'
-
-    def _final_version(parsed_version):
-        try:
-            return not parsed_version.is_prerelease
-        except AttributeError:
-            # Older setuptools
-            for part in parsed_version:
-                if (part[:1] == '*') and (part not in _final_parts):
-                    return False
-            return True
-
-    index = setuptools.package_index.PackageIndex(
-        search_path=[setuptools_path])
-    if find_links:
-        index.add_find_links((find_links,))
-    req = pkg_resources.Requirement.parse(requirement)
-    if index.obtain(req) is not None:
-        best = []
-        bestv = None
-        for dist in index[req.project_name]:
-            distv = dist.parsed_version
-            if _final_version(distv):
-                if bestv is None or distv > bestv:
-                    best = [dist]
-                    bestv = distv
-                elif distv == bestv:
-                    best.append(dist)
-        if best:
-            best.sort()
-            version = best[-1].version
-if version:
-    requirement = '=='.join((requirement, version))
-cmd.append(requirement)
-
-import subprocess
-if subprocess.call(cmd) != 0:
-    raise Exception(
-        "Failed to execute command:\n%s" % repr(cmd)[1:-1])
-
-######################################################################
-# Import and run buildout
-
-ws.add_entry(tmpeggs)
-ws.require(requirement)
-import zc.buildout.buildout
-
-if not [a for a in args if '=' not in a]:
-    args.append('bootstrap')
-
-# if -c was provided, we push it back into args for buildout' main function
-if options.config_file is not None:
-    args[0:0] = ['-c', options.config_file]
-
-zc.buildout.buildout.main(args)
-shutil.rmtree(tmpeggs)

+ 1 - 9
buildout.cfg

@@ -11,12 +11,4 @@ eggs =
     sphinx-bootstrap-theme
 
 [versions]
-docutils = 0.13.1
-Jinja2 = 2.9.5
-MarkupSafe = 0.23
-Pygments = 2.2.0
-six = 1.10.0
-setuptools = 28.6.1
-Sphinx = 1.5.2
-z3c.recipe.egg = 2.0.3
-zc.buildout = 2.5.3
+Sphinx = 1.7.5

+ 0 - 3
builds/README.md

@@ -1,3 +0,0 @@
-This directory exists as a location for intermediate files generated by the
-Babel compiler, before they're bundled into distribution bundles in the
-`./dist/` directory.

+ 503 - 147
css/converse.css

@@ -3,7 +3,7 @@
  * Converse.js (Web-based XMPP instant messaging client)
  * http://conversejs.org
  *
- * Copyright (c) 2012-2016, JC Brand <jc@opkode.com>
+ * Copyright (c) 2013-2018, JC Brand <jc@opkode.com>
  * Licensed under the Mozilla Public License
  */
 @font-face {
@@ -6868,6 +6868,13 @@ body.reset {
   font-size: 14px;
   direction: ltr;
   z-index: 1031; }
+  #conversejs.converse-overlayed > .row {
+    flex-direction: row-reverse; }
+  #conversejs.converse-fullscreen .converse-chatboxes, #conversejs.converse-mobile .converse-chatboxes {
+    width: 100vw;
+    right: 15px; }
+  #conversejs.converse-overlayed {
+    height: 3em; }
   #conversejs .brand-heading {
     font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif; }
     #conversejs .brand-heading .icon-conversejs {
@@ -6878,7 +6885,6 @@ body.reset {
     z-index: 1031;
     position: fixed;
     bottom: 0;
-    height: 2.7rem;
     right: 0; }
   #conversejs ::-webkit-input-placeholder {
     /* Chrome/Opera/Safari */
@@ -6932,6 +6938,8 @@ body.reset {
     min-height: 0; }
   #conversejs strong {
     font-weight: 700; }
+  #conversejs em {
+    font-style: italic; }
   #conversejs ol, #conversejs ul {
     list-style: none; }
   #conversejs li {
@@ -6939,13 +6947,17 @@ body.reset {
   #conversejs ul, #conversejs ol, #conversejs dl {
     font: inherit;
     margin: 0; }
-  #conversejs a, #conversejs a:visited, #conversejs a:hover, #conversejs a:not([href]):not([tabindex]) {
+  #conversejs a, #conversejs a:visited, #conversejs a:not([href]):not([tabindex]) {
     text-decoration: none;
     color: #578EA9;
     text-shadow: none; }
-    #conversejs a.fa, #conversejs a:visited.fa, #conversejs a:hover.fa, #conversejs a:not([href]):not([tabindex]).fa {
+    #conversejs a:hover, #conversejs a:visited:hover, #conversejs a:not([href]):not([tabindex]):hover {
+      color: #345566;
+      text-decoration: none;
+      text-shadow: none; }
+    #conversejs a.fa, #conversejs a:visited.fa, #conversejs a:not([href]):not([tabindex]).fa {
       color: #A8ABA1; }
-      #conversejs a.fa:hover, #conversejs a:visited.fa:hover, #conversejs a:hover.fa:hover, #conversejs a:not([href]):not([tabindex]).fa:hover {
+      #conversejs a.fa:hover, #conversejs a:visited.fa:hover, #conversejs a:not([href]):not([tabindex]).fa:hover {
         color: #818479; }
   #conversejs canvas {
     border-radius: 4px; }
@@ -7201,9 +7213,6 @@ body.reset {
 @media screen and (max-height: 450px) {
   #conversejs {
     left: 0; } }
-#conversejs > .row {
-  flex-direction: row-reverse; }
-
 #conversejs form .form-group {
   margin-bottom: 2em; }
 #conversejs form .form-check-label {
@@ -7283,9 +7292,10 @@ body.reset {
 #conversejs #user-profile-modal label {
   font-weight: bold; }
 
+#conversejs .chatbox-navback {
+  display: none; }
 #conversejs .flyout {
   border-radius: 4px;
-  bottom: 1em;
   position: absolute; }
   @media screen and (max-height: 450px) {
     #conversejs .flyout {
@@ -7314,7 +7324,6 @@ body.reset {
   flex-wrap: nowrap;
   color: #ffffff;
   font-size: 100%;
-  height: 55px;
   margin: 0;
   padding: 0.5em;
   position: relative; }
@@ -7324,6 +7333,8 @@ body.reset {
     height: 36px;
     width: 36px;
     margin-right: 0.5em; }
+  #conversejs .chat-head .chatbox-title .chatroom-description {
+    font-size: 80%; }
   #conversejs .chat-head .chatbox-buttons {
     flex-direction: row-reverse;
     position: relative;
@@ -7377,8 +7388,6 @@ body.reset {
     justify-content: space-between;
     background-color: #3AA569;
     box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-    height: 450px;
-    min-height: 225px;
     z-index: 1;
     overflow-y: scroll;
     width: 100%; }
@@ -7486,7 +7495,6 @@ body.reset {
       width: 100%;
       border: none;
       min-height: 60px;
-      max-height: 200px;
       margin-bottom: -4px; }
       #conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler {
         height: 42px; }
@@ -7551,7 +7559,6 @@ body.reset {
           #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu a {
             color: #578EA9; }
           #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker {
-            height: 100px;
             overflow: scroll;
             padding: 0.5em; }
           #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li {
@@ -7618,75 +7625,209 @@ body.reset {
       top: 0;
       left: 0; }
 
-#conversejs.converse-fullscreen .chatbox-btn {
-  font-size: 16px; }
-#conversejs.converse-fullscreen .chat-head .chatbox-buttons {
-  flex: 0 0 25%;
-  max-width: 25%; }
-
-@media screen and (max-width: 767px) {
-  #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) .sidebar {
-    display: block; }
-  #conversejs:not(.converse-embedded) .chatbox {
-    width: calc(100% - 50px); }
-    #conversejs:not(.converse-embedded) .chatbox .row .box-flyout {
-      left: 50px;
-      bottom: 0;
-      height: 100vh;
-      box-shadow: none; } }
-#converse-embedded-chat .chat-head,
-#conversejs:not(.fullscreen) .chat-head {
+/* ******************* Overlay and embedded styles *************************** */
+#conversejs.converse-embedded .chat-head,
+#conversejs.converse-overlayed .chat-head {
   border-top-left-radius: 4px;
   border-top-right-radius: 4px; }
   @media screen and (max-height: 450px) {
-    #converse-embedded-chat .chat-head,
-    #conversejs:not(.fullscreen) .chat-head {
+    #conversejs.converse-embedded .chat-head,
+    #conversejs.converse-overlayed .chat-head {
       border-top-left-radius: 0;
       border-top-right-radius: 0; } }
   @media screen and (max-width: 480px) {
-    #converse-embedded-chat .chat-head,
-    #conversejs:not(.fullscreen) .chat-head {
+    #conversejs.converse-embedded .chat-head,
+    #conversejs.converse-overlayed .chat-head {
       border-top-left-radius: 0;
       border-top-right-radius: 0; } }
-#converse-embedded-chat .chatbox,
-#conversejs:not(.fullscreen) .chatbox {
+  #conversejs.converse-embedded .chat-head .chatbox-title,
+  #conversejs.converse-overlayed .chat-head .chatbox-title {
+    flex: 0 0 66.6666666667%;
+    max-width: 66.6666666667%; }
+  #conversejs.converse-embedded .chat-head .chatbox-buttons,
+  #conversejs.converse-overlayed .chat-head .chatbox-buttons {
+    flex: 0 0 33.3333333333%;
+    max-width: 33.3333333333%; }
+#conversejs.converse-embedded .chatbox,
+#conversejs.converse-overlayed .chatbox {
   min-width: 250px !important;
   width: 250px; }
-  #converse-embedded-chat .chatbox .box-flyout,
-  #conversejs:not(.fullscreen) .chatbox .box-flyout {
+  #conversejs.converse-embedded .chatbox .box-flyout,
+  #conversejs.converse-overlayed .chatbox .box-flyout {
     min-width: 250px !important;
     width: 250px; }
-  #converse-embedded-chat .chatbox .chat-body .chat-message,
-  #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message {
+  #conversejs.converse-embedded .chatbox .chat-body .chat-message,
+  #conversejs.converse-overlayed .chatbox .chat-body .chat-message {
     line-height: 20px; }
-    #converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-author,
-    #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message .chat-msg-author {
+    #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-author,
+    #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-author {
       line-height: 20px; }
-    #converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content,
-    #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message .chat-msg-content {
+    #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content,
+    #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content {
       line-height: 20px; }
-      #converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content .emojione,
-      #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message .chat-msg-content .emojione {
+      #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content .emojione,
+      #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content .emojione {
         margin-bottom: -5px; }
-#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
-#conversejs:not(.fullscreen) .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
+#conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
+#conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
   min-width: 235px; }
-  #converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar,
-  #conversejs:not(.fullscreen) .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar {
+  #conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar,
+  #conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar {
     width: 100%; }
-    #converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category,
-    #conversejs:not(.fullscreen) .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category {
+    #conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category,
+    #conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category {
       float: left; }
 
+#conversejs.converse-overlayed .flyout {
+  bottom: 1em; }
+#conversejs.converse-overlayed .box-flyout {
+  height: 450px;
+  min-height: 225px; }
+#conversejs.converse-overlayed .chat-head {
+  height: 55px; }
+#conversejs.converse-overlayed .chat-textarea {
+  max-height: 200px; }
+#conversejs.converse-overlayed .emoji-picker {
+  height: 100px; }
+
 @media (max-width: 767.98px) {
-  #conversejs:not(.converse-fullscreen):not(.converse-embedded) > .row {
+  #conversejs.converse-overlayed > .row {
     flex-direction: column; }
-    #conversejs:not(.converse-fullscreen):not(.converse-embedded) > .row.no-gutters {
+    #conversejs.converse-overlayed > .row.no-gutters {
       margin: -1em; } }
+/* ******************* Fullpage styles *************************** */
+#conversejs.converse-fullscreen .flyout {
+  border-radius: 0;
+  border-top: 0.8em solid #3AA569;
+  border: 1.2em solid #3AA569;
+  bottom: 0; }
+#conversejs.converse-fullscreen .chatbox-btn {
+  font-size: 16px;
+  margin: 0 0.3em; }
+#conversejs.converse-fullscreen .chat-head {
+  height: 62px;
+  font-size: 20px;
+  padding: 0; }
+  #conversejs.converse-fullscreen .chat-head .user-custom-message {
+    font-size: 50%;
+    height: auto;
+    line-height: 16px; }
+  #conversejs.converse-fullscreen .chat-head .chatbox-title {
+    flex: 0 0 83.3333333333%;
+    max-width: 83.3333333333%; }
+  #conversejs.converse-fullscreen .chat-head .chatbox-buttons {
+    flex: 0 0 16.6666666667%;
+    max-width: 16.6666666667%; }
+#conversejs.converse-fullscreen .chat-textarea {
+  max-height: 400px; }
+#conversejs.converse-fullscreen .emoji-picker {
+  height: 150px; }
+#conversejs.converse-fullscreen .chatbox {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  position: relative;
+  width: 100%;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px; }
+  @media (min-width: 768px) {
+    #conversejs.converse-fullscreen .chatbox {
+      flex: 0 0 75%;
+      max-width: 75%; } }
+  @media (min-width: 992px) {
+    #conversejs.converse-fullscreen .chatbox {
+      flex: 0 0 75%;
+      max-width: 75%; } }
+  @media (min-width: 1200px) {
+    #conversejs.converse-fullscreen .chatbox {
+      flex: 0 0 83.3333333333%;
+      max-width: 83.3333333333%; } }
+  #conversejs.converse-fullscreen .chatbox .box-flyout {
+    background-color: #3AA569;
+    box-shadow: none;
+    height: 100vh;
+    min-height: 50vh;
+    width: 100%; }
+  #conversejs.converse-fullscreen .chatbox .chat-body {
+    background-color: #3AA569;
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px; }
+    #conversejs.converse-fullscreen .chatbox .chat-body .chat-message {
+      line-height: 16px;
+      font-size: 12px; }
+      #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-author {
+        line-height: 16px; }
+      #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content {
+        line-height: 16px; }
+        #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content .emojione {
+          height: 16px;
+          margin-bottom: -4px; }
+  #conversejs.converse-fullscreen .chatbox .chat-content {
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px; }
+  #conversejs.converse-fullscreen .chatbox .chat-title {
+    font-size: 20px;
+    line-height: 24px; }
+  #conversejs.converse-fullscreen .chatbox .sendXMPPMessage ul {
+    width: 100%; }
+  #conversejs.converse-fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category-picker {
+    margin-right: 5em; }
+  #conversejs.converse-fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category {
+    padding-left: 10px;
+    padding-right: 10px; }
+
+@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: 100vh;
+      box-shadow: none; }
+
+  #conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback,
+  #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback,
+  #conversejs.converse-embedded .chatbox .box-flyout .chatbox-navback,
+  #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback {
+    display: flex;
+    flex: 0 0 16.6666666667%;
+    max-width: 16.6666666667%; }
+    #conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,
+    #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,
+    #conversejs.converse-embedded .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,
+    #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before {
+      color: white; }
+  #conversejs.converse-mobile .chatbox .box-flyout .chatbox-title,
+  #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-title,
+  #conversejs.converse-embedded .chatbox .box-flyout .chatbox-title,
+  #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-title {
+    flex: 0 0 58.3333333333%;
+    max-width: 58.3333333333%; }
+  #conversejs.converse-mobile .chatbox .box-flyout .chatbox-buttons,
+  #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-buttons,
+  #conversejs.converse-embedded .chatbox .box-flyout .chatbox-buttons,
+  #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-buttons {
+    flex: 0 0 25%;
+    max-width: 25%; } }
+#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: #578EA9;
+      font-size: 16px; }
+      #conversejs .oauth-providers .oauth-provider .oauth-login:hover {
+        color: #345566; }
+      #conversejs .oauth-providers .oauth-provider .oauth-login i {
+        color: #578EA9;
+        font-size: 20px;
+        margin-right: 0.5em; }
 #conversejs .set-xmpp-status .fa-circle, #conversejs .xmpp-status .fa-circle, #conversejs .roster-contacts .fa-circle {
   color: #3AA569; }
 #conversejs .set-xmpp-status .fa-minus-circle, #conversejs .xmpp-status .fa-minus-circle, #conversejs .roster-contacts .fa-minus-circle {
@@ -7805,11 +7946,6 @@ body.reset {
       color: #578EA9; }
   #conversejs #controlbox .toggle-register-login {
     font-weight: bold; }
-  #conversejs #controlbox .oauth-login {
-    margin-left: 0;
-    color: #666; }
-    #conversejs #controlbox .oauth-login .icon-social:before {
-      font-size: 16px; }
   #conversejs #controlbox .controlbox-pane .userinfo {
     padding-bottom: 1em; }
     #conversejs #controlbox .controlbox-pane .userinfo .username {
@@ -7884,6 +8020,7 @@ body.reset {
     #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: 0.5em; }
@@ -7925,7 +8062,6 @@ body.reset {
       #conversejs:not(.converse-embedded) .converse-chatboxes .converse-chatroom {
         font-size: 14px; }
       #conversejs:not(.converse-embedded) .converse-chatboxes .chatbox .box-flyout {
-        top: -100vh;
         margin-left: 15px;
         left: 0;
         bottom: 0;
@@ -7933,31 +8069,32 @@ body.reset {
         width: 100vw !important;
         height: 100vh !important; }
       #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox {
-        order: 0; }
+        width: 100vw !important; }
         #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .box-flyout {
           width: 100vw !important;
-          height: 100vh !important; }
+          height: 100vh !important;
+          margin-left: 30px; }
         #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .sidebar {
           display: block; }
       #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open .chatbox:not(#controlbox) {
         display: none; }
       #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open #controlbox .controlbox-pane {
         display: block; } }
-#conversejs:not(.converse-fullscreen) #controlbox {
+#conversejs.converse-overlayed #controlbox {
   order: -1;
   min-width: 250px !important;
   width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .box-flyout {
+  #conversejs.converse-overlayed #controlbox .box-flyout {
     min-width: 250px !important;
     width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox:not(.logged-out) .controlbox-head {
+  #conversejs.converse-overlayed #controlbox:not(.logged-out) .controlbox-head {
     height: 15px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head {
+  #conversejs.converse-overlayed #controlbox .controlbox-head {
     display: flex;
     flex-direction: row-reverse;
     flex-wrap: nowrap;
     justify-content: space-between; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .brand-heading {
+    #conversejs.converse-overlayed #controlbox .controlbox-head .brand-heading {
       position: relative;
       width: 100%;
       min-height: 1px;
@@ -7967,18 +8104,158 @@ body.reset {
       max-width: 66.6666666667%;
       color: #666;
       font-size: 2em; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .chatbox-btn {
+    #conversejs.converse-overlayed #controlbox .controlbox-head .chatbox-btn {
       color: #578EA9;
       margin: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register, #conversejs:not(.converse-fullscreen) #controlbox #converse-login {
+  #conversejs.converse-overlayed #controlbox #converse-register, #conversejs.converse-overlayed #controlbox #converse-login {
     flex: 0 0 100%;
     max-width: 100%;
     padding-bottom: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register .button-cancel {
+  #conversejs.converse-overlayed #controlbox #converse-register .button-cancel {
     font-size: 90%; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-panes {
+  #conversejs.converse-overlayed #controlbox .controlbox-panes {
     border-radius: 4px; }
 
+#conversejs.converse-fullscreen #controlbox,
+#conversejs.converse-mobile #controlbox {
+  position: relative;
+  width: 100%;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px;
+  margin: 0; }
+  @media (min-width: 768px) {
+    #conversejs.converse-fullscreen #controlbox,
+    #conversejs.converse-mobile #controlbox {
+      flex: 0 0 25%;
+      max-width: 25%; } }
+  @media (min-width: 992px) {
+    #conversejs.converse-fullscreen #controlbox,
+    #conversejs.converse-mobile #controlbox {
+      flex: 0 0 25%;
+      max-width: 25%; } }
+  @media (min-width: 1200px) {
+    #conversejs.converse-fullscreen #controlbox,
+    #conversejs.converse-mobile #controlbox {
+      flex: 0 0 16.6666666667%;
+      max-width: 16.6666666667%; } }
+  #conversejs.converse-fullscreen #controlbox.logged-out,
+  #conversejs.converse-mobile #controlbox.logged-out {
+    flex: 0 0 100%;
+    max-width: 100%; }
+  #conversejs.converse-fullscreen #controlbox .controlbox-pane,
+  #conversejs.converse-mobile #controlbox .controlbox-pane {
+    border-radius: 0; }
+  #conversejs.converse-fullscreen #controlbox .flyout,
+  #conversejs.converse-mobile #controlbox .flyout {
+    border-radius: 0; }
+  #conversejs.converse-fullscreen #controlbox #converse-login-panel,
+  #conversejs.converse-mobile #controlbox #converse-login-panel {
+    border-radius: 0; }
+    #conversejs.converse-fullscreen #controlbox #converse-login-panel .converse-form,
+    #conversejs.converse-mobile #controlbox #converse-login-panel .converse-form {
+      padding: 3em 2em 3em; }
+  #conversejs.converse-fullscreen #controlbox .toggle-register-login,
+  #conversejs.converse-mobile #controlbox .toggle-register-login {
+    line-height: 24px; }
+  #conversejs.converse-fullscreen #controlbox .brand-heading-container,
+  #conversejs.converse-mobile #controlbox .brand-heading-container {
+    flex: 0 0 100%;
+    max-width: 100%;
+    text-align: center; }
+    #conversejs.converse-fullscreen #controlbox .brand-heading-container .brand-heading,
+    #conversejs.converse-mobile #controlbox .brand-heading-container .brand-heading {
+      font-size: 150%;
+      font-size: 600%;
+      padding: 0.7em 0 0 0;
+      opacity: 0.8;
+      color: #387592; }
+    #conversejs.converse-fullscreen #controlbox .brand-heading-container .brand-subtitle,
+    #conversejs.converse-mobile #controlbox .brand-heading-container .brand-subtitle {
+      font-size: 90%;
+      padding: 0.5em; }
+    @media screen and (max-width: 480px) {
+      #conversejs.converse-fullscreen #controlbox .brand-heading-container .brand-heading,
+      #conversejs.converse-mobile #controlbox .brand-heading-container .brand-heading {
+        font-size: 400%; } }
+  #conversejs.converse-fullscreen #controlbox.logged-out,
+  #conversejs.converse-mobile #controlbox.logged-out {
+    flex: 0 0 100%;
+    max-width: 100%;
+    opacity: 0;
+    /* make things invisible upon start */
+    -webkit-animation-name: fadein;
+    -moz-animation-name: fadein;
+    animation-name: fadein;
+    -webkit-animation-fill-mode: forwards;
+    -moz-animation-fill-mode: forwards;
+    animation-fill-mode: forwards;
+    -webkit-animation-duration: 0.75s;
+    -moz-animation-duration: 0.75s;
+    animation-duration: 0.75s;
+    -webkit-animation-timing-function: ease;
+    -moz-animation-timing-function: ease;
+    animation-timing-function: ease;
+    width: 100%; }
+    #conversejs.converse-fullscreen #controlbox.logged-out .box-flyout,
+    #conversejs.converse-mobile #controlbox.logged-out .box-flyout {
+      width: 100%; }
+  #conversejs.converse-fullscreen #controlbox .box-flyout,
+  #conversejs.converse-mobile #controlbox .box-flyout {
+    border: 0;
+    width: 100%;
+    z-index: 1;
+    background-color: #578EA9; }
+    #conversejs.converse-fullscreen #controlbox .box-flyout .controlbox-head,
+    #conversejs.converse-mobile #controlbox .box-flyout .controlbox-head {
+      display: none; }
+  #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+  #conversejs.converse-mobile #controlbox #converse-register,
+  #conversejs.converse-mobile #controlbox #converse-login {
+    position: relative;
+    width: 100%;
+    min-height: 1px;
+    padding-right: 15px;
+    padding-left: 15px;
+    flex: 0 0 66.6666666667%;
+    max-width: 66.6666666667%;
+    margin-left: 16.6666666667%; }
+    @media (min-width: 576px) {
+      #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+      #conversejs.converse-mobile #controlbox #converse-register,
+      #conversejs.converse-mobile #controlbox #converse-login {
+        flex: 0 0 66.6666666667%;
+        max-width: 66.6666666667%;
+        margin-left: 16.6666666667%; } }
+    @media (min-width: 768px) {
+      #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+      #conversejs.converse-mobile #controlbox #converse-register,
+      #conversejs.converse-mobile #controlbox #converse-login {
+        flex: 0 0 66.6666666667%;
+        max-width: 66.6666666667%;
+        margin-left: 16.6666666667%; } }
+    @media (min-width: 992px) {
+      #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+      #conversejs.converse-mobile #controlbox #converse-register,
+      #conversejs.converse-mobile #controlbox #converse-login {
+        flex: 0 0 50%;
+        max-width: 50%;
+        margin-left: 25%; } }
+    #conversejs.converse-fullscreen #controlbox #converse-register .title, #conversejs.converse-fullscreen #controlbox #converse-register .instructions, #conversejs.converse-fullscreen #controlbox #converse-login .title, #conversejs.converse-fullscreen #controlbox #converse-login .instructions,
+    #conversejs.converse-mobile #controlbox #converse-register .title,
+    #conversejs.converse-mobile #controlbox #converse-register .instructions,
+    #conversejs.converse-mobile #controlbox #converse-login .title,
+    #conversejs.converse-mobile #controlbox #converse-login .instructions {
+      margin: 1em 0; }
+    #conversejs.converse-fullscreen #controlbox #converse-register input[type=submit],
+    #conversejs.converse-fullscreen #controlbox #converse-register input[type=button], #conversejs.converse-fullscreen #controlbox #converse-login input[type=submit],
+    #conversejs.converse-fullscreen #controlbox #converse-login input[type=button],
+    #conversejs.converse-mobile #controlbox #converse-register input[type=submit],
+    #conversejs.converse-mobile #controlbox #converse-register input[type=button],
+    #conversejs.converse-mobile #controlbox #converse-login input[type=submit],
+    #conversejs.converse-mobile #controlbox #converse-login input[type=button] {
+      width: auto; }
+
 #conversejs .list-container {
   text-align: left;
   padding: 0.3em 0; }
@@ -8005,6 +8282,13 @@ body.reset {
     #conversejs .list-container .items-list .open-headline:hover,
     #conversejs .list-container .items-list .open-chatroom:hover {
       background-color: #eff4f7; }
+      #conversejs .list-container .items-list .available-chatroom:hover a.add-bookmark,
+      #conversejs .list-container .items-list .available-chatroom:hover a.room-info,
+      #conversejs .list-container .items-list .open-headline:hover a.add-bookmark,
+      #conversejs .list-container .items-list .open-headline:hover a.room-info,
+      #conversejs .list-container .items-list .open-chatroom:hover a.add-bookmark,
+      #conversejs .list-container .items-list .open-chatroom:hover a.room-info {
+        display: block !important; }
     #conversejs .list-container .items-list .available-chatroom.unread-msgs .msgs-indicator,
     #conversejs .list-container .items-list .open-headline.unread-msgs .msgs-indicator,
     #conversejs .list-container .items-list .open-chatroom.unread-msgs .msgs-indicator {
@@ -8022,10 +8306,18 @@ body.reset {
     #conversejs .list-container .items-list .open-headline a:hover,
     #conversejs .list-container .items-list .open-chatroom a:hover {
       color: #206485; }
-    #conversejs .list-container .items-list .available-chatroom a.room-info:before,
-    #conversejs .list-container .items-list .open-headline a.room-info:before,
-    #conversejs .list-container .items-list .open-chatroom a.room-info:before {
-      font-size: 15px; }
+    #conversejs .list-container .items-list .available-chatroom a.add-bookmark, #conversejs .list-container .items-list .available-chatroom a.room-info,
+    #conversejs .list-container .items-list .open-headline a.add-bookmark,
+    #conversejs .list-container .items-list .open-headline a.room-info,
+    #conversejs .list-container .items-list .open-chatroom a.add-bookmark,
+    #conversejs .list-container .items-list .open-chatroom a.room-info {
+      display: none; }
+      #conversejs .list-container .items-list .available-chatroom a.add-bookmark:before, #conversejs .list-container .items-list .available-chatroom a.room-info:before,
+      #conversejs .list-container .items-list .open-headline a.add-bookmark:before,
+      #conversejs .list-container .items-list .open-headline a.room-info:before,
+      #conversejs .list-container .items-list .open-chatroom a.add-bookmark:before,
+      #conversejs .list-container .items-list .open-chatroom a.room-info:before {
+        font-size: 15px; }
     #conversejs .list-container .items-list .available-chatroom a.open-room,
     #conversejs .list-container .items-list .open-headline a.open-room,
     #conversejs .list-container .items-list .open-chatroom a.open-room {
@@ -8070,7 +8362,6 @@ body.reset {
   position: relative;
   margin: 0;
   height: 194px;
-  height: calc(~"100% - 50px - 20px");
   padding: 0;
   overflow: hidden;
   height: calc(100% - 70px);
@@ -8092,7 +8383,6 @@ body.reset {
       font-size: calc(14px - 2px); }
     #conversejs #converse-roster .roster-filter-form .state-type {
       font-size: calc(14px - 2px);
-      height: 25px;
       width: 100%; }
   #conversejs #converse-roster .roster-contacts {
     padding: 0;
@@ -8163,8 +8453,7 @@ body.reset {
               max-width: 60%; }
           #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .avatar {
             float: left;
-            display: inline-block;
-            height: 60px; }
+            display: inline-block; }
         #conversejs #converse-roster .roster-contacts .roster-group li.current-xmpp-contact span {
           font-size: 14px;
           float: left;
@@ -8202,13 +8491,33 @@ body.reset {
 #conversejs .add-chatroom input[type="submit"],
 #conversejs .add-chatroom input[type="button"] {
   margin: 0.3em 0; }
+#conversejs.converse-embedded #room-details-modal .features-list,
+#conversejs #room-details-modal .features-list {
+  margin-left: 1em; }
+#conversejs.converse-embedded .chatroom-features,
+#conversejs .chatroom-features {
+  width: 100%; }
+  #conversejs.converse-embedded .chatroom-features .features-list,
+  #conversejs .chatroom-features .features-list {
+    padding-top: 0; }
+    #conversejs.converse-embedded .chatroom-features .features-list .feature,
+    #conversejs .chatroom-features .features-list .feature {
+      width: 100%;
+      margin-right: 0.5em;
+      padding-right: 0;
+      font-size: 1em;
+      cursor: help; }
+      #conversejs.converse-embedded .chatroom-features .features-list .feature .fa,
+      #conversejs .chatroom-features .features-list .feature .fa {
+        margin-right: 0.5em;
+        color: #666; }
 #conversejs.converse-embedded .chat-head-chatroom,
 #conversejs .chat-head-chatroom {
   background-color: #E77051; }
   #conversejs.converse-embedded .chat-head-chatroom .chatroom-description,
   #conversejs .chat-head-chatroom .chatroom-description {
     color: #f6ccc1;
-    font-size: 16px;
+    font-size: 14px;
     font-size: 70%;
     margin-top: 3px;
     overflow-y: hidden;
@@ -8295,17 +8604,13 @@ body.reset {
       #conversejs .chatroom .box-flyout .chatroom-body .chat-area {
         display: flex;
         flex-direction: column;
-        word-wrap: break-word;
-        min-width: 250px; }
+        word-wrap: break-word; }
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator,
         #conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator {
           background-color: #E77051; }
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
         #conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
           height: 100%; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area.full {
-          min-width: 100%; }
       #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,
       #conversejs .chatroom .box-flyout .chatroom-body .occupants {
         display: flex;
@@ -8318,20 +8623,18 @@ body.reset {
         border-left: 1px solid #666;
         border-bottom-right-radius: 4px;
         padding: 0.5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
-          font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-          padding: 0.3em 0; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features {
-          width: 100%; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature {
-            float: left;
-            margin-right: 0.5em;
-            padding-right: 0;
-            font-size: 1em;
-            cursor: help; }
+        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header,
+        #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header {
+          display: flex;
+          flex-direction: column; }
+          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants,
+          #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants {
+            align-self: flex-end;
+            cursor: pointer; }
+          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header .occupants-heading,
+          #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header .occupants-heading {
+            font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
+            padding: 0.3em 0; }
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul,
         #conversejs .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul {
           padding: 0; }
@@ -8351,15 +8654,6 @@ body.reset {
             flex-basis: 0;
             flex-grow: 1;
             border-bottom: 1px solid lightgrey; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list {
-            padding-top: 0; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature {
-              width: 100%; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa {
-                color: #666; }
           #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li,
           #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li {
             cursor: default;
@@ -8455,14 +8749,86 @@ body.reset {
     width: 100%;
     border: 1px solid #999; }
 
-#conversejs .chatbox.chatroom {
+/* ******************* Overlay  styles *************************** */
+#conversejs.converse-overlayed .chatbox.chatroom {
   min-width: 400px !important;
   width: 400px; }
-  #conversejs .chatbox.chatroom .box-flyout {
+  #conversejs.converse-overlayed .chatbox.chatroom .box-flyout {
     min-width: 400px !important;
     width: 400px; }
-  #conversejs .chatbox.chatroom .chatroom-body .occupants .chatroom-features .feature {
+  #conversejs.converse-overlayed .chatbox.chatroom .chatbox-title {
+    flex: 0 0 66.6666666667%;
+    max-width: 66.6666666667%; }
+    #conversejs.converse-overlayed .chatbox.chatroom .chatbox-title .chatroom-description {
+      font-size: 80%; }
+  #conversejs.converse-overlayed .chatbox.chatroom .chatbox-buttons {
+    flex: 0 0 33.3333333333%;
+    max-width: 33.3333333333%; }
+  #conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .chatroom-features .feature {
     font-size: 12px; }
+  #conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .chat-area {
+    min-width: 250px; }
+
+#conversejs.converse-fullscreen .chatroom .box-flyout .chatbox-title {
+  flex: 0 0 75%;
+  max-width: 75%; }
+#conversejs.converse-fullscreen .chatroom .box-flyout .chatbox-buttons {
+  flex: 0 0 25%;
+  max-width: 25%; }
+
+@media (max-width: 767.98px) {
+  #conversejs:not(.converse-embedded) .chatroom {
+    width: 100vw !important; }
+    #conversejs:not(.converse-embedded) .chatroom .box-flyout .chatbox-navback {
+      flex: 0 0 16.6666666667%;
+      max-width: 16.6666666667%; }
+    #conversejs:not(.converse-embedded) .chatroom .box-flyout .chatbox-title {
+      flex: 0 0 58.3333333333%;
+      max-width: 58.3333333333%; }
+    #conversejs:not(.converse-embedded) .chatroom .box-flyout .chatbox-buttons {
+      flex: 0 0 25%;
+      max-width: 25%; } }
+#conversejs.converse-fullscreen .chatroom .box-flyout,
+#conversejs.converse-mobile .chatroom .box-flyout {
+  background-color: #E77051;
+  border: 1.2em solid #E77051;
+  border-top: 0.8em solid #E77051;
+  width: 100%; }
+  #conversejs.converse-fullscreen .chatroom .box-flyout .chatbox-title .chatroom-description,
+  #conversejs.converse-mobile .chatroom .box-flyout .chatbox-title .chatroom-description {
+    font-size: 70%; }
+  #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body,
+  #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body {
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px; }
+    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chatroom-form-container,
+    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chatroom-form-container {
+      border-radius: 4px; }
+    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area,
+    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area {
+      border-top-left-radius: 4px; }
+      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
+      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
+        border-top-left-radius: 4px; }
+      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full,
+      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full {
+        max-width: 100%; }
+        #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-fullscreen .chatroom .box-flyout .chatroom-body .occupants,
+    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants {
+      border-top-right-radius: 4px;
+      padding: 1em; }
+      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
+      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
+        font-size: 16px; }
+      #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: 12px; }
+#conversejs.converse-fullscreen .chatroom .room-invite span .invited-contact,
+#conversejs.converse-mobile .chatroom .room-invite span .invited-contact {
+  margin: 0 0 0.5em -1px; }
 
 #conversejs .chatbox.headlines .chat-head.chat-head-chatbox {
   background-color: #E7A151; }
@@ -8474,6 +8840,14 @@ body.reset {
 #conversejs .chatbox.headlines .chat-content {
   height: 100%; }
 
+#conversejs.converse-fullscreen .chatbox.headlines .box-flyout {
+  background-color: #E7A151; }
+#conversejs.converse-fullscreen .chatbox.headlines .chat-head.chat-head-chatbox {
+  background-color: #E7A151; }
+#conversejs.converse-fullscreen .chatbox.headlines .flyout {
+  border: 1.2em solid #E7A151;
+  border-top: 0.8em solid #E7A151; }
+
 #conversejs .message.date-separator {
   height: 2em;
   margin: 0;
@@ -8600,7 +8974,7 @@ body.reset {
 @media screen and (max-width: 767px) {
   #conversejs:not(.converse-embedded) .message.chat-msg .chat-msg-author {
     white-space: normal; } }
-#conversejs:not(.fullscreen) #minimized-chats {
+#conversejs.converse-overlayed #minimized-chats {
   order: 100;
   width: 130px;
   margin-bottom: -1em;
@@ -8609,10 +8983,10 @@ body.reset {
   color: white;
   margin-right: 0.5em;
   padding: 0; }
-  #conversejs:not(.fullscreen) #minimized-chats .badge {
+  #conversejs.converse-overlayed #minimized-chats .badge {
     bottom: 8px;
     border: 1px solid #818479; }
-  #conversejs:not(.fullscreen) #minimized-chats #toggle-minimized-chats {
+  #conversejs.converse-overlayed #minimized-chats #toggle-minimized-chats {
     border-top-left-radius: 4px;
     border-top-right-radius: 4px;
     background-color: #578EA9;
@@ -8624,7 +8998,7 @@ body.reset {
     text-overflow: ellipsis;
     display: block;
     height: 45px; }
-  #conversejs:not(.fullscreen) #minimized-chats a.restore-chat {
+  #conversejs.converse-overlayed #minimized-chats a.restore-chat {
     padding: 1px 0 1px 5px;
     color: white;
     line-height: 15px;
@@ -8632,24 +9006,24 @@ body.reset {
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap; }
-    #conversejs:not(.fullscreen) #minimized-chats a.restore-chat:hover {
+    #conversejs.converse-overlayed #minimized-chats a.restore-chat:hover {
       text-decoration: none; }
-  #conversejs:not(.fullscreen) #minimized-chats a.restore-chat:visited {
+  #conversejs.converse-overlayed #minimized-chats a.restore-chat:visited {
     color: white; }
-  #conversejs:not(.fullscreen) #minimized-chats .minimized-chats-flyout {
+  #conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout {
     flex-direction: column-reverse;
     bottom: 42px;
     width: 130px; }
-    #conversejs:not(.fullscreen) #minimized-chats .minimized-chats-flyout .chat-head {
+    #conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head {
       padding: 0.3em;
       border-radius: 4px;
       height: 35px;
       margin-bottom: 0.2em;
       box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
       width: 100%; }
-    #conversejs:not(.fullscreen) #minimized-chats .minimized-chats-flyout.minimized {
+    #conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout.minimized {
       height: auto; }
-  #conversejs:not(.fullscreen) #minimized-chats .unread-message-count {
+  #conversejs.converse-overlayed #minimized-chats .unread-message-count {
     font-weight: bold;
     background-color: white;
     border: 1px solid;
@@ -8662,31 +9036,24 @@ body.reset {
     position: absolute;
     right: 116px;
     bottom: 10px; }
-  #conversejs:not(.fullscreen) #minimized-chats .unread-message-count-hidden,
-  #conversejs:not(.fullscreen) #minimized-chats .chat-head-message-count-hidden {
+  #conversejs.converse-overlayed #minimized-chats .unread-message-count-hidden,
+  #conversejs.converse-overlayed #minimized-chats .chat-head-message-count-hidden {
     display: none; }
 
-#converse-embedded-chat [hidden],
 #conversejs [hidden] {
   display: none; }
-#converse-embedded-chat .visually-hidden,
 #conversejs .visually-hidden {
   position: absolute;
   clip: rect(0, 0, 0, 0); }
-#converse-embedded-chat .form-group .awesomplete,
 #conversejs .form-group .awesomplete {
   width: 100%; }
-#converse-embedded-chat div.awesomplete,
 #conversejs div.awesomplete {
   display: inline-block;
   position: relative; }
-  #converse-embedded-chat div.awesomplete mark,
   #conversejs div.awesomplete mark {
     background: #FFB9A7; }
-  #converse-embedded-chat div.awesomplete > input,
   #conversejs div.awesomplete > input {
     display: block; }
-  #converse-embedded-chat div.awesomplete > ul,
   #conversejs div.awesomplete > ul {
     position: absolute;
     left: 0;
@@ -8703,7 +9070,6 @@ body.reset {
     border: 1px solid rgba(0, 0, 0, 0.3);
     box-shadow: 0.05em 0.2em 0.6em rgba(0, 0, 0, 0.2);
     text-shadow: none; }
-    #converse-embedded-chat div.awesomplete > ul:before,
     #conversejs div.awesomplete > ul:before {
       content: "";
       position: absolute;
@@ -8717,44 +9083,34 @@ body.reset {
       border-bottom: 0;
       -webkit-transform: rotate(45deg);
       transform: rotate(45deg); }
-    #converse-embedded-chat div.awesomplete > ul > li,
     #conversejs div.awesomplete > ul > li {
       text-overflow: ellipsis;
       overflow-x: hidden;
       position: relative;
       cursor: pointer;
       padding: 1em; }
-#converse-embedded-chat div.awesomplete > ul[hidden],
-#converse-embedded-chat div.awesomplete > ul:empty,
 #conversejs div.awesomplete > ul[hidden],
 #conversejs div.awesomplete > ul:empty {
   display: none; }
 @supports (transform: scale(0)) {
-  #converse-embedded-chat div.awesomplete > ul,
   #conversejs div.awesomplete > ul {
     transition: 0.3s cubic-bezier(0.4, 0.2, 0.5, 1.4);
     transform-origin: 1.43em -.43em; }
-  #converse-embedded-chat div.awesomplete > ul[hidden],
-  #converse-embedded-chat div.awesomplete > ul:empty,
   #conversejs div.awesomplete > ul[hidden],
   #conversejs div.awesomplete > ul:empty {
     opacity: 0;
     transform: scale(0);
     display: block;
     transition-timing-function: ease; } }
-#converse-embedded-chat div.awesomplete > ul > li:hover,
 #conversejs div.awesomplete > ul > li:hover {
   background: #E77051;
   color: white; }
-#converse-embedded-chat div.awesomplete > ul > li[aria-selected="true"],
 #conversejs div.awesomplete > ul > li[aria-selected="true"] {
   background: #3d6d8f;
   color: white; }
-#converse-embedded-chat div.awesomplete li:hover mark,
 #conversejs div.awesomplete li:hover mark {
   background: #A53214;
   color: white; }
-#converse-embedded-chat div.awesomplete li[aria-selected="true"] mark,
 #conversejs div.awesomplete li[aria-selected="true"] mark {
   background: #3d6b00;
   color: inherit; }

+ 26 - 0
css/fullpage.css

@@ -0,0 +1,26 @@
+body {
+    font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
+    color: #ffffff;
+    background-color: #578EA9;
+}
+.brand-heading {
+    font-size: 600%;
+    margin-left: -10%;
+}
+.icon-conversejs {
+    font-size: 88%;
+}
+.brand-heading div.content {
+    height: 100vh;
+    width: 100vw;
+    position: fixed;
+    background-color: #578EA9;
+}
+.brand-heading div.content .inner-content {
+    text-align: center;
+    padding: 7%;
+}
+p.no-chats {
+    padding-right: 10%;
+    font-size: 120%;
+}

+ 0 - 8908
css/inverse.css

@@ -1,8908 +0,0 @@
-@charset "UTF-8";
-/*!
- * Converse.js (Web-based XMPP instant messaging client)
- * http://conversejs.org
- *
- * Copyright (c) 2012-2014, JC Brand <jc@opkode.com>
- * Licensed under the Mozilla Public License
- */
-@font-face {
-  font-family: 'ConverseFontAwesome';
-  src: url("../fonts/fontawesome-webfont.eot?v=4.7.0");
-  src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0") format("embedded-opentype"), url("../fonts/fontawesome-webfont.woff2?v=4.7.0") format("woff2"), url("../fonts/fontawesome-webfont.woff?v=4.7.0") format("woff"), url("../fonts/fontawesome-webfont.ttf?v=4.7.0") format("truetype"), url("../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular") format("svg");
-  font-weight: normal;
-  font-style: normal; }
-.fa {
-  display: inline-block;
-  font: normal normal normal 14px/1 FontAwesome;
-  font-size: inherit;
-  text-rendering: auto;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale; }
-
-/* makes the font 33% larger relative to the icon container */
-.fa-lg {
-  font-size: 1.3333333333em;
-  line-height: 0.75em;
-  vertical-align: -15%; }
-
-.fa-2x {
-  font-size: 2em; }
-
-.fa-3x {
-  font-size: 3em; }
-
-.fa-4x {
-  font-size: 4em; }
-
-.fa-5x {
-  font-size: 5em; }
-
-.fa-fw {
-  width: 1.2857142857em;
-  text-align: center; }
-
-.fa-ul {
-  padding-left: 0;
-  margin-left: 2.1428571429em;
-  list-style-type: none; }
-  .fa-ul > li {
-    position: relative; }
-
-.fa-li {
-  position: absolute;
-  left: -2.1428571429em;
-  width: 2.1428571429em;
-  top: 0.1428571429em;
-  text-align: center; }
-  .fa-li.fa-lg {
-    left: -1.8571428571em; }
-
-.fa-border {
-  padding: .2em .25em .15em;
-  border: solid 0.08em #eee;
-  border-radius: .1em; }
-
-.fa-pull-left {
-  float: left; }
-
-.fa-pull-right {
-  float: right; }
-
-.fa.fa-pull-left {
-  margin-right: .3em; }
-.fa.fa-pull-right {
-  margin-left: .3em; }
-
-/* Deprecated as of 4.4.0 */
-.pull-right {
-  float: right; }
-
-.pull-left {
-  float: left; }
-
-.fa.pull-left {
-  margin-right: .3em; }
-.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% {
-    -webkit-transform: rotate(0deg);
-    transform: rotate(0deg); }
-  100% {
-    -webkit-transform: rotate(359deg);
-    transform: rotate(359deg); } }
-@keyframes fa-spin {
-  0% {
-    -webkit-transform: rotate(0deg);
-    transform: rotate(0deg); }
-  100% {
-    -webkit-transform: rotate(359deg);
-    transform: rotate(359deg); } }
-.fa-rotate-90 {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
-  -webkit-transform: rotate(90deg);
-  -ms-transform: rotate(90deg);
-  transform: rotate(90deg); }
-
-.fa-rotate-180 {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
-  -webkit-transform: rotate(180deg);
-  -ms-transform: rotate(180deg);
-  transform: rotate(180deg); }
-
-.fa-rotate-270 {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
-  -webkit-transform: rotate(270deg);
-  -ms-transform: rotate(270deg);
-  transform: rotate(270deg); }
-
-.fa-flip-horizontal {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
-  -webkit-transform: scale(-1, 1);
-  -ms-transform: scale(-1, 1);
-  transform: scale(-1, 1); }
-
-.fa-flip-vertical {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
-  -webkit-transform: scale(1, -1);
-  -ms-transform: scale(1, -1);
-  transform: scale(1, -1); }
-
-:root .fa-rotate-90,
-:root .fa-rotate-180,
-:root .fa-rotate-270,
-:root .fa-flip-horizontal,
-:root .fa-flip-vertical {
-  filter: none; }
-
-.fa-stack {
-  position: relative;
-  display: inline-block;
-  width: 2em;
-  height: 2em;
-  line-height: 2em;
-  vertical-align: middle; }
-
-.fa-stack-1x, .fa-stack-2x {
-  position: absolute;
-  left: 0;
-  width: 100%;
-  text-align: center; }
-
-.fa-stack-1x {
-  line-height: inherit; }
-
-.fa-stack-2x {
-  font-size: 2em; }
-
-.fa-inverse {
-  color: #fff; }
-
-/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
-   readers do not read off random characters that represent icons */
-.fa-glass:before {
-  content: ""; }
-
-.fa-music:before {
-  content: ""; }
-
-.fa-search:before {
-  content: ""; }
-
-.fa-envelope-o:before {
-  content: ""; }
-
-.fa-heart:before {
-  content: ""; }
-
-.fa-star:before {
-  content: ""; }
-
-.fa-star-o:before {
-  content: ""; }
-
-.fa-user:before {
-  content: ""; }
-
-.fa-film:before {
-  content: ""; }
-
-.fa-th-large:before {
-  content: ""; }
-
-.fa-th:before {
-  content: ""; }
-
-.fa-th-list:before {
-  content: ""; }
-
-.fa-check:before {
-  content: ""; }
-
-.fa-remove:before,
-.fa-close:before,
-.fa-times:before {
-  content: ""; }
-
-.fa-search-plus:before {
-  content: ""; }
-
-.fa-search-minus:before {
-  content: ""; }
-
-.fa-power-off:before {
-  content: ""; }
-
-.fa-signal:before {
-  content: ""; }
-
-.fa-gear:before,
-.fa-cog:before {
-  content: ""; }
-
-.fa-trash-o:before {
-  content: ""; }
-
-.fa-home:before {
-  content: ""; }
-
-.fa-file-o:before {
-  content: ""; }
-
-.fa-clock-o:before {
-  content: ""; }
-
-.fa-road:before {
-  content: ""; }
-
-.fa-download:before {
-  content: ""; }
-
-.fa-arrow-circle-o-down:before {
-  content: ""; }
-
-.fa-arrow-circle-o-up:before {
-  content: ""; }
-
-.fa-inbox:before {
-  content: ""; }
-
-.fa-play-circle-o:before {
-  content: ""; }
-
-.fa-rotate-right:before,
-.fa-repeat:before {
-  content: ""; }
-
-.fa-refresh:before {
-  content: ""; }
-
-.fa-list-alt:before {
-  content: ""; }
-
-.fa-lock:before {
-  content: ""; }
-
-.fa-flag:before {
-  content: ""; }
-
-.fa-headphones:before {
-  content: ""; }
-
-.fa-volume-off:before {
-  content: ""; }
-
-.fa-volume-down:before {
-  content: ""; }
-
-.fa-volume-up:before {
-  content: ""; }
-
-.fa-qrcode:before {
-  content: ""; }
-
-.fa-barcode:before {
-  content: ""; }
-
-.fa-tag:before {
-  content: ""; }
-
-.fa-tags:before {
-  content: ""; }
-
-.fa-book:before {
-  content: ""; }
-
-.fa-bookmark:before {
-  content: ""; }
-
-.fa-print:before {
-  content: ""; }
-
-.fa-camera:before {
-  content: ""; }
-
-.fa-font:before {
-  content: ""; }
-
-.fa-bold:before {
-  content: ""; }
-
-.fa-italic:before {
-  content: ""; }
-
-.fa-text-height:before {
-  content: ""; }
-
-.fa-text-width:before {
-  content: ""; }
-
-.fa-align-left:before {
-  content: ""; }
-
-.fa-align-center:before {
-  content: ""; }
-
-.fa-align-right:before {
-  content: ""; }
-
-.fa-align-justify:before {
-  content: ""; }
-
-.fa-list:before {
-  content: ""; }
-
-.fa-dedent:before,
-.fa-outdent:before {
-  content: ""; }
-
-.fa-indent:before {
-  content: ""; }
-
-.fa-video-camera:before {
-  content: ""; }
-
-.fa-photo:before,
-.fa-image:before,
-.fa-picture-o:before {
-  content: ""; }
-
-.fa-pencil:before {
-  content: ""; }
-
-.fa-map-marker:before {
-  content: ""; }
-
-.fa-adjust:before {
-  content: ""; }
-
-.fa-tint:before {
-  content: ""; }
-
-.fa-edit:before,
-.fa-pencil-square-o:before {
-  content: ""; }
-
-.fa-share-square-o:before {
-  content: ""; }
-
-.fa-check-square-o:before {
-  content: ""; }
-
-.fa-arrows:before {
-  content: ""; }
-
-.fa-step-backward:before {
-  content: ""; }
-
-.fa-fast-backward:before {
-  content: ""; }
-
-.fa-backward:before {
-  content: ""; }
-
-.fa-play:before {
-  content: ""; }
-
-.fa-pause:before {
-  content: ""; }
-
-.fa-stop:before {
-  content: ""; }
-
-.fa-forward:before {
-  content: ""; }
-
-.fa-fast-forward:before {
-  content: ""; }
-
-.fa-step-forward:before {
-  content: ""; }
-
-.fa-eject:before {
-  content: ""; }
-
-.fa-chevron-left:before {
-  content: ""; }
-
-.fa-chevron-right:before {
-  content: ""; }
-
-.fa-plus-circle:before {
-  content: ""; }
-
-.fa-minus-circle:before {
-  content: ""; }
-
-.fa-times-circle:before {
-  content: ""; }
-
-.fa-check-circle:before {
-  content: ""; }
-
-.fa-question-circle:before {
-  content: ""; }
-
-.fa-info-circle:before {
-  content: ""; }
-
-.fa-crosshairs:before {
-  content: ""; }
-
-.fa-times-circle-o:before {
-  content: ""; }
-
-.fa-check-circle-o:before {
-  content: ""; }
-
-.fa-ban:before {
-  content: ""; }
-
-.fa-arrow-left:before {
-  content: ""; }
-
-.fa-arrow-right:before {
-  content: ""; }
-
-.fa-arrow-up:before {
-  content: ""; }
-
-.fa-arrow-down:before {
-  content: ""; }
-
-.fa-mail-forward:before,
-.fa-share:before {
-  content: ""; }
-
-.fa-expand:before {
-  content: ""; }
-
-.fa-compress:before {
-  content: ""; }
-
-.fa-plus:before {
-  content: ""; }
-
-.fa-minus:before {
-  content: ""; }
-
-.fa-asterisk:before {
-  content: ""; }
-
-.fa-exclamation-circle:before {
-  content: ""; }
-
-.fa-gift:before {
-  content: ""; }
-
-.fa-leaf:before {
-  content: ""; }
-
-.fa-fire:before {
-  content: ""; }
-
-.fa-eye:before {
-  content: ""; }
-
-.fa-eye-slash:before {
-  content: ""; }
-
-.fa-warning:before,
-.fa-exclamation-triangle:before {
-  content: ""; }
-
-.fa-plane:before {
-  content: ""; }
-
-.fa-calendar:before {
-  content: ""; }
-
-.fa-random:before {
-  content: ""; }
-
-.fa-comment:before {
-  content: ""; }
-
-.fa-magnet:before {
-  content: ""; }
-
-.fa-chevron-up:before {
-  content: ""; }
-
-.fa-chevron-down:before {
-  content: ""; }
-
-.fa-retweet:before {
-  content: ""; }
-
-.fa-shopping-cart:before {
-  content: ""; }
-
-.fa-folder:before {
-  content: ""; }
-
-.fa-folder-open:before {
-  content: ""; }
-
-.fa-arrows-v:before {
-  content: ""; }
-
-.fa-arrows-h:before {
-  content: ""; }
-
-.fa-bar-chart-o:before,
-.fa-bar-chart:before {
-  content: ""; }
-
-.fa-twitter-square:before {
-  content: ""; }
-
-.fa-facebook-square:before {
-  content: ""; }
-
-.fa-camera-retro:before {
-  content: ""; }
-
-.fa-key:before {
-  content: ""; }
-
-.fa-gears:before,
-.fa-cogs:before {
-  content: ""; }
-
-.fa-comments:before {
-  content: ""; }
-
-.fa-thumbs-o-up:before {
-  content: ""; }
-
-.fa-thumbs-o-down:before {
-  content: ""; }
-
-.fa-star-half:before {
-  content: ""; }
-
-.fa-heart-o:before {
-  content: ""; }
-
-.fa-sign-out:before {
-  content: ""; }
-
-.fa-linkedin-square:before {
-  content: ""; }
-
-.fa-thumb-tack:before {
-  content: ""; }
-
-.fa-external-link:before {
-  content: ""; }
-
-.fa-sign-in:before {
-  content: ""; }
-
-.fa-trophy:before {
-  content: ""; }
-
-.fa-github-square:before {
-  content: ""; }
-
-.fa-upload:before {
-  content: ""; }
-
-.fa-lemon-o:before {
-  content: ""; }
-
-.fa-phone:before {
-  content: ""; }
-
-.fa-square-o:before {
-  content: ""; }
-
-.fa-bookmark-o:before {
-  content: ""; }
-
-.fa-phone-square:before {
-  content: ""; }
-
-.fa-twitter:before {
-  content: ""; }
-
-.fa-facebook-f:before,
-.fa-facebook:before {
-  content: ""; }
-
-.fa-github:before {
-  content: ""; }
-
-.fa-unlock:before {
-  content: ""; }
-
-.fa-credit-card:before {
-  content: ""; }
-
-.fa-feed:before,
-.fa-rss:before {
-  content: ""; }
-
-.fa-hdd-o:before {
-  content: ""; }
-
-.fa-bullhorn:before {
-  content: ""; }
-
-.fa-bell:before {
-  content: ""; }
-
-.fa-certificate:before {
-  content: ""; }
-
-.fa-hand-o-right:before {
-  content: ""; }
-
-.fa-hand-o-left:before {
-  content: ""; }
-
-.fa-hand-o-up:before {
-  content: ""; }
-
-.fa-hand-o-down:before {
-  content: ""; }
-
-.fa-arrow-circle-left:before {
-  content: ""; }
-
-.fa-arrow-circle-right:before {
-  content: ""; }
-
-.fa-arrow-circle-up:before {
-  content: ""; }
-
-.fa-arrow-circle-down:before {
-  content: ""; }
-
-.fa-globe:before {
-  content: ""; }
-
-.fa-wrench:before {
-  content: ""; }
-
-.fa-tasks:before {
-  content: ""; }
-
-.fa-filter:before {
-  content: ""; }
-
-.fa-briefcase:before {
-  content: ""; }
-
-.fa-arrows-alt:before {
-  content: ""; }
-
-.fa-group:before,
-.fa-users:before {
-  content: ""; }
-
-.fa-chain:before,
-.fa-link:before {
-  content: ""; }
-
-.fa-cloud:before {
-  content: ""; }
-
-.fa-flask:before {
-  content: ""; }
-
-.fa-cut:before,
-.fa-scissors:before {
-  content: ""; }
-
-.fa-copy:before,
-.fa-files-o:before {
-  content: ""; }
-
-.fa-paperclip:before {
-  content: ""; }
-
-.fa-save:before,
-.fa-floppy-o:before {
-  content: ""; }
-
-.fa-square:before {
-  content: ""; }
-
-.fa-navicon:before,
-.fa-reorder:before,
-.fa-bars:before {
-  content: ""; }
-
-.fa-list-ul:before {
-  content: ""; }
-
-.fa-list-ol:before {
-  content: ""; }
-
-.fa-strikethrough:before {
-  content: ""; }
-
-.fa-underline:before {
-  content: ""; }
-
-.fa-table:before {
-  content: ""; }
-
-.fa-magic:before {
-  content: ""; }
-
-.fa-truck:before {
-  content: ""; }
-
-.fa-pinterest:before {
-  content: ""; }
-
-.fa-pinterest-square:before {
-  content: ""; }
-
-.fa-google-plus-square:before {
-  content: ""; }
-
-.fa-google-plus:before {
-  content: ""; }
-
-.fa-money:before {
-  content: ""; }
-
-.fa-caret-down:before {
-  content: ""; }
-
-.fa-caret-up:before {
-  content: ""; }
-
-.fa-caret-left:before {
-  content: ""; }
-
-.fa-caret-right:before {
-  content: ""; }
-
-.fa-columns:before {
-  content: ""; }
-
-.fa-unsorted:before,
-.fa-sort:before {
-  content: ""; }
-
-.fa-sort-down:before,
-.fa-sort-desc:before {
-  content: ""; }
-
-.fa-sort-up:before,
-.fa-sort-asc:before {
-  content: ""; }
-
-.fa-envelope:before {
-  content: ""; }
-
-.fa-linkedin:before {
-  content: ""; }
-
-.fa-rotate-left:before,
-.fa-undo:before {
-  content: ""; }
-
-.fa-legal:before,
-.fa-gavel:before {
-  content: ""; }
-
-.fa-dashboard:before,
-.fa-tachometer:before {
-  content: ""; }
-
-.fa-comment-o:before {
-  content: ""; }
-
-.fa-comments-o:before {
-  content: ""; }
-
-.fa-flash:before,
-.fa-bolt:before {
-  content: ""; }
-
-.fa-sitemap:before {
-  content: ""; }
-
-.fa-umbrella:before {
-  content: ""; }
-
-.fa-paste:before,
-.fa-clipboard:before {
-  content: ""; }
-
-.fa-lightbulb-o:before {
-  content: ""; }
-
-.fa-exchange:before {
-  content: ""; }
-
-.fa-cloud-download:before {
-  content: ""; }
-
-.fa-cloud-upload:before {
-  content: ""; }
-
-.fa-user-md:before {
-  content: ""; }
-
-.fa-stethoscope:before {
-  content: ""; }
-
-.fa-suitcase:before {
-  content: ""; }
-
-.fa-bell-o:before {
-  content: ""; }
-
-.fa-coffee:before {
-  content: ""; }
-
-.fa-cutlery:before {
-  content: ""; }
-
-.fa-file-text-o:before {
-  content: ""; }
-
-.fa-building-o:before {
-  content: ""; }
-
-.fa-hospital-o:before {
-  content: ""; }
-
-.fa-ambulance:before {
-  content: ""; }
-
-.fa-medkit:before {
-  content: ""; }
-
-.fa-fighter-jet:before {
-  content: ""; }
-
-.fa-beer:before {
-  content: ""; }
-
-.fa-h-square:before {
-  content: ""; }
-
-.fa-plus-square:before {
-  content: ""; }
-
-.fa-angle-double-left:before {
-  content: ""; }
-
-.fa-angle-double-right:before {
-  content: ""; }
-
-.fa-angle-double-up:before {
-  content: ""; }
-
-.fa-angle-double-down:before {
-  content: ""; }
-
-.fa-angle-left:before {
-  content: ""; }
-
-.fa-angle-right:before {
-  content: ""; }
-
-.fa-angle-up:before {
-  content: ""; }
-
-.fa-angle-down:before {
-  content: ""; }
-
-.fa-desktop:before {
-  content: ""; }
-
-.fa-laptop:before {
-  content: ""; }
-
-.fa-tablet:before {
-  content: ""; }
-
-.fa-mobile-phone:before,
-.fa-mobile:before {
-  content: ""; }
-
-.fa-circle-o:before {
-  content: ""; }
-
-.fa-quote-left:before {
-  content: ""; }
-
-.fa-quote-right:before {
-  content: ""; }
-
-.fa-spinner:before {
-  content: ""; }
-
-.fa-circle:before {
-  content: ""; }
-
-.fa-mail-reply:before,
-.fa-reply:before {
-  content: ""; }
-
-.fa-github-alt:before {
-  content: ""; }
-
-.fa-folder-o:before {
-  content: ""; }
-
-.fa-folder-open-o:before {
-  content: ""; }
-
-.fa-smile-o:before {
-  content: ""; }
-
-.fa-frown-o:before {
-  content: ""; }
-
-.fa-meh-o:before {
-  content: ""; }
-
-.fa-gamepad:before {
-  content: ""; }
-
-.fa-keyboard-o:before {
-  content: ""; }
-
-.fa-flag-o:before {
-  content: ""; }
-
-.fa-flag-checkered:before {
-  content: ""; }
-
-.fa-terminal:before {
-  content: ""; }
-
-.fa-code:before {
-  content: ""; }
-
-.fa-mail-reply-all:before,
-.fa-reply-all:before {
-  content: ""; }
-
-.fa-star-half-empty:before,
-.fa-star-half-full:before,
-.fa-star-half-o:before {
-  content: ""; }
-
-.fa-location-arrow:before {
-  content: ""; }
-
-.fa-crop:before {
-  content: ""; }
-
-.fa-code-fork:before {
-  content: ""; }
-
-.fa-unlink:before,
-.fa-chain-broken:before {
-  content: ""; }
-
-.fa-question:before {
-  content: ""; }
-
-.fa-info:before {
-  content: ""; }
-
-.fa-exclamation:before {
-  content: ""; }
-
-.fa-superscript:before {
-  content: ""; }
-
-.fa-subscript:before {
-  content: ""; }
-
-.fa-eraser:before {
-  content: ""; }
-
-.fa-puzzle-piece:before {
-  content: ""; }
-
-.fa-microphone:before {
-  content: ""; }
-
-.fa-microphone-slash:before {
-  content: ""; }
-
-.fa-shield:before {
-  content: ""; }
-
-.fa-calendar-o:before {
-  content: ""; }
-
-.fa-fire-extinguisher:before {
-  content: ""; }
-
-.fa-rocket:before {
-  content: ""; }
-
-.fa-maxcdn:before {
-  content: ""; }
-
-.fa-chevron-circle-left:before {
-  content: ""; }
-
-.fa-chevron-circle-right:before {
-  content: ""; }
-
-.fa-chevron-circle-up:before {
-  content: ""; }
-
-.fa-chevron-circle-down:before {
-  content: ""; }
-
-.fa-html5:before {
-  content: ""; }
-
-.fa-css3:before {
-  content: ""; }
-
-.fa-anchor:before {
-  content: ""; }
-
-.fa-unlock-alt:before {
-  content: ""; }
-
-.fa-bullseye:before {
-  content: ""; }
-
-.fa-ellipsis-h:before {
-  content: ""; }
-
-.fa-ellipsis-v:before {
-  content: ""; }
-
-.fa-rss-square:before {
-  content: ""; }
-
-.fa-play-circle:before {
-  content: ""; }
-
-.fa-ticket:before {
-  content: ""; }
-
-.fa-minus-square:before {
-  content: ""; }
-
-.fa-minus-square-o:before {
-  content: ""; }
-
-.fa-level-up:before {
-  content: ""; }
-
-.fa-level-down:before {
-  content: ""; }
-
-.fa-check-square:before {
-  content: ""; }
-
-.fa-pencil-square:before {
-  content: ""; }
-
-.fa-external-link-square:before {
-  content: ""; }
-
-.fa-share-square:before {
-  content: ""; }
-
-.fa-compass:before {
-  content: ""; }
-
-.fa-toggle-down:before,
-.fa-caret-square-o-down:before {
-  content: ""; }
-
-.fa-toggle-up:before,
-.fa-caret-square-o-up:before {
-  content: ""; }
-
-.fa-toggle-right:before,
-.fa-caret-square-o-right:before {
-  content: ""; }
-
-.fa-euro:before,
-.fa-eur:before {
-  content: ""; }
-
-.fa-gbp:before {
-  content: ""; }
-
-.fa-dollar:before,
-.fa-usd:before {
-  content: ""; }
-
-.fa-rupee:before,
-.fa-inr:before {
-  content: ""; }
-
-.fa-cny:before,
-.fa-rmb:before,
-.fa-yen:before,
-.fa-jpy:before {
-  content: ""; }
-
-.fa-ruble:before,
-.fa-rouble:before,
-.fa-rub:before {
-  content: ""; }
-
-.fa-won:before,
-.fa-krw:before {
-  content: ""; }
-
-.fa-bitcoin:before,
-.fa-btc:before {
-  content: ""; }
-
-.fa-file:before {
-  content: ""; }
-
-.fa-file-text:before {
-  content: ""; }
-
-.fa-sort-alpha-asc:before {
-  content: ""; }
-
-.fa-sort-alpha-desc:before {
-  content: ""; }
-
-.fa-sort-amount-asc:before {
-  content: ""; }
-
-.fa-sort-amount-desc:before {
-  content: ""; }
-
-.fa-sort-numeric-asc:before {
-  content: ""; }
-
-.fa-sort-numeric-desc:before {
-  content: ""; }
-
-.fa-thumbs-up:before {
-  content: ""; }
-
-.fa-thumbs-down:before {
-  content: ""; }
-
-.fa-youtube-square:before {
-  content: ""; }
-
-.fa-youtube:before {
-  content: ""; }
-
-.fa-xing:before {
-  content: ""; }
-
-.fa-xing-square:before {
-  content: ""; }
-
-.fa-youtube-play:before {
-  content: ""; }
-
-.fa-dropbox:before {
-  content: ""; }
-
-.fa-stack-overflow:before {
-  content: ""; }
-
-.fa-instagram:before {
-  content: ""; }
-
-.fa-flickr:before {
-  content: ""; }
-
-.fa-adn:before {
-  content: ""; }
-
-.fa-bitbucket:before {
-  content: ""; }
-
-.fa-bitbucket-square:before {
-  content: ""; }
-
-.fa-tumblr:before {
-  content: ""; }
-
-.fa-tumblr-square:before {
-  content: ""; }
-
-.fa-long-arrow-down:before {
-  content: ""; }
-
-.fa-long-arrow-up:before {
-  content: ""; }
-
-.fa-long-arrow-left:before {
-  content: ""; }
-
-.fa-long-arrow-right:before {
-  content: ""; }
-
-.fa-apple:before {
-  content: ""; }
-
-.fa-windows:before {
-  content: ""; }
-
-.fa-android:before {
-  content: ""; }
-
-.fa-linux:before {
-  content: ""; }
-
-.fa-dribbble:before {
-  content: ""; }
-
-.fa-skype:before {
-  content: ""; }
-
-.fa-foursquare:before {
-  content: ""; }
-
-.fa-trello:before {
-  content: ""; }
-
-.fa-female:before {
-  content: ""; }
-
-.fa-male:before {
-  content: ""; }
-
-.fa-gittip:before,
-.fa-gratipay:before {
-  content: ""; }
-
-.fa-sun-o:before {
-  content: ""; }
-
-.fa-moon-o:before {
-  content: ""; }
-
-.fa-archive:before {
-  content: ""; }
-
-.fa-bug:before {
-  content: ""; }
-
-.fa-vk:before {
-  content: ""; }
-
-.fa-weibo:before {
-  content: ""; }
-
-.fa-renren:before {
-  content: ""; }
-
-.fa-pagelines:before {
-  content: ""; }
-
-.fa-stack-exchange:before {
-  content: ""; }
-
-.fa-arrow-circle-o-right:before {
-  content: ""; }
-
-.fa-arrow-circle-o-left:before {
-  content: ""; }
-
-.fa-toggle-left:before,
-.fa-caret-square-o-left:before {
-  content: ""; }
-
-.fa-dot-circle-o:before {
-  content: ""; }
-
-.fa-wheelchair:before {
-  content: ""; }
-
-.fa-vimeo-square:before {
-  content: ""; }
-
-.fa-turkish-lira:before,
-.fa-try:before {
-  content: ""; }
-
-.fa-plus-square-o:before {
-  content: ""; }
-
-.fa-space-shuttle:before {
-  content: ""; }
-
-.fa-slack:before {
-  content: ""; }
-
-.fa-envelope-square:before {
-  content: ""; }
-
-.fa-wordpress:before {
-  content: ""; }
-
-.fa-openid:before {
-  content: ""; }
-
-.fa-institution:before,
-.fa-bank:before,
-.fa-university:before {
-  content: ""; }
-
-.fa-mortar-board:before,
-.fa-graduation-cap:before {
-  content: ""; }
-
-.fa-yahoo:before {
-  content: ""; }
-
-.fa-google:before {
-  content: ""; }
-
-.fa-reddit:before {
-  content: ""; }
-
-.fa-reddit-square:before {
-  content: ""; }
-
-.fa-stumbleupon-circle:before {
-  content: ""; }
-
-.fa-stumbleupon:before {
-  content: ""; }
-
-.fa-delicious:before {
-  content: ""; }
-
-.fa-digg:before {
-  content: ""; }
-
-.fa-pied-piper-pp:before {
-  content: ""; }
-
-.fa-pied-piper-alt:before {
-  content: ""; }
-
-.fa-drupal:before {
-  content: ""; }
-
-.fa-joomla:before {
-  content: ""; }
-
-.fa-language:before {
-  content: ""; }
-
-.fa-fax:before {
-  content: ""; }
-
-.fa-building:before {
-  content: ""; }
-
-.fa-child:before {
-  content: ""; }
-
-.fa-paw:before {
-  content: ""; }
-
-.fa-spoon:before {
-  content: ""; }
-
-.fa-cube:before {
-  content: ""; }
-
-.fa-cubes:before {
-  content: ""; }
-
-.fa-behance:before {
-  content: ""; }
-
-.fa-behance-square:before {
-  content: ""; }
-
-.fa-steam:before {
-  content: ""; }
-
-.fa-steam-square:before {
-  content: ""; }
-
-.fa-recycle:before {
-  content: ""; }
-
-.fa-automobile:before,
-.fa-car:before {
-  content: ""; }
-
-.fa-cab:before,
-.fa-taxi:before {
-  content: ""; }
-
-.fa-tree:before {
-  content: ""; }
-
-.fa-spotify:before {
-  content: ""; }
-
-.fa-deviantart:before {
-  content: ""; }
-
-.fa-soundcloud:before {
-  content: ""; }
-
-.fa-database:before {
-  content: ""; }
-
-.fa-file-pdf-o:before {
-  content: ""; }
-
-.fa-file-word-o:before {
-  content: ""; }
-
-.fa-file-excel-o:before {
-  content: ""; }
-
-.fa-file-powerpoint-o:before {
-  content: ""; }
-
-.fa-file-photo-o:before,
-.fa-file-picture-o:before,
-.fa-file-image-o:before {
-  content: ""; }
-
-.fa-file-zip-o:before,
-.fa-file-archive-o:before {
-  content: ""; }
-
-.fa-file-sound-o:before,
-.fa-file-audio-o:before {
-  content: ""; }
-
-.fa-file-movie-o:before,
-.fa-file-video-o:before {
-  content: ""; }
-
-.fa-file-code-o:before {
-  content: ""; }
-
-.fa-vine:before {
-  content: ""; }
-
-.fa-codepen:before {
-  content: ""; }
-
-.fa-jsfiddle:before {
-  content: ""; }
-
-.fa-life-bouy:before,
-.fa-life-buoy:before,
-.fa-life-saver:before,
-.fa-support:before,
-.fa-life-ring:before {
-  content: ""; }
-
-.fa-circle-o-notch:before {
-  content: ""; }
-
-.fa-ra:before,
-.fa-resistance:before,
-.fa-rebel:before {
-  content: ""; }
-
-.fa-ge:before,
-.fa-empire:before {
-  content: ""; }
-
-.fa-git-square:before {
-  content: ""; }
-
-.fa-git:before {
-  content: ""; }
-
-.fa-y-combinator-square:before,
-.fa-yc-square:before,
-.fa-hacker-news:before {
-  content: ""; }
-
-.fa-tencent-weibo:before {
-  content: ""; }
-
-.fa-qq:before {
-  content: ""; }
-
-.fa-wechat:before,
-.fa-weixin:before {
-  content: ""; }
-
-.fa-send:before,
-.fa-paper-plane:before {
-  content: ""; }
-
-.fa-send-o:before,
-.fa-paper-plane-o:before {
-  content: ""; }
-
-.fa-history:before {
-  content: ""; }
-
-.fa-circle-thin:before {
-  content: ""; }
-
-.fa-header:before {
-  content: ""; }
-
-.fa-paragraph:before {
-  content: ""; }
-
-.fa-sliders:before {
-  content: ""; }
-
-.fa-share-alt:before {
-  content: ""; }
-
-.fa-share-alt-square:before {
-  content: ""; }
-
-.fa-bomb:before {
-  content: ""; }
-
-.fa-soccer-ball-o:before,
-.fa-futbol-o:before {
-  content: ""; }
-
-.fa-tty:before {
-  content: ""; }
-
-.fa-binoculars:before {
-  content: ""; }
-
-.fa-plug:before {
-  content: ""; }
-
-.fa-slideshare:before {
-  content: ""; }
-
-.fa-twitch:before {
-  content: ""; }
-
-.fa-yelp:before {
-  content: ""; }
-
-.fa-newspaper-o:before {
-  content: ""; }
-
-.fa-wifi:before {
-  content: ""; }
-
-.fa-calculator:before {
-  content: ""; }
-
-.fa-paypal:before {
-  content: ""; }
-
-.fa-google-wallet:before {
-  content: ""; }
-
-.fa-cc-visa:before {
-  content: ""; }
-
-.fa-cc-mastercard:before {
-  content: ""; }
-
-.fa-cc-discover:before {
-  content: ""; }
-
-.fa-cc-amex:before {
-  content: ""; }
-
-.fa-cc-paypal:before {
-  content: ""; }
-
-.fa-cc-stripe:before {
-  content: ""; }
-
-.fa-bell-slash:before {
-  content: ""; }
-
-.fa-bell-slash-o:before {
-  content: ""; }
-
-.fa-trash:before {
-  content: ""; }
-
-.fa-copyright:before {
-  content: ""; }
-
-.fa-at:before {
-  content: ""; }
-
-.fa-eyedropper:before {
-  content: ""; }
-
-.fa-paint-brush:before {
-  content: ""; }
-
-.fa-birthday-cake:before {
-  content: ""; }
-
-.fa-area-chart:before {
-  content: ""; }
-
-.fa-pie-chart:before {
-  content: ""; }
-
-.fa-line-chart:before {
-  content: ""; }
-
-.fa-lastfm:before {
-  content: ""; }
-
-.fa-lastfm-square:before {
-  content: ""; }
-
-.fa-toggle-off:before {
-  content: ""; }
-
-.fa-toggle-on:before {
-  content: ""; }
-
-.fa-bicycle:before {
-  content: ""; }
-
-.fa-bus:before {
-  content: ""; }
-
-.fa-ioxhost:before {
-  content: ""; }
-
-.fa-angellist:before {
-  content: ""; }
-
-.fa-cc:before {
-  content: ""; }
-
-.fa-shekel:before,
-.fa-sheqel:before,
-.fa-ils:before {
-  content: ""; }
-
-.fa-meanpath:before {
-  content: ""; }
-
-.fa-buysellads:before {
-  content: ""; }
-
-.fa-connectdevelop:before {
-  content: ""; }
-
-.fa-dashcube:before {
-  content: ""; }
-
-.fa-forumbee:before {
-  content: ""; }
-
-.fa-leanpub:before {
-  content: ""; }
-
-.fa-sellsy:before {
-  content: ""; }
-
-.fa-shirtsinbulk:before {
-  content: ""; }
-
-.fa-simplybuilt:before {
-  content: ""; }
-
-.fa-skyatlas:before {
-  content: ""; }
-
-.fa-cart-plus:before {
-  content: ""; }
-
-.fa-cart-arrow-down:before {
-  content: ""; }
-
-.fa-diamond:before {
-  content: ""; }
-
-.fa-ship:before {
-  content: ""; }
-
-.fa-user-secret:before {
-  content: ""; }
-
-.fa-motorcycle:before {
-  content: ""; }
-
-.fa-street-view:before {
-  content: ""; }
-
-.fa-heartbeat:before {
-  content: ""; }
-
-.fa-venus:before {
-  content: ""; }
-
-.fa-mars:before {
-  content: ""; }
-
-.fa-mercury:before {
-  content: ""; }
-
-.fa-intersex:before,
-.fa-transgender:before {
-  content: ""; }
-
-.fa-transgender-alt:before {
-  content: ""; }
-
-.fa-venus-double:before {
-  content: ""; }
-
-.fa-mars-double:before {
-  content: ""; }
-
-.fa-venus-mars:before {
-  content: ""; }
-
-.fa-mars-stroke:before {
-  content: ""; }
-
-.fa-mars-stroke-v:before {
-  content: ""; }
-
-.fa-mars-stroke-h:before {
-  content: ""; }
-
-.fa-neuter:before {
-  content: ""; }
-
-.fa-genderless:before {
-  content: ""; }
-
-.fa-facebook-official:before {
-  content: ""; }
-
-.fa-pinterest-p:before {
-  content: ""; }
-
-.fa-whatsapp:before {
-  content: ""; }
-
-.fa-server:before {
-  content: ""; }
-
-.fa-user-plus:before {
-  content: ""; }
-
-.fa-user-times:before {
-  content: ""; }
-
-.fa-hotel:before,
-.fa-bed:before {
-  content: ""; }
-
-.fa-viacoin:before {
-  content: ""; }
-
-.fa-train:before {
-  content: ""; }
-
-.fa-subway:before {
-  content: ""; }
-
-.fa-medium:before {
-  content: ""; }
-
-.fa-yc:before,
-.fa-y-combinator:before {
-  content: ""; }
-
-.fa-optin-monster:before {
-  content: ""; }
-
-.fa-opencart:before {
-  content: ""; }
-
-.fa-expeditedssl:before {
-  content: ""; }
-
-.fa-battery-4:before,
-.fa-battery:before,
-.fa-battery-full:before {
-  content: ""; }
-
-.fa-battery-3:before,
-.fa-battery-three-quarters:before {
-  content: ""; }
-
-.fa-battery-2:before,
-.fa-battery-half:before {
-  content: ""; }
-
-.fa-battery-1:before,
-.fa-battery-quarter:before {
-  content: ""; }
-
-.fa-battery-0:before,
-.fa-battery-empty:before {
-  content: ""; }
-
-.fa-mouse-pointer:before {
-  content: ""; }
-
-.fa-i-cursor:before {
-  content: ""; }
-
-.fa-object-group:before {
-  content: ""; }
-
-.fa-object-ungroup:before {
-  content: ""; }
-
-.fa-sticky-note:before {
-  content: ""; }
-
-.fa-sticky-note-o:before {
-  content: ""; }
-
-.fa-cc-jcb:before {
-  content: ""; }
-
-.fa-cc-diners-club:before {
-  content: ""; }
-
-.fa-clone:before {
-  content: ""; }
-
-.fa-balance-scale:before {
-  content: ""; }
-
-.fa-hourglass-o:before {
-  content: ""; }
-
-.fa-hourglass-1:before,
-.fa-hourglass-start:before {
-  content: ""; }
-
-.fa-hourglass-2:before,
-.fa-hourglass-half:before {
-  content: ""; }
-
-.fa-hourglass-3:before,
-.fa-hourglass-end:before {
-  content: ""; }
-
-.fa-hourglass:before {
-  content: ""; }
-
-.fa-hand-grab-o:before,
-.fa-hand-rock-o:before {
-  content: ""; }
-
-.fa-hand-stop-o:before,
-.fa-hand-paper-o:before {
-  content: ""; }
-
-.fa-hand-scissors-o:before {
-  content: ""; }
-
-.fa-hand-lizard-o:before {
-  content: ""; }
-
-.fa-hand-spock-o:before {
-  content: ""; }
-
-.fa-hand-pointer-o:before {
-  content: ""; }
-
-.fa-hand-peace-o:before {
-  content: ""; }
-
-.fa-trademark:before {
-  content: ""; }
-
-.fa-registered:before {
-  content: ""; }
-
-.fa-creative-commons:before {
-  content: ""; }
-
-.fa-gg:before {
-  content: ""; }
-
-.fa-gg-circle:before {
-  content: ""; }
-
-.fa-tripadvisor:before {
-  content: ""; }
-
-.fa-odnoklassniki:before {
-  content: ""; }
-
-.fa-odnoklassniki-square:before {
-  content: ""; }
-
-.fa-get-pocket:before {
-  content: ""; }
-
-.fa-wikipedia-w:before {
-  content: ""; }
-
-.fa-safari:before {
-  content: ""; }
-
-.fa-chrome:before {
-  content: ""; }
-
-.fa-firefox:before {
-  content: ""; }
-
-.fa-opera:before {
-  content: ""; }
-
-.fa-internet-explorer:before {
-  content: ""; }
-
-.fa-tv:before,
-.fa-television:before {
-  content: ""; }
-
-.fa-contao:before {
-  content: ""; }
-
-.fa-500px:before {
-  content: ""; }
-
-.fa-amazon:before {
-  content: ""; }
-
-.fa-calendar-plus-o:before {
-  content: ""; }
-
-.fa-calendar-minus-o:before {
-  content: ""; }
-
-.fa-calendar-times-o:before {
-  content: ""; }
-
-.fa-calendar-check-o:before {
-  content: ""; }
-
-.fa-industry:before {
-  content: ""; }
-
-.fa-map-pin:before {
-  content: ""; }
-
-.fa-map-signs:before {
-  content: ""; }
-
-.fa-map-o:before {
-  content: ""; }
-
-.fa-map:before {
-  content: ""; }
-
-.fa-commenting:before {
-  content: ""; }
-
-.fa-commenting-o:before {
-  content: ""; }
-
-.fa-houzz:before {
-  content: ""; }
-
-.fa-vimeo:before {
-  content: ""; }
-
-.fa-black-tie:before {
-  content: ""; }
-
-.fa-fonticons:before {
-  content: ""; }
-
-.fa-reddit-alien:before {
-  content: ""; }
-
-.fa-edge:before {
-  content: ""; }
-
-.fa-credit-card-alt:before {
-  content: ""; }
-
-.fa-codiepie:before {
-  content: ""; }
-
-.fa-modx:before {
-  content: ""; }
-
-.fa-fort-awesome:before {
-  content: ""; }
-
-.fa-usb:before {
-  content: ""; }
-
-.fa-product-hunt:before {
-  content: ""; }
-
-.fa-mixcloud:before {
-  content: ""; }
-
-.fa-scribd:before {
-  content: ""; }
-
-.fa-pause-circle:before {
-  content: ""; }
-
-.fa-pause-circle-o:before {
-  content: ""; }
-
-.fa-stop-circle:before {
-  content: ""; }
-
-.fa-stop-circle-o:before {
-  content: ""; }
-
-.fa-shopping-bag:before {
-  content: ""; }
-
-.fa-shopping-basket:before {
-  content: ""; }
-
-.fa-hashtag:before {
-  content: ""; }
-
-.fa-bluetooth:before {
-  content: ""; }
-
-.fa-bluetooth-b:before {
-  content: ""; }
-
-.fa-percent:before {
-  content: ""; }
-
-.fa-gitlab:before {
-  content: ""; }
-
-.fa-wpbeginner:before {
-  content: ""; }
-
-.fa-wpforms:before {
-  content: ""; }
-
-.fa-envira:before {
-  content: ""; }
-
-.fa-universal-access:before {
-  content: ""; }
-
-.fa-wheelchair-alt:before {
-  content: ""; }
-
-.fa-question-circle-o:before {
-  content: ""; }
-
-.fa-blind:before {
-  content: ""; }
-
-.fa-audio-description:before {
-  content: ""; }
-
-.fa-volume-control-phone:before {
-  content: ""; }
-
-.fa-braille:before {
-  content: ""; }
-
-.fa-assistive-listening-systems:before {
-  content: ""; }
-
-.fa-asl-interpreting:before,
-.fa-american-sign-language-interpreting:before {
-  content: ""; }
-
-.fa-deafness:before,
-.fa-hard-of-hearing:before,
-.fa-deaf:before {
-  content: ""; }
-
-.fa-glide:before {
-  content: ""; }
-
-.fa-glide-g:before {
-  content: ""; }
-
-.fa-signing:before,
-.fa-sign-language:before {
-  content: ""; }
-
-.fa-low-vision:before {
-  content: ""; }
-
-.fa-viadeo:before {
-  content: ""; }
-
-.fa-viadeo-square:before {
-  content: ""; }
-
-.fa-snapchat:before {
-  content: ""; }
-
-.fa-snapchat-ghost:before {
-  content: ""; }
-
-.fa-snapchat-square:before {
-  content: ""; }
-
-.fa-pied-piper:before {
-  content: ""; }
-
-.fa-first-order:before {
-  content: ""; }
-
-.fa-yoast:before {
-  content: ""; }
-
-.fa-themeisle:before {
-  content: ""; }
-
-.fa-google-plus-circle:before,
-.fa-google-plus-official:before {
-  content: ""; }
-
-.fa-fa:before,
-.fa-font-awesome:before {
-  content: ""; }
-
-.fa-handshake-o:before {
-  content: ""; }
-
-.fa-envelope-open:before {
-  content: ""; }
-
-.fa-envelope-open-o:before {
-  content: ""; }
-
-.fa-linode:before {
-  content: ""; }
-
-.fa-address-book:before {
-  content: ""; }
-
-.fa-address-book-o:before {
-  content: ""; }
-
-.fa-vcard:before,
-.fa-address-card:before {
-  content: ""; }
-
-.fa-vcard-o:before,
-.fa-address-card-o:before {
-  content: ""; }
-
-.fa-user-circle:before {
-  content: ""; }
-
-.fa-user-circle-o:before {
-  content: ""; }
-
-.fa-user-o:before {
-  content: ""; }
-
-.fa-id-badge:before {
-  content: ""; }
-
-.fa-drivers-license:before,
-.fa-id-card:before {
-  content: ""; }
-
-.fa-drivers-license-o:before,
-.fa-id-card-o:before {
-  content: ""; }
-
-.fa-quora:before {
-  content: ""; }
-
-.fa-free-code-camp:before {
-  content: ""; }
-
-.fa-telegram:before {
-  content: ""; }
-
-.fa-thermometer-4:before,
-.fa-thermometer:before,
-.fa-thermometer-full:before {
-  content: ""; }
-
-.fa-thermometer-3:before,
-.fa-thermometer-three-quarters:before {
-  content: ""; }
-
-.fa-thermometer-2:before,
-.fa-thermometer-half:before {
-  content: ""; }
-
-.fa-thermometer-1:before,
-.fa-thermometer-quarter:before {
-  content: ""; }
-
-.fa-thermometer-0:before,
-.fa-thermometer-empty:before {
-  content: ""; }
-
-.fa-shower:before {
-  content: ""; }
-
-.fa-bathtub:before,
-.fa-s15:before,
-.fa-bath:before {
-  content: ""; }
-
-.fa-podcast:before {
-  content: ""; }
-
-.fa-window-maximize:before {
-  content: ""; }
-
-.fa-window-minimize:before {
-  content: ""; }
-
-.fa-window-restore:before {
-  content: ""; }
-
-.fa-times-rectangle:before,
-.fa-window-close:before {
-  content: ""; }
-
-.fa-times-rectangle-o:before,
-.fa-window-close-o:before {
-  content: ""; }
-
-.fa-bandcamp:before {
-  content: ""; }
-
-.fa-grav:before {
-  content: ""; }
-
-.fa-etsy:before {
-  content: ""; }
-
-.fa-imdb:before {
-  content: ""; }
-
-.fa-ravelry:before {
-  content: ""; }
-
-.fa-eercast:before {
-  content: ""; }
-
-.fa-microchip:before {
-  content: ""; }
-
-.fa-snowflake-o:before {
-  content: ""; }
-
-.fa-superpowers:before {
-  content: ""; }
-
-.fa-wpexplorer:before {
-  content: ""; }
-
-.fa-meetup:before {
-  content: ""; }
-
-.sr-only {
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  margin: -1px;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  border: 0; }
-
-.sr-only-focusable:active, .sr-only-focusable:focus {
-  position: static;
-  width: auto;
-  height: auto;
-  margin: 0;
-  overflow: visible;
-  clip: auto; }
-
-/*
-    Color scheme helpers:
-    https://coolors.co/app/264653-2a9d8f-e9c46a-f4a261-e76f51
-    http://paletton.com/#uid=70a0u0kkNs+b4JOgryLpxqpsbkI
- */
-#conversejs :root {
-  --blue: #387592;
-  --indigo: #6610f2;
-  --purple: #6f42c1;
-  --pink: #e83e8c;
-  --red: #E77051;
-  --orange: #E7A151;
-  --yellow: #ffc107;
-  --green: #3AA569;
-  --teal: #20c997;
-  --cyan: #17a2b8;
-  --white: #fff;
-  --gray: #6c757d;
-  --gray-dark: #343a40;
-  --primary: #387592;
-  --secondary: #6c757d;
-  --success: #3AA569;
-  --info: #17a2b8;
-  --warning: #ffc107;
-  --danger: #E77051;
-  --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, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
-#conversejs *,
-#conversejs *::before,
-#conversejs *::after {
-  box-sizing: border-box; }
-#conversejs html {
-  font-family: sans-serif;
-  line-height: 1.15;
-  -webkit-text-size-adjust: 100%;
-  -ms-text-size-adjust: 100%;
-  -ms-overflow-style: scrollbar;
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
-@-ms-viewport {
-  width: device-width; }
-#conversejs article, #conversejs aside, #conversejs dialog, #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, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  font-size: 1rem;
-  font-weight: 400;
-  line-height: 1.5;
-  color: #212529;
-  text-align: left;
-  background-color: #fff; }
-#conversejs [tabindex="-1"]:focus {
-  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: 0.5rem; }
-#conversejs p {
-  margin-top: 0;
-  margin-bottom: 1rem; }
-#conversejs abbr[title],
-#conversejs abbr[data-original-title] {
-  text-decoration: underline;
-  text-decoration: underline dotted;
-  cursor: help;
-  border-bottom: 0; }
-#conversejs address {
-  margin-bottom: 1rem;
-  font-style: normal;
-  line-height: inherit; }
-#conversejs ol,
-#conversejs ul,
-#conversejs dl {
-  margin-top: 0;
-  margin-bottom: 1rem; }
-#conversejs ol ol,
-#conversejs ul ul,
-#conversejs ol ul,
-#conversejs ul ol {
-  margin-bottom: 0; }
-#conversejs dt {
-  font-weight: 700; }
-#conversejs dd {
-  margin-bottom: .5rem;
-  margin-left: 0; }
-#conversejs blockquote {
-  margin: 0 0 1rem; }
-#conversejs dfn {
-  font-style: italic; }
-#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: #578EA9;
-  text-decoration: none;
-  background-color: transparent;
-  -webkit-text-decoration-skip: objects; }
-  #conversejs a:hover {
-    color: #3d6477;
-    text-decoration: underline; }
-#conversejs a:not([href]):not([tabindex]) {
-  color: inherit;
-  text-decoration: none; }
-  #conversejs a:not([href]):not([tabindex]):hover, #conversejs a:not([href]):not([tabindex]):focus {
-    color: inherit;
-    text-decoration: none; }
-  #conversejs a:not([href]):not([tabindex]):focus {
-    outline: 0; }
-#conversejs pre,
-#conversejs code,
-#conversejs kbd,
-#conversejs samp {
-  font-family: monospace, monospace;
-  font-size: 1em; }
-#conversejs pre {
-  margin-top: 0;
-  margin-bottom: 1rem;
-  overflow: auto;
-  -ms-overflow-style: scrollbar; }
-#conversejs figure {
-  margin: 0 0 1rem; }
-#conversejs img {
-  vertical-align: middle;
-  border-style: none; }
-#conversejs svg:not(:root) {
-  overflow: hidden; }
-#conversejs table {
-  border-collapse: collapse; }
-#conversejs caption {
-  padding-top: 0.75rem;
-  padding-bottom: 0.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 input,
-#conversejs button,
-#conversejs select,
-#conversejs optgroup,
-#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 button,
-#conversejs html [type="button"],
-#conversejs [type="reset"],
-#conversejs [type="submit"] {
-  -webkit-appearance: button; }
-#conversejs button::-moz-focus-inner,
-#conversejs [type="button"]::-moz-focus-inner,
-#conversejs [type="reset"]::-moz-focus-inner,
-#conversejs [type="submit"]::-moz-focus-inner {
-  padding: 0;
-  border-style: none; }
-#conversejs input[type="radio"],
-#conversejs input[type="checkbox"] {
-  box-sizing: border-box;
-  padding: 0; }
-#conversejs input[type="date"],
-#conversejs input[type="time"],
-#conversejs input[type="datetime-local"],
-#conversejs input[type="month"] {
-  -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-cancel-button,
-#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: 0.5rem;
-  font-family: inherit;
-  font-weight: 500;
-  line-height: 1.2;
-  color: inherit; }
-#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, 0.1); }
-#conversejs small,
-#conversejs .small {
-  font-size: 80%;
-  font-weight: 400; }
-#conversejs mark,
-#conversejs .mark {
-  padding: 0.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: 0.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: 0.25rem;
-  background-color: #fff;
-  border: 1px solid #dee2e6;
-  border-radius: 0.25rem;
-  max-width: 100%;
-  height: auto; }
-#conversejs .figure {
-  display: inline-block; }
-#conversejs .figure-img {
-  margin-bottom: 0.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 {
-  width: 100%;
-  padding-right: 15px;
-  padding-left: 15px;
-  margin-right: auto;
-  margin-left: auto; }
-#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-1, #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-10, #conversejs .col-11, #conversejs .col-12, #conversejs .col,
-#conversejs .col-auto, #conversejs .col-sm-1, #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-10, #conversejs .col-sm-11, #conversejs .col-sm-12, #conversejs .col-sm,
-#conversejs .col-sm-auto, #conversejs .col-md-1, #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-10, #conversejs .col-md-11, #conversejs .col-md-12, #conversejs .col-md,
-#conversejs .col-md-auto, #conversejs .col-lg-1, #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-10, #conversejs .col-lg-11, #conversejs .col-lg-12, #conversejs .col-lg,
-#conversejs .col-lg-auto, #conversejs .col-xl-1, #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-10, #conversejs .col-xl-11, #conversejs .col-xl-12, #conversejs .col-xl,
-#conversejs .col-xl-auto {
-  position: relative;
-  width: 100%;
-  min-height: 1px;
-  padding-right: 15px;
-  padding-left: 15px; }
-#conversejs .col {
-  flex-basis: 0;
-  flex-grow: 1;
-  max-width: 100%; }
-#conversejs .col-auto {
-  flex: 0 0 auto;
-  width: auto;
-  max-width: none; }
-#conversejs .col-1 {
-  flex: 0 0 8.3333333333%;
-  max-width: 8.3333333333%; }
-#conversejs .col-2 {
-  flex: 0 0 16.6666666667%;
-  max-width: 16.6666666667%; }
-#conversejs .col-3 {
-  flex: 0 0 25%;
-  max-width: 25%; }
-#conversejs .col-4 {
-  flex: 0 0 33.3333333333%;
-  max-width: 33.3333333333%; }
-#conversejs .col-5 {
-  flex: 0 0 41.6666666667%;
-  max-width: 41.6666666667%; }
-#conversejs .col-6 {
-  flex: 0 0 50%;
-  max-width: 50%; }
-#conversejs .col-7 {
-  flex: 0 0 58.3333333333%;
-  max-width: 58.3333333333%; }
-#conversejs .col-8 {
-  flex: 0 0 66.6666666667%;
-  max-width: 66.6666666667%; }
-#conversejs .col-9 {
-  flex: 0 0 75%;
-  max-width: 75%; }
-#conversejs .col-10 {
-  flex: 0 0 83.3333333333%;
-  max-width: 83.3333333333%; }
-#conversejs .col-11 {
-  flex: 0 0 91.6666666667%;
-  max-width: 91.6666666667%; }
-#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.3333333333%; }
-#conversejs .offset-2 {
-  margin-left: 16.6666666667%; }
-#conversejs .offset-3 {
-  margin-left: 25%; }
-#conversejs .offset-4 {
-  margin-left: 33.3333333333%; }
-#conversejs .offset-5 {
-  margin-left: 41.6666666667%; }
-#conversejs .offset-6 {
-  margin-left: 50%; }
-#conversejs .offset-7 {
-  margin-left: 58.3333333333%; }
-#conversejs .offset-8 {
-  margin-left: 66.6666666667%; }
-#conversejs .offset-9 {
-  margin-left: 75%; }
-#conversejs .offset-10 {
-  margin-left: 83.3333333333%; }
-#conversejs .offset-11 {
-  margin-left: 91.6666666667%; }
-@media (min-width: 576px) {
-  #conversejs .col-sm {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-sm-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-sm-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-sm-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-sm-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-sm-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-sm-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-sm-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-sm-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-sm-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-sm-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-sm-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-sm-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #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.3333333333%; }
-  #conversejs .offset-sm-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-sm-3 {
-    margin-left: 25%; }
-  #conversejs .offset-sm-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-sm-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-sm-6 {
-    margin-left: 50%; }
-  #conversejs .offset-sm-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-sm-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-sm-9 {
-    margin-left: 75%; }
-  #conversejs .offset-sm-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-sm-11 {
-    margin-left: 91.6666666667%; } }
-@media (min-width: 768px) {
-  #conversejs .col-md {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-md-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-md-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-md-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-md-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-md-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-md-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-md-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-md-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-md-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-md-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-md-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-md-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #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.3333333333%; }
-  #conversejs .offset-md-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-md-3 {
-    margin-left: 25%; }
-  #conversejs .offset-md-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-md-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-md-6 {
-    margin-left: 50%; }
-  #conversejs .offset-md-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-md-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-md-9 {
-    margin-left: 75%; }
-  #conversejs .offset-md-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-md-11 {
-    margin-left: 91.6666666667%; } }
-@media (min-width: 992px) {
-  #conversejs .col-lg {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-lg-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-lg-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-lg-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-lg-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-lg-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-lg-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-lg-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-lg-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-lg-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-lg-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-lg-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-lg-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #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.3333333333%; }
-  #conversejs .offset-lg-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-lg-3 {
-    margin-left: 25%; }
-  #conversejs .offset-lg-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-lg-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-lg-6 {
-    margin-left: 50%; }
-  #conversejs .offset-lg-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-lg-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-lg-9 {
-    margin-left: 75%; }
-  #conversejs .offset-lg-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-lg-11 {
-    margin-left: 91.6666666667%; } }
-@media (min-width: 1200px) {
-  #conversejs .col-xl {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-xl-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-xl-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-xl-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-xl-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-xl-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-xl-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-xl-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-xl-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-xl-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-xl-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-xl-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-xl-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #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.3333333333%; }
-  #conversejs .offset-xl-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-xl-3 {
-    margin-left: 25%; }
-  #conversejs .offset-xl-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-xl-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-xl-6 {
-    margin-left: 50%; }
-  #conversejs .offset-xl-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-xl-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-xl-9 {
-    margin-left: 75%; }
-  #conversejs .offset-xl-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-xl-11 {
-    margin-left: 91.6666666667%; } }
-#conversejs .form-control {
-  display: block;
-  width: 100%;
-  padding: 0.375rem 0.75rem;
-  font-size: 1rem;
-  line-height: 1.5;
-  color: #495057;
-  background-color: #fff;
-  background-clip: padding-box;
-  border: 1px solid #ced4da;
-  border-radius: 0.25rem;
-  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; }
-  #conversejs .form-control::-ms-expand {
-    background-color: transparent;
-    border: 0; }
-  #conversejs .form-control:focus {
-    color: #1A9707;
-    background-color: #fff;
-    border-color: #7db3cd;
-    outline: 0;
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-  #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:not([size]):not([multiple]) {
-  height: calc(2.25rem + 2px); }
-#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(0.375rem + 1px);
-  padding-bottom: calc(0.375rem + 1px);
-  margin-bottom: 0;
-  font-size: inherit;
-  line-height: 1.5; }
-#conversejs .col-form-label-lg {
-  padding-top: calc(0.5rem + 1px);
-  padding-bottom: calc(0.5rem + 1px);
-  font-size: 1.25rem;
-  line-height: 1.5; }
-#conversejs .col-form-label-sm {
-  padding-top: calc(0.25rem + 1px);
-  padding-bottom: calc(0.25rem + 1px);
-  font-size: 0.875rem;
-  line-height: 1.5; }
-#conversejs .form-control-plaintext {
-  display: block;
-  width: 100%;
-  padding-top: 0.375rem;
-  padding-bottom: 0.375rem;
-  margin-bottom: 0;
-  line-height: 1.5;
-  background-color: transparent;
-  border: solid transparent;
-  border-width: 1px 0; }
-  #conversejs .form-control-plaintext.form-control-sm, #conversejs .input-group-sm > .form-control-plaintext.form-control,
-  #conversejs .input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-sm > .input-group-append > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-sm > .input-group-prepend > .form-control-plaintext.btn,
-  #conversejs .input-group-sm > .input-group-append > .form-control-plaintext.btn, #conversejs .form-control-plaintext.form-control-lg, #conversejs .input-group-lg > .form-control-plaintext.form-control,
-  #conversejs .input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-lg > .input-group-append > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-lg > .input-group-prepend > .form-control-plaintext.btn,
-  #conversejs .input-group-lg > .input-group-append > .form-control-plaintext.btn {
-    padding-right: 0;
-    padding-left: 0; }
-#conversejs .form-control-sm, #conversejs .input-group-sm > .form-control,
-#conversejs .input-group-sm > .input-group-prepend > .input-group-text,
-#conversejs .input-group-sm > .input-group-append > .input-group-text,
-#conversejs .input-group-sm > .input-group-prepend > .btn,
-#conversejs .input-group-sm > .input-group-append > .btn {
-  padding: 0.25rem 0.5rem;
-  font-size: 0.875rem;
-  line-height: 1.5;
-  border-radius: 0.2rem; }
-#conversejs select.form-control-sm:not([size]):not([multiple]), #conversejs .input-group-sm > select.form-control:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) {
-  height: calc(1.8125rem + 2px); }
-#conversejs .form-control-lg, #conversejs .input-group-lg > .form-control,
-#conversejs .input-group-lg > .input-group-prepend > .input-group-text,
-#conversejs .input-group-lg > .input-group-append > .input-group-text,
-#conversejs .input-group-lg > .input-group-prepend > .btn,
-#conversejs .input-group-lg > .input-group-append > .btn {
-  padding: 0.5rem 1rem;
-  font-size: 1.25rem;
-  line-height: 1.5;
-  border-radius: 0.3rem; }
-#conversejs select.form-control-lg:not([size]):not([multiple]), #conversejs .input-group-lg > select.form-control:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) {
-  height: calc(2.875rem + 2px); }
-#conversejs .form-group {
-  margin-bottom: 1rem; }
-#conversejs .form-text {
-  display: block;
-  margin-top: 0.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: 0.3rem;
-  margin-left: -1.25rem; }
-  #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: 0.75rem; }
-  #conversejs .form-check-inline .form-check-input {
-    position: static;
-    margin-top: 0;
-    margin-right: 0.3125rem;
-    margin-left: 0; }
-#conversejs .valid-feedback {
-  display: none;
-  width: 100%;
-  margin-top: 0.25rem;
-  font-size: 80%;
-  color: #3AA569; }
-#conversejs .valid-tooltip {
-  position: absolute;
-  top: 100%;
-  z-index: 5;
-  display: none;
-  max-width: 100%;
-  padding: .5rem;
-  margin-top: .1rem;
-  font-size: .875rem;
-  line-height: 1;
-  color: #fff;
-  background-color: rgba(58, 165, 105, 0.8);
-  border-radius: .2rem; }
-.was-validated #conversejs .form-control:valid, #conversejs .form-control.is-valid,
-.was-validated #conversejs .custom-select:valid,
-#conversejs .custom-select.is-valid {
-  border-color: #3AA569; }
-  .was-validated #conversejs .form-control:valid:focus, #conversejs .form-control.is-valid:focus,
-  .was-validated #conversejs .custom-select:valid:focus,
-  #conversejs .custom-select.is-valid:focus {
-    border-color: #3AA569;
-    box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.25); }
-  .was-validated #conversejs .form-control:valid ~ .valid-feedback,
-  .was-validated #conversejs .form-control:valid ~ .valid-tooltip, #conversejs .form-control.is-valid ~ .valid-feedback,
-  #conversejs .form-control.is-valid ~ .valid-tooltip,
-  .was-validated #conversejs .custom-select:valid ~ .valid-feedback,
-  .was-validated #conversejs .custom-select:valid ~ .valid-tooltip,
-  #conversejs .custom-select.is-valid ~ .valid-feedback,
-  #conversejs .custom-select.is-valid ~ .valid-tooltip {
-    display: block; }
-.was-validated #conversejs .form-check-input:valid ~ .form-check-label, #conversejs .form-check-input.is-valid ~ .form-check-label {
-  color: #3AA569; }
-.was-validated #conversejs .form-check-input:valid ~ .valid-feedback,
-.was-validated #conversejs .form-check-input:valid ~ .valid-tooltip, #conversejs .form-check-input.is-valid ~ .valid-feedback,
-#conversejs .form-check-input.is-valid ~ .valid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:valid ~ .custom-control-label, #conversejs .custom-control-input.is-valid ~ .custom-control-label {
-  color: #3AA569; }
-  .was-validated #conversejs .custom-control-input:valid ~ .custom-control-label::before, #conversejs .custom-control-input.is-valid ~ .custom-control-label::before {
-    background-color: #89d6ab; }
-.was-validated #conversejs .custom-control-input:valid ~ .valid-feedback,
-.was-validated #conversejs .custom-control-input:valid ~ .valid-tooltip, #conversejs .custom-control-input.is-valid ~ .valid-feedback,
-#conversejs .custom-control-input.is-valid ~ .valid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:valid:checked ~ .custom-control-label::before, #conversejs .custom-control-input.is-valid:checked ~ .custom-control-label::before {
-  background-color: #50c282; }
-.was-validated #conversejs .custom-control-input:valid:focus ~ .custom-control-label::before, #conversejs .custom-control-input.is-valid:focus ~ .custom-control-label::before {
-  box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(58, 165, 105, 0.25); }
-.was-validated #conversejs .custom-file-input:valid ~ .custom-file-label, #conversejs .custom-file-input.is-valid ~ .custom-file-label {
-  border-color: #3AA569; }
-  .was-validated #conversejs .custom-file-input:valid ~ .custom-file-label::before, #conversejs .custom-file-input.is-valid ~ .custom-file-label::before {
-    border-color: inherit; }
-.was-validated #conversejs .custom-file-input:valid ~ .valid-feedback,
-.was-validated #conversejs .custom-file-input:valid ~ .valid-tooltip, #conversejs .custom-file-input.is-valid ~ .valid-feedback,
-#conversejs .custom-file-input.is-valid ~ .valid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-file-input:valid:focus ~ .custom-file-label, #conversejs .custom-file-input.is-valid:focus ~ .custom-file-label {
-  box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.25); }
-#conversejs .invalid-feedback {
-  display: none;
-  width: 100%;
-  margin-top: 0.25rem;
-  font-size: 80%;
-  color: #E77051; }
-#conversejs .invalid-tooltip {
-  position: absolute;
-  top: 100%;
-  z-index: 5;
-  display: none;
-  max-width: 100%;
-  padding: .5rem;
-  margin-top: .1rem;
-  font-size: .875rem;
-  line-height: 1;
-  color: #fff;
-  background-color: rgba(231, 112, 81, 0.8);
-  border-radius: .2rem; }
-.was-validated #conversejs .form-control:invalid, #conversejs .form-control.is-invalid,
-.was-validated #conversejs .custom-select:invalid,
-#conversejs .custom-select.is-invalid {
-  border-color: #E77051; }
-  .was-validated #conversejs .form-control:invalid:focus, #conversejs .form-control.is-invalid:focus,
-  .was-validated #conversejs .custom-select:invalid:focus,
-  #conversejs .custom-select.is-invalid:focus {
-    border-color: #E77051;
-    box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.25); }
-  .was-validated #conversejs .form-control:invalid ~ .invalid-feedback,
-  .was-validated #conversejs .form-control:invalid ~ .invalid-tooltip, #conversejs .form-control.is-invalid ~ .invalid-feedback,
-  #conversejs .form-control.is-invalid ~ .invalid-tooltip,
-  .was-validated #conversejs .custom-select:invalid ~ .invalid-feedback,
-  .was-validated #conversejs .custom-select:invalid ~ .invalid-tooltip,
-  #conversejs .custom-select.is-invalid ~ .invalid-feedback,
-  #conversejs .custom-select.is-invalid ~ .invalid-tooltip {
-    display: block; }
-.was-validated #conversejs .form-check-input:invalid ~ .form-check-label, #conversejs .form-check-input.is-invalid ~ .form-check-label {
-  color: #E77051; }
-.was-validated #conversejs .form-check-input:invalid ~ .invalid-feedback,
-.was-validated #conversejs .form-check-input:invalid ~ .invalid-tooltip, #conversejs .form-check-input.is-invalid ~ .invalid-feedback,
-#conversejs .form-check-input.is-invalid ~ .invalid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:invalid ~ .custom-control-label, #conversejs .custom-control-input.is-invalid ~ .custom-control-label {
-  color: #E77051; }
-  .was-validated #conversejs .custom-control-input:invalid ~ .custom-control-label::before, #conversejs .custom-control-input.is-invalid ~ .custom-control-label::before {
-    background-color: #f6ccc1; }
-.was-validated #conversejs .custom-control-input:invalid ~ .invalid-feedback,
-.was-validated #conversejs .custom-control-input:invalid ~ .invalid-tooltip, #conversejs .custom-control-input.is-invalid ~ .invalid-feedback,
-#conversejs .custom-control-input.is-invalid ~ .invalid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:invalid:checked ~ .custom-control-label::before, #conversejs .custom-control-input.is-invalid:checked ~ .custom-control-label::before {
-  background-color: #ed957e; }
-.was-validated #conversejs .custom-control-input:invalid:focus ~ .custom-control-label::before, #conversejs .custom-control-input.is-invalid:focus ~ .custom-control-label::before {
-  box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(231, 112, 81, 0.25); }
-.was-validated #conversejs .custom-file-input:invalid ~ .custom-file-label, #conversejs .custom-file-input.is-invalid ~ .custom-file-label {
-  border-color: #E77051; }
-  .was-validated #conversejs .custom-file-input:invalid ~ .custom-file-label::before, #conversejs .custom-file-input.is-invalid ~ .custom-file-label::before {
-    border-color: inherit; }
-.was-validated #conversejs .custom-file-input:invalid ~ .invalid-feedback,
-.was-validated #conversejs .custom-file-input:invalid ~ .invalid-tooltip, #conversejs .custom-file-input.is-invalid ~ .invalid-feedback,
-#conversejs .custom-file-input.is-invalid ~ .invalid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-file-input:invalid:focus ~ .custom-file-label, #conversejs .custom-file-input.is-invalid:focus ~ .custom-file-label {
-  box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.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 .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;
-      margin-top: 0;
-      margin-right: 0.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;
-  text-align: center;
-  white-space: nowrap;
-  vertical-align: middle;
-  user-select: none;
-  border: 1px solid transparent;
-  padding: 0.375rem 0.75rem;
-  font-size: 1rem;
-  line-height: 1.5;
-  border-radius: 0.25rem;
-  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; }
-  #conversejs .btn:hover, #conversejs .btn:focus {
-    text-decoration: none; }
-  #conversejs .btn:focus, #conversejs .btn.focus {
-    outline: 0;
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-  #conversejs .btn.disabled, #conversejs .btn:disabled {
-    opacity: 0.65; }
-  #conversejs .btn:not(:disabled):not(.disabled) {
-    cursor: pointer; }
-  #conversejs .btn:not(:disabled):not(.disabled):active, #conversejs .btn:not(:disabled):not(.disabled).active {
-    background-image: none; }
-#conversejs a.btn.disabled,
-#conversejs fieldset:disabled a.btn {
-  pointer-events: none; }
-#conversejs .btn-primary {
-  color: #fff;
-  background-color: #387592;
-  border-color: #387592; }
-  #conversejs .btn-primary:hover {
-    color: #fff;
-    background-color: #2d5f76;
-    border-color: #2a576d; }
-  #conversejs .btn-primary:focus, #conversejs .btn-primary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.5); }
-  #conversejs .btn-primary.disabled, #conversejs .btn-primary:disabled {
-    color: #fff;
-    background-color: #387592;
-    border-color: #387592; }
-  #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: #2a576d;
-    border-color: #265064; }
-    #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 0.2rem rgba(56, 117, 146, 0.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 {
-    box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.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 0.2rem rgba(108, 117, 125, 0.5); }
-#conversejs .btn-success {
-  color: #fff;
-  background-color: #3AA569;
-  border-color: #3AA569; }
-  #conversejs .btn-success:hover {
-    color: #fff;
-    background-color: #308957;
-    border-color: #2d7f51; }
-  #conversejs .btn-success:focus, #conversejs .btn-success.focus {
-    box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.5); }
-  #conversejs .btn-success.disabled, #conversejs .btn-success:disabled {
-    color: #fff;
-    background-color: #3AA569;
-    border-color: #3AA569; }
-  #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: #2d7f51;
-    border-color: #29764b; }
-    #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 0.2rem rgba(58, 165, 105, 0.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 {
-    box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.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 0.2rem rgba(23, 162, 184, 0.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 {
-    box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.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 0.2rem rgba(255, 193, 7, 0.5); }
-#conversejs .btn-danger {
-  color: #fff;
-  background-color: #E77051;
-  border-color: #E77051; }
-  #conversejs .btn-danger:hover {
-    color: #fff;
-    background-color: #e2542f;
-    border-color: #e14b24; }
-  #conversejs .btn-danger:focus, #conversejs .btn-danger.focus {
-    box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.5); }
-  #conversejs .btn-danger.disabled, #conversejs .btn-danger:disabled {
-    color: #fff;
-    background-color: #E77051;
-    border-color: #E77051; }
-  #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: #e14b24;
-    border-color: #da451e; }
-    #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 0.2rem rgba(231, 112, 81, 0.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 {
-    box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.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 0.2rem rgba(248, 249, 250, 0.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 {
-    box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.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 0.2rem rgba(52, 58, 64, 0.5); }
-#conversejs .btn-outline-primary {
-  color: #387592;
-  background-color: transparent;
-  background-image: none;
-  border-color: #387592; }
-  #conversejs .btn-outline-primary:hover {
-    color: #fff;
-    background-color: #387592;
-    border-color: #387592; }
-  #conversejs .btn-outline-primary:focus, #conversejs .btn-outline-primary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.5); }
-  #conversejs .btn-outline-primary.disabled, #conversejs .btn-outline-primary:disabled {
-    color: #387592;
-    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: #387592;
-    border-color: #387592; }
-    #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 0.2rem rgba(56, 117, 146, 0.5); }
-#conversejs .btn-outline-secondary {
-  color: #6c757d;
-  background-color: transparent;
-  background-image: none;
-  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 0.2rem rgba(108, 117, 125, 0.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 0.2rem rgba(108, 117, 125, 0.5); }
-#conversejs .btn-outline-success {
-  color: #3AA569;
-  background-color: transparent;
-  background-image: none;
-  border-color: #3AA569; }
-  #conversejs .btn-outline-success:hover {
-    color: #fff;
-    background-color: #3AA569;
-    border-color: #3AA569; }
-  #conversejs .btn-outline-success:focus, #conversejs .btn-outline-success.focus {
-    box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.5); }
-  #conversejs .btn-outline-success.disabled, #conversejs .btn-outline-success:disabled {
-    color: #3AA569;
-    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: #3AA569;
-    border-color: #3AA569; }
-    #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 0.2rem rgba(58, 165, 105, 0.5); }
-#conversejs .btn-outline-info {
-  color: #17a2b8;
-  background-color: transparent;
-  background-image: none;
-  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 0.2rem rgba(23, 162, 184, 0.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 0.2rem rgba(23, 162, 184, 0.5); }
-#conversejs .btn-outline-warning {
-  color: #ffc107;
-  background-color: transparent;
-  background-image: none;
-  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 0.2rem rgba(255, 193, 7, 0.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 0.2rem rgba(255, 193, 7, 0.5); }
-#conversejs .btn-outline-danger {
-  color: #E77051;
-  background-color: transparent;
-  background-image: none;
-  border-color: #E77051; }
-  #conversejs .btn-outline-danger:hover {
-    color: #fff;
-    background-color: #E77051;
-    border-color: #E77051; }
-  #conversejs .btn-outline-danger:focus, #conversejs .btn-outline-danger.focus {
-    box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.5); }
-  #conversejs .btn-outline-danger.disabled, #conversejs .btn-outline-danger:disabled {
-    color: #E77051;
-    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: #E77051;
-    border-color: #E77051; }
-    #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 0.2rem rgba(231, 112, 81, 0.5); }
-#conversejs .btn-outline-light {
-  color: #f8f9fa;
-  background-color: transparent;
-  background-image: none;
-  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 0.2rem rgba(248, 249, 250, 0.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 0.2rem rgba(248, 249, 250, 0.5); }
-#conversejs .btn-outline-dark {
-  color: #343a40;
-  background-color: transparent;
-  background-image: none;
-  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 0.2rem rgba(52, 58, 64, 0.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 0.2rem rgba(52, 58, 64, 0.5); }
-#conversejs .btn-link {
-  font-weight: 400;
-  color: #578EA9;
-  background-color: transparent; }
-  #conversejs .btn-link:hover {
-    color: #3d6477;
-    text-decoration: underline;
-    background-color: transparent;
-    border-color: transparent; }
-  #conversejs .btn-link:focus, #conversejs .btn-link.focus {
-    text-decoration: underline;
-    border-color: transparent;
-    box-shadow: none; }
-  #conversejs .btn-link:disabled, #conversejs .btn-link.disabled {
-    color: #6c757d; }
-#conversejs .btn-lg, #conversejs .btn-group-lg > .btn {
-  padding: 0.5rem 1rem;
-  font-size: 1.25rem;
-  line-height: 1.5;
-  border-radius: 0.3rem; }
-#conversejs .btn-sm, #conversejs .btn-group-sm > .btn {
-  padding: 0.25rem 0.5rem;
-  font-size: 0.875rem;
-  line-height: 1.5;
-  border-radius: 0.2rem; }
-#conversejs .btn-block {
-  display: block;
-  width: 100%; }
-  #conversejs .btn-block + .btn-block {
-    margin-top: 0.5rem; }
-#conversejs input[type="submit"].btn-block,
-#conversejs input[type="reset"].btn-block,
-#conversejs input[type="button"].btn-block {
-  width: 100%; }
-#conversejs .fade {
-  opacity: 0;
-  transition: opacity 0.15s linear; }
-  #conversejs .fade.show {
-    opacity: 1; }
-#conversejs .collapse {
-  display: none; }
-  #conversejs .collapse.show {
-    display: block; }
-#conversejs tr.collapse.show {
-  display: table-row; }
-#conversejs tbody.collapse.show {
-  display: table-row-group; }
-#conversejs .collapsing {
-  position: relative;
-  height: 0;
-  overflow: hidden;
-  transition: height 0.35s ease; }
-#conversejs .dropup,
-#conversejs .dropdown {
-  position: relative; }
-#conversejs .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0.3em solid;
-  border-right: 0.3em solid transparent;
-  border-bottom: 0;
-  border-left: 0.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: 0.5rem 0;
-  margin: 0.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, 0.15);
-  border-radius: 0.25rem; }
-#conversejs .dropup .dropdown-menu {
-  margin-top: 0;
-  margin-bottom: 0.125rem; }
-#conversejs .dropup .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0;
-  border-right: 0.3em solid transparent;
-  border-bottom: 0.3em solid;
-  border-left: 0.3em solid transparent; }
-#conversejs .dropup .dropdown-toggle:empty::after {
-  margin-left: 0; }
-#conversejs .dropright .dropdown-menu {
-  margin-top: 0;
-  margin-left: 0.125rem; }
-#conversejs .dropright .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0.3em solid transparent;
-  border-bottom: 0.3em solid transparent;
-  border-left: 0.3em solid; }
-#conversejs .dropright .dropdown-toggle:empty::after {
-  margin-left: 0; }
-#conversejs .dropright .dropdown-toggle::after {
-  vertical-align: 0; }
-#conversejs .dropleft .dropdown-menu {
-  margin-top: 0;
-  margin-right: 0.125rem; }
-#conversejs .dropleft .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: ""; }
-#conversejs .dropleft .dropdown-toggle::after {
-  display: none; }
-#conversejs .dropleft .dropdown-toggle::before {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-right: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0.3em solid transparent;
-  border-right: 0.3em solid;
-  border-bottom: 0.3em solid transparent; }
-#conversejs .dropleft .dropdown-toggle:empty::after {
-  margin-left: 0; }
-#conversejs .dropleft .dropdown-toggle::before {
-  vertical-align: 0; }
-#conversejs .dropdown-divider {
-  height: 0;
-  margin: 0.5rem 0;
-  overflow: hidden;
-  border-top: 1px solid #e9ecef; }
-#conversejs .dropdown-item {
-  display: block;
-  width: 100%;
-  padding: 0.25rem 1.5rem;
-  clear: both;
-  font-weight: 400;
-  color: #212529;
-  text-align: inherit;
-  white-space: nowrap;
-  background-color: transparent;
-  border: 0; }
-  #conversejs .dropdown-item:hover, #conversejs .dropdown-item:focus {
-    color: #16181b;
-    text-decoration: none;
-    background-color: #f8f9fa; }
-  #conversejs .dropdown-item.active, #conversejs .dropdown-item:active {
-    color: #fff;
-    text-decoration: none;
-    background-color: #387592; }
-  #conversejs .dropdown-item.disabled, #conversejs .dropdown-item:disabled {
-    color: #6c757d;
-    background-color: transparent; }
-#conversejs .dropdown-menu.show {
-  display: block; }
-#conversejs .dropdown-header {
-  display: block;
-  padding: 0.5rem 1.5rem;
-  margin-bottom: 0;
-  font-size: 0.875rem;
-  color: #6c757d;
-  white-space: nowrap; }
-#conversejs .btn-group,
-#conversejs .btn-group-vertical {
-  position: relative;
-  display: inline-flex;
-  vertical-align: middle; }
-  #conversejs .btn-group > .btn,
-  #conversejs .btn-group-vertical > .btn {
-    position: relative;
-    flex: 0 1 auto; }
-    #conversejs .btn-group > .btn:hover,
-    #conversejs .btn-group-vertical > .btn:hover {
-      z-index: 1; }
-    #conversejs .btn-group > .btn:focus, #conversejs .btn-group > .btn:active, #conversejs .btn-group > .btn.active,
-    #conversejs .btn-group-vertical > .btn:focus,
-    #conversejs .btn-group-vertical > .btn:active,
-    #conversejs .btn-group-vertical > .btn.active {
-      z-index: 1; }
-  #conversejs .btn-group .btn + .btn,
-  #conversejs .btn-group .btn + .btn-group,
-  #conversejs .btn-group .btn-group + .btn,
-  #conversejs .btn-group .btn-group + .btn-group,
-  #conversejs .btn-group-vertical .btn + .btn,
-  #conversejs .btn-group-vertical .btn + .btn-group,
-  #conversejs .btn-group-vertical .btn-group + .btn,
-  #conversejs .btn-group-vertical .btn-group + .btn-group {
-    margin-left: -1px; }
-#conversejs .btn-toolbar {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: flex-start; }
-  #conversejs .btn-toolbar .input-group {
-    width: auto; }
-#conversejs .btn-group > .btn:first-child {
-  margin-left: 0; }
-#conversejs .btn-group > .btn:not(:last-child):not(.dropdown-toggle),
-#conversejs .btn-group > .btn-group:not(:last-child) > .btn {
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0; }
-#conversejs .btn-group > .btn:not(:first-child),
-#conversejs .btn-group > .btn-group:not(:first-child) > .btn {
-  border-top-left-radius: 0;
-  border-bottom-left-radius: 0; }
-#conversejs .dropdown-toggle-split {
-  padding-right: 0.5625rem;
-  padding-left: 0.5625rem; }
-  #conversejs .dropdown-toggle-split::after {
-    margin-left: 0; }
-#conversejs .btn-sm + .dropdown-toggle-split, #conversejs .btn-group-sm > .btn + .dropdown-toggle-split {
-  padding-right: 0.375rem;
-  padding-left: 0.375rem; }
-#conversejs .btn-lg + .dropdown-toggle-split, #conversejs .btn-group-lg > .btn + .dropdown-toggle-split {
-  padding-right: 0.75rem;
-  padding-left: 0.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 + .btn,
-  #conversejs .btn-group-vertical > .btn + .btn-group,
-  #conversejs .btn-group-vertical > .btn-group + .btn,
-  #conversejs .btn-group-vertical > .btn-group + .btn-group {
-    margin-top: -1px;
-    margin-left: 0; }
-  #conversejs .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),
-  #conversejs .btn-group-vertical > .btn-group:not(:last-child) > .btn {
-    border-bottom-right-radius: 0;
-    border-bottom-left-radius: 0; }
-  #conversejs .btn-group-vertical > .btn:not(:first-child),
-  #conversejs .btn-group-vertical > .btn-group:not(:first-child) > .btn {
-    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="radio"],
-  #conversejs .btn-group-toggle > .btn input[type="checkbox"],
-  #conversejs .btn-group-toggle > .btn-group > .btn input[type="radio"],
-  #conversejs .btn-group-toggle > .btn-group > .btn input[type="checkbox"] {
-    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 > .form-control,
-  #conversejs .input-group > .custom-select,
-  #conversejs .input-group > .custom-file {
-    position: relative;
-    flex: 1 1 auto;
-    width: 1%;
-    margin-bottom: 0; }
-    #conversejs .input-group > .form-control:focus,
-    #conversejs .input-group > .custom-select:focus,
-    #conversejs .input-group > .custom-file:focus {
-      z-index: 3; }
-    #conversejs .input-group > .form-control + .form-control,
-    #conversejs .input-group > .form-control + .custom-select,
-    #conversejs .input-group > .form-control + .custom-file,
-    #conversejs .input-group > .custom-select + .form-control,
-    #conversejs .input-group > .custom-select + .custom-select,
-    #conversejs .input-group > .custom-select + .custom-file,
-    #conversejs .input-group > .custom-file + .form-control,
-    #conversejs .input-group > .custom-file + .custom-select,
-    #conversejs .input-group > .custom-file + .custom-file {
-      margin-left: -1px; }
-  #conversejs .input-group > .form-control:not(:last-child),
-  #conversejs .input-group > .custom-select:not(:last-child) {
-    border-top-right-radius: 0;
-    border-bottom-right-radius: 0; }
-  #conversejs .input-group > .form-control:not(:first-child),
-  #conversejs .input-group > .custom-select: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::before {
-      border-top-right-radius: 0;
-      border-bottom-right-radius: 0; }
-    #conversejs .input-group > .custom-file:not(:first-child) .custom-file-label, #conversejs .input-group > .custom-file:not(:first-child) .custom-file-label::before {
-      border-top-left-radius: 0;
-      border-bottom-left-radius: 0; }
-#conversejs .input-group-prepend,
-#conversejs .input-group-append {
-  display: flex; }
-  #conversejs .input-group-prepend .btn,
-  #conversejs .input-group-append .btn {
-    position: relative;
-    z-index: 2; }
-  #conversejs .input-group-prepend .btn + .btn,
-  #conversejs .input-group-prepend .btn + .input-group-text,
-  #conversejs .input-group-prepend .input-group-text + .input-group-text,
-  #conversejs .input-group-prepend .input-group-text + .btn,
-  #conversejs .input-group-append .btn + .btn,
-  #conversejs .input-group-append .btn + .input-group-text,
-  #conversejs .input-group-append .input-group-text + .input-group-text,
-  #conversejs .input-group-append .input-group-text + .btn {
-    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: 0.375rem 0.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: 0.25rem; }
-  #conversejs .input-group-text input[type="radio"],
-  #conversejs .input-group-text input[type="checkbox"] {
-    margin-top: 0; }
-#conversejs .input-group > .input-group-prepend > .btn,
-#conversejs .input-group > .input-group-prepend > .input-group-text,
-#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-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
-#conversejs .input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
-  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:not(:first-child) > .btn,
-#conversejs .input-group > .input-group-prepend:not(:first-child) > .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) {
-  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;
-  z-index: -1;
-  opacity: 0; }
-  #conversejs .custom-control-input:checked ~ .custom-control-label::before {
-    color: #fff;
-    background-color: #387592; }
-  #conversejs .custom-control-input:focus ~ .custom-control-label::before {
-    box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-  #conversejs .custom-control-input:active ~ .custom-control-label::before {
-    color: #fff;
-    background-color: #a1c9db; }
-  #conversejs .custom-control-input:disabled ~ .custom-control-label {
-    color: #6c757d; }
-    #conversejs .custom-control-input:disabled ~ .custom-control-label::before {
-      background-color: #e9ecef; }
-#conversejs .custom-control-label {
-  margin-bottom: 0; }
-  #conversejs .custom-control-label::before {
-    position: absolute;
-    top: 0.25rem;
-    left: 0;
-    display: block;
-    width: 1rem;
-    height: 1rem;
-    pointer-events: none;
-    content: "";
-    user-select: none;
-    background-color: #dee2e6; }
-  #conversejs .custom-control-label::after {
-    position: absolute;
-    top: 0.25rem;
-    left: 0;
-    display: block;
-    width: 1rem;
-    height: 1rem;
-    content: "";
-    background-repeat: no-repeat;
-    background-position: center center;
-    background-size: 50% 50%; }
-#conversejs .custom-checkbox .custom-control-label::before {
-  border-radius: 0.25rem; }
-#conversejs .custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
-  background-color: #387592; }
-#conversejs .custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {
-  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); }
-#conversejs .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {
-  background-color: #387592; }
-#conversejs .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {
-  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' 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(56, 117, 146, 0.5); }
-#conversejs .custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {
-  background-color: rgba(56, 117, 146, 0.5); }
-#conversejs .custom-radio .custom-control-label::before {
-  border-radius: 50%; }
-#conversejs .custom-radio .custom-control-input:checked ~ .custom-control-label::before {
-  background-color: #387592; }
-#conversejs .custom-radio .custom-control-input:checked ~ .custom-control-label::after {
-  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' 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(56, 117, 146, 0.5); }
-#conversejs .custom-select {
-  display: inline-block;
-  width: 100%;
-  height: calc(2.25rem + 2px);
-  padding: 0.375rem 1.75rem 0.375rem 0.75rem;
-  line-height: 1.5;
-  color: #495057;
-  vertical-align: middle;
-  background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
-  background-size: 8px 10px;
-  border: 1px solid #ced4da;
-  border-radius: 0.25rem;
-  appearance: none; }
-  #conversejs .custom-select:focus {
-    border-color: #7db3cd;
-    outline: 0;
-    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(125, 179, 205, 0.5); }
-    #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: 0.75rem;
-    background-image: none; }
-  #conversejs .custom-select:disabled {
-    color: #6c757d;
-    background-color: #e9ecef; }
-  #conversejs .custom-select::-ms-expand {
-    opacity: 0; }
-#conversejs .custom-select-sm {
-  height: calc(1.8125rem + 2px);
-  padding-top: 0.375rem;
-  padding-bottom: 0.375rem;
-  font-size: 75%; }
-#conversejs .custom-select-lg {
-  height: calc(2.875rem + 2px);
-  padding-top: 0.375rem;
-  padding-bottom: 0.375rem;
-  font-size: 125%; }
-#conversejs .custom-file {
-  position: relative;
-  display: inline-block;
-  width: 100%;
-  height: calc(2.25rem + 2px);
-  margin-bottom: 0; }
-#conversejs .custom-file-input {
-  position: relative;
-  z-index: 2;
-  width: 100%;
-  height: calc(2.25rem + 2px);
-  margin: 0;
-  opacity: 0; }
-  #conversejs .custom-file-input:focus ~ .custom-file-control {
-    border-color: #7db3cd;
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-    #conversejs .custom-file-input:focus ~ .custom-file-control::before {
-      border-color: #7db3cd; }
-  #conversejs .custom-file-input:lang(en) ~ .custom-file-label::after {
-    content: "Browse"; }
-#conversejs .custom-file-label {
-  position: absolute;
-  top: 0;
-  right: 0;
-  left: 0;
-  z-index: 1;
-  height: calc(2.25rem + 2px);
-  padding: 0.375rem 0.75rem;
-  line-height: 1.5;
-  color: #495057;
-  background-color: #fff;
-  border: 1px solid #ced4da;
-  border-radius: 0.25rem; }
-  #conversejs .custom-file-label::after {
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    z-index: 3;
-    display: block;
-    height: calc(calc(2.25rem + 2px) - 1px * 2);
-    padding: 0.375rem 0.75rem;
-    line-height: 1.5;
-    color: #495057;
-    content: "Browse";
-    background-color: #e9ecef;
-    border-left: 1px solid #ced4da;
-    border-radius: 0 0.25rem 0.25rem 0; }
-#conversejs .card {
-  position: relative;
-  display: flex;
-  flex-direction: column;
-  min-width: 0;
-  word-wrap: break-word;
-  background-color: #fff;
-  background-clip: border-box;
-  border: 1px solid rgba(0, 0, 0, 0.125);
-  border-radius: 0.25rem; }
-  #conversejs .card > hr {
-    margin-right: 0;
-    margin-left: 0; }
-  #conversejs .card > .list-group:first-child .list-group-item:first-child {
-    border-top-left-radius: 0.25rem;
-    border-top-right-radius: 0.25rem; }
-  #conversejs .card > .list-group:last-child .list-group-item:last-child {
-    border-bottom-right-radius: 0.25rem;
-    border-bottom-left-radius: 0.25rem; }
-#conversejs .card-body {
-  flex: 1 1 auto;
-  padding: 1.25rem; }
-#conversejs .card-title {
-  margin-bottom: 0.75rem; }
-#conversejs .card-subtitle {
-  margin-top: -0.375rem;
-  margin-bottom: 0; }
-#conversejs .card-text:last-child {
-  margin-bottom: 0; }
-#conversejs .card-link:hover {
-  text-decoration: none; }
-#conversejs .card-link + .card-link {
-  margin-left: 1.25rem; }
-#conversejs .card-header {
-  padding: 0.75rem 1.25rem;
-  margin-bottom: 0;
-  background-color: rgba(0, 0, 0, 0.03);
-  border-bottom: 1px solid rgba(0, 0, 0, 0.125); }
-  #conversejs .card-header:first-child {
-    border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; }
-  #conversejs .card-header + .list-group .list-group-item:first-child {
-    border-top: 0; }
-#conversejs .card-footer {
-  padding: 0.75rem 1.25rem;
-  background-color: rgba(0, 0, 0, 0.03);
-  border-top: 1px solid rgba(0, 0, 0, 0.125); }
-  #conversejs .card-footer:last-child {
-    border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); }
-#conversejs .card-header-tabs {
-  margin-right: -0.625rem;
-  margin-bottom: -0.75rem;
-  margin-left: -0.625rem;
-  border-bottom: 0; }
-#conversejs .card-header-pills {
-  margin-right: -0.625rem;
-  margin-left: -0.625rem; }
-#conversejs .card-img-overlay {
-  position: absolute;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  padding: 1.25rem; }
-#conversejs .card-img {
-  width: 100%;
-  border-radius: calc(0.25rem - 1px); }
-#conversejs .card-img-top {
-  width: 100%;
-  border-top-left-radius: calc(0.25rem - 1px);
-  border-top-right-radius: calc(0.25rem - 1px); }
-#conversejs .card-img-bottom {
-  width: 100%;
-  border-bottom-right-radius: calc(0.25rem - 1px);
-  border-bottom-left-radius: calc(0.25rem - 1px); }
-#conversejs .card-deck {
-  display: flex;
-  flex-direction: column; }
-  #conversejs .card-deck .card {
-    margin-bottom: 15px; }
-  @media (min-width: 576px) {
-    #conversejs .card-deck {
-      flex-flow: row wrap;
-      margin-right: -15px;
-      margin-left: -15px; }
-      #conversejs .card-deck .card {
-        display: flex;
-        flex: 1 0 0%;
-        flex-direction: column;
-        margin-right: 15px;
-        margin-bottom: 0;
-        margin-left: 15px; } }
-#conversejs .card-group {
-  display: flex;
-  flex-direction: column; }
-  #conversejs .card-group > .card {
-    margin-bottom: 15px; }
-  @media (min-width: 576px) {
-    #conversejs .card-group {
-      flex-flow: row wrap; }
-      #conversejs .card-group > .card {
-        flex: 1 0 0%;
-        margin-bottom: 0; }
-        #conversejs .card-group > .card + .card {
-          margin-left: 0;
-          border-left: 0; }
-        #conversejs .card-group > .card:first-child {
-          border-top-right-radius: 0;
-          border-bottom-right-radius: 0; }
-          #conversejs .card-group > .card:first-child .card-img-top,
-          #conversejs .card-group > .card:first-child .card-header {
-            border-top-right-radius: 0; }
-          #conversejs .card-group > .card:first-child .card-img-bottom,
-          #conversejs .card-group > .card:first-child .card-footer {
-            border-bottom-right-radius: 0; }
-        #conversejs .card-group > .card:last-child {
-          border-top-left-radius: 0;
-          border-bottom-left-radius: 0; }
-          #conversejs .card-group > .card:last-child .card-img-top,
-          #conversejs .card-group > .card:last-child .card-header {
-            border-top-left-radius: 0; }
-          #conversejs .card-group > .card:last-child .card-img-bottom,
-          #conversejs .card-group > .card:last-child .card-footer {
-            border-bottom-left-radius: 0; }
-        #conversejs .card-group > .card:only-child {
-          border-radius: 0.25rem; }
-          #conversejs .card-group > .card:only-child .card-img-top,
-          #conversejs .card-group > .card:only-child .card-header {
-            border-top-left-radius: 0.25rem;
-            border-top-right-radius: 0.25rem; }
-          #conversejs .card-group > .card:only-child .card-img-bottom,
-          #conversejs .card-group > .card:only-child .card-footer {
-            border-bottom-right-radius: 0.25rem;
-            border-bottom-left-radius: 0.25rem; }
-        #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {
-          border-radius: 0; }
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {
-            border-radius: 0; } }
-#conversejs .card-columns .card {
-  margin-bottom: 0.75rem; }
-@media (min-width: 576px) {
-  #conversejs .card-columns {
-    column-count: 3;
-    column-gap: 1.25rem; }
-    #conversejs .card-columns .card {
-      display: inline-block;
-      width: 100%; } }
-#conversejs .breadcrumb {
-  display: flex;
-  flex-wrap: wrap;
-  padding: 0.75rem 1rem;
-  margin-bottom: 1rem;
-  list-style: none;
-  background-color: #e9ecef;
-  border-radius: 0.25rem; }
-#conversejs .breadcrumb-item + .breadcrumb-item::before {
-  display: inline-block;
-  padding-right: 0.5rem;
-  padding-left: 0.5rem;
-  color: #6c757d;
-  content: "/"; }
-#conversejs .breadcrumb-item + .breadcrumb-item:hover::before {
-  text-decoration: underline; }
-#conversejs .breadcrumb-item + .breadcrumb-item:hover::before {
-  text-decoration: none; }
-#conversejs .breadcrumb-item.active {
-  color: #6c757d; }
-#conversejs .badge {
-  display: inline-block;
-  padding: 0.25em 0.4em;
-  font-size: 75%;
-  font-weight: 700;
-  line-height: 1;
-  text-align: center;
-  white-space: nowrap;
-  vertical-align: baseline;
-  border-radius: 0.25rem; }
-  #conversejs .badge:empty {
-    display: none; }
-#conversejs .btn .badge {
-  position: relative;
-  top: -1px; }
-#conversejs .badge-pill {
-  padding-right: 0.6em;
-  padding-left: 0.6em;
-  border-radius: 10rem; }
-#conversejs .badge-primary {
-  color: #fff;
-  background-color: #387592; }
-  #conversejs .badge-primary[href]:hover, #conversejs .badge-primary[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #2a576d; }
-#conversejs .badge-secondary {
-  color: #fff;
-  background-color: #6c757d; }
-  #conversejs .badge-secondary[href]:hover, #conversejs .badge-secondary[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #545b62; }
-#conversejs .badge-success {
-  color: #fff;
-  background-color: #3AA569; }
-  #conversejs .badge-success[href]:hover, #conversejs .badge-success[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #2d7f51; }
-#conversejs .badge-info {
-  color: #fff;
-  background-color: #17a2b8; }
-  #conversejs .badge-info[href]:hover, #conversejs .badge-info[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #117a8b; }
-#conversejs .badge-warning {
-  color: #212529;
-  background-color: #ffc107; }
-  #conversejs .badge-warning[href]:hover, #conversejs .badge-warning[href]:focus {
-    color: #212529;
-    text-decoration: none;
-    background-color: #d39e00; }
-#conversejs .badge-danger {
-  color: #fff;
-  background-color: #E77051; }
-  #conversejs .badge-danger[href]:hover, #conversejs .badge-danger[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #e14b24; }
-#conversejs .badge-light {
-  color: #212529;
-  background-color: #f8f9fa; }
-  #conversejs .badge-light[href]:hover, #conversejs .badge-light[href]:focus {
-    color: #212529;
-    text-decoration: none;
-    background-color: #dae0e5; }
-#conversejs .badge-dark {
-  color: #fff;
-  background-color: #343a40; }
-  #conversejs .badge-dark[href]:hover, #conversejs .badge-dark[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #1d2124; }
-#conversejs .alert {
-  position: relative;
-  padding: 0.75rem 1.25rem;
-  margin-bottom: 1rem;
-  border: 1px solid transparent;
-  border-radius: 0.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: 0.75rem 1.25rem;
-    color: inherit; }
-#conversejs .alert-primary {
-  color: #1d3d4c;
-  background-color: #d7e3e9;
-  border-color: #c7d8e0; }
-  #conversejs .alert-primary hr {
-    border-top-color: #b7cdd7; }
-  #conversejs .alert-primary .alert-link {
-    color: #0f1f27; }
-#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: #1e5637;
-  background-color: #d8ede1;
-  border-color: #c8e6d5; }
-  #conversejs .alert-success hr {
-    border-top-color: #b6dec8; }
-  #conversejs .alert-success .alert-link {
-    color: #11301f; }
-#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: #783a2a;
-  background-color: #fae2dc;
-  border-color: #f8d7ce; }
-  #conversejs .alert-danger hr {
-    border-top-color: #f5c5b8; }
-  #conversejs .alert-danger .alert-link {
-    color: #52281d; }
-#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:hover, #conversejs .list-group-item-action:focus {
-    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: 0.75rem 1.25rem;
-  margin-bottom: -1px;
-  background-color: #fff;
-  border: 1px solid rgba(0, 0, 0, 0.125); }
-  #conversejs .list-group-item:first-child {
-    border-top-left-radius: 0.25rem;
-    border-top-right-radius: 0.25rem; }
-  #conversejs .list-group-item:last-child {
-    margin-bottom: 0;
-    border-bottom-right-radius: 0.25rem;
-    border-bottom-left-radius: 0.25rem; }
-  #conversejs .list-group-item:hover, #conversejs .list-group-item:focus {
-    z-index: 1;
-    text-decoration: none; }
-  #conversejs .list-group-item.disabled, #conversejs .list-group-item:disabled {
-    color: #6c757d;
-    background-color: #fff; }
-  #conversejs .list-group-item.active {
-    z-index: 2;
-    color: #fff;
-    background-color: #387592;
-    border-color: #387592; }
-#conversejs .list-group-flush .list-group-item {
-  border-right: 0;
-  border-left: 0;
-  border-radius: 0; }
-#conversejs .list-group-flush:first-child .list-group-item:first-child {
-  border-top: 0; }
-#conversejs .list-group-flush:last-child .list-group-item:last-child {
-  border-bottom: 0; }
-#conversejs .list-group-item-primary {
-  color: #1d3d4c;
-  background-color: #c7d8e0; }
-  #conversejs .list-group-item-primary.list-group-item-action:hover, #conversejs .list-group-item-primary.list-group-item-action:focus {
-    color: #1d3d4c;
-    background-color: #b7cdd7; }
-  #conversejs .list-group-item-primary.list-group-item-action.active {
-    color: #fff;
-    background-color: #1d3d4c;
-    border-color: #1d3d4c; }
-#conversejs .list-group-item-secondary {
-  color: #383d41;
-  background-color: #d6d8db; }
-  #conversejs .list-group-item-secondary.list-group-item-action:hover, #conversejs .list-group-item-secondary.list-group-item-action:focus {
-    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: #1e5637;
-  background-color: #c8e6d5; }
-  #conversejs .list-group-item-success.list-group-item-action:hover, #conversejs .list-group-item-success.list-group-item-action:focus {
-    color: #1e5637;
-    background-color: #b6dec8; }
-  #conversejs .list-group-item-success.list-group-item-action.active {
-    color: #fff;
-    background-color: #1e5637;
-    border-color: #1e5637; }
-#conversejs .list-group-item-info {
-  color: #0c5460;
-  background-color: #bee5eb; }
-  #conversejs .list-group-item-info.list-group-item-action:hover, #conversejs .list-group-item-info.list-group-item-action:focus {
-    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:hover, #conversejs .list-group-item-warning.list-group-item-action:focus {
-    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: #783a2a;
-  background-color: #f8d7ce; }
-  #conversejs .list-group-item-danger.list-group-item-action:hover, #conversejs .list-group-item-danger.list-group-item-action:focus {
-    color: #783a2a;
-    background-color: #f5c5b8; }
-  #conversejs .list-group-item-danger.list-group-item-action.active {
-    color: #fff;
-    background-color: #783a2a;
-    border-color: #783a2a; }
-#conversejs .list-group-item-light {
-  color: #818182;
-  background-color: #fdfdfe; }
-  #conversejs .list-group-item-light.list-group-item-action:hover, #conversejs .list-group-item-light.list-group-item-action:focus {
-    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:hover, #conversejs .list-group-item-dark.list-group-item-action:focus {
-    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, #conversejs .close:focus {
-    color: #000;
-    text-decoration: none;
-    opacity: .75; }
-  #conversejs .close:not(:disabled):not(.disabled) {
-    cursor: pointer; }
-#conversejs button.close {
-  padding: 0;
-  background-color: transparent;
-  border: 0;
-  -webkit-appearance: none; }
-#conversejs .modal-open {
-  overflow: hidden; }
-#conversejs .modal {
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 1050;
-  display: none;
-  overflow: hidden;
-  outline: 0; }
-  .modal-open #conversejs .modal {
-    overflow-x: hidden;
-    overflow-y: auto; }
-#conversejs .modal-dialog {
-  position: relative;
-  width: auto;
-  margin: 0.5rem;
-  pointer-events: none; }
-  .modal.fade #conversejs .modal-dialog {
-    transition: transform 0.3s ease-out;
-    transform: translate(0, -25%); }
-  .modal.show #conversejs .modal-dialog {
-    transform: translate(0, 0); }
-#conversejs .modal-dialog-centered {
-  display: flex;
-  align-items: center;
-  min-height: calc(100% - (0.5rem * 2)); }
-#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, 0.2);
-  border-radius: 0.3rem;
-  outline: 0; }
-#conversejs .modal-backdrop {
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 1040;
-  background-color: #000; }
-  #conversejs .modal-backdrop.fade {
-    opacity: 0; }
-  #conversejs .modal-backdrop.show {
-    opacity: 0.5; }
-#conversejs .modal-header {
-  display: flex;
-  align-items: flex-start;
-  justify-content: space-between;
-  padding: 1rem;
-  border-bottom: 1px solid #e9ecef;
-  border-top-left-radius: 0.3rem;
-  border-top-right-radius: 0.3rem; }
-  #conversejs .modal-header .close {
-    padding: 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;
-  align-items: center;
-  justify-content: flex-end;
-  padding: 1rem;
-  border-top: 1px solid #e9ecef; }
-  #conversejs .modal-footer > :not(:first-child) {
-    margin-left: .25rem; }
-  #conversejs .modal-footer > :not(:last-child) {
-    margin-right: .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-centered {
-    min-height: calc(100% - (1.75rem * 2)); }
-  #conversejs .modal-sm {
-    max-width: 300px; } }
-@media (min-width: 992px) {
-  #conversejs .modal-lg {
-    max-width: 800px; } }
-#conversejs .tooltip {
-  position: absolute;
-  z-index: 1070;
-  display: block;
-  margin: 0;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  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: 0.875rem;
-  word-wrap: break-word;
-  opacity: 0; }
-  #conversejs .tooltip.show {
-    opacity: 0.9; }
-  #conversejs .tooltip .arrow {
-    position: absolute;
-    display: block;
-    width: 0.8rem;
-    height: 0.4rem; }
-    #conversejs .tooltip .arrow::before {
-      position: absolute;
-      content: "";
-      border-color: transparent;
-      border-style: solid; }
-#conversejs .bs-tooltip-top, #conversejs .bs-tooltip-auto[x-placement^="top"] {
-  padding: 0.4rem 0; }
-  #conversejs .bs-tooltip-top .arrow, #conversejs .bs-tooltip-auto[x-placement^="top"] .arrow {
-    bottom: 0; }
-    #conversejs .bs-tooltip-top .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="top"] .arrow::before {
-      top: 0;
-      border-width: 0.4rem 0.4rem 0;
-      border-top-color: #000; }
-#conversejs .bs-tooltip-right, #conversejs .bs-tooltip-auto[x-placement^="right"] {
-  padding: 0 0.4rem; }
-  #conversejs .bs-tooltip-right .arrow, #conversejs .bs-tooltip-auto[x-placement^="right"] .arrow {
-    left: 0;
-    width: 0.4rem;
-    height: 0.8rem; }
-    #conversejs .bs-tooltip-right .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="right"] .arrow::before {
-      right: 0;
-      border-width: 0.4rem 0.4rem 0.4rem 0;
-      border-right-color: #000; }
-#conversejs .bs-tooltip-bottom, #conversejs .bs-tooltip-auto[x-placement^="bottom"] {
-  padding: 0.4rem 0; }
-  #conversejs .bs-tooltip-bottom .arrow, #conversejs .bs-tooltip-auto[x-placement^="bottom"] .arrow {
-    top: 0; }
-    #conversejs .bs-tooltip-bottom .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="bottom"] .arrow::before {
-      bottom: 0;
-      border-width: 0 0.4rem 0.4rem;
-      border-bottom-color: #000; }
-#conversejs .bs-tooltip-left, #conversejs .bs-tooltip-auto[x-placement^="left"] {
-  padding: 0 0.4rem; }
-  #conversejs .bs-tooltip-left .arrow, #conversejs .bs-tooltip-auto[x-placement^="left"] .arrow {
-    right: 0;
-    width: 0.4rem;
-    height: 0.8rem; }
-    #conversejs .bs-tooltip-left .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="left"] .arrow::before {
-      left: 0;
-      border-width: 0.4rem 0 0.4rem 0.4rem;
-      border-left-color: #000; }
-#conversejs .tooltip-inner {
-  max-width: 200px;
-  padding: 0.25rem 0.5rem;
-  color: #fff;
-  text-align: center;
-  background-color: #000;
-  border-radius: 0.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, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  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: 0.875rem;
-  word-wrap: break-word;
-  background-color: #fff;
-  background-clip: padding-box;
-  border: 1px solid rgba(0, 0, 0, 0.2);
-  border-radius: 0.3rem; }
-  #conversejs .popover .arrow {
-    position: absolute;
-    display: block;
-    width: 1rem;
-    height: 0.5rem;
-    margin: 0 0.3rem; }
-    #conversejs .popover .arrow::before, #conversejs .popover .arrow::after {
-      position: absolute;
-      display: block;
-      content: "";
-      border-color: transparent;
-      border-style: solid; }
-#conversejs .bs-popover-top, #conversejs .bs-popover-auto[x-placement^="top"] {
-  margin-bottom: 0.5rem; }
-  #conversejs .bs-popover-top .arrow, #conversejs .bs-popover-auto[x-placement^="top"] .arrow {
-    bottom: calc((0.5rem + 1px) * -1); }
-  #conversejs .bs-popover-top .arrow::before, #conversejs .bs-popover-auto[x-placement^="top"] .arrow::before,
-  #conversejs .bs-popover-top .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="top"] .arrow::after {
-    border-width: 0.5rem 0.5rem 0; }
-  #conversejs .bs-popover-top .arrow::before, #conversejs .bs-popover-auto[x-placement^="top"] .arrow::before {
-    bottom: 0;
-    border-top-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-top .arrow::after, #conversejs .bs-popover-auto[x-placement^="top"] .arrow::after {
-    bottom: 1px;
-    border-top-color: #fff; }
-#conversejs .bs-popover-right, #conversejs .bs-popover-auto[x-placement^="right"] {
-  margin-left: 0.5rem; }
-  #conversejs .bs-popover-right .arrow, #conversejs .bs-popover-auto[x-placement^="right"] .arrow {
-    left: calc((0.5rem + 1px) * -1);
-    width: 0.5rem;
-    height: 1rem;
-    margin: 0.3rem 0; }
-  #conversejs .bs-popover-right .arrow::before, #conversejs .bs-popover-auto[x-placement^="right"] .arrow::before,
-  #conversejs .bs-popover-right .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="right"] .arrow::after {
-    border-width: 0.5rem 0.5rem 0.5rem 0; }
-  #conversejs .bs-popover-right .arrow::before, #conversejs .bs-popover-auto[x-placement^="right"] .arrow::before {
-    left: 0;
-    border-right-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-right .arrow::after, #conversejs .bs-popover-auto[x-placement^="right"] .arrow::after {
-    left: 1px;
-    border-right-color: #fff; }
-#conversejs .bs-popover-bottom, #conversejs .bs-popover-auto[x-placement^="bottom"] {
-  margin-top: 0.5rem; }
-  #conversejs .bs-popover-bottom .arrow, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow {
-    top: calc((0.5rem + 1px) * -1); }
-  #conversejs .bs-popover-bottom .arrow::before, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::before,
-  #conversejs .bs-popover-bottom .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::after {
-    border-width: 0 0.5rem 0.5rem 0.5rem; }
-  #conversejs .bs-popover-bottom .arrow::before, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::before {
-    top: 0;
-    border-bottom-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-bottom .arrow::after, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::after {
-    top: 1px;
-    border-bottom-color: #fff; }
-  #conversejs .bs-popover-bottom .popover-header::before, #conversejs .bs-popover-auto[x-placement^="bottom"] .popover-header::before {
-    position: absolute;
-    top: 0;
-    left: 50%;
-    display: block;
-    width: 1rem;
-    margin-left: -0.5rem;
-    content: "";
-    border-bottom: 1px solid #f7f7f7; }
-#conversejs .bs-popover-left, #conversejs .bs-popover-auto[x-placement^="left"] {
-  margin-right: 0.5rem; }
-  #conversejs .bs-popover-left .arrow, #conversejs .bs-popover-auto[x-placement^="left"] .arrow {
-    right: calc((0.5rem + 1px) * -1);
-    width: 0.5rem;
-    height: 1rem;
-    margin: 0.3rem 0; }
-  #conversejs .bs-popover-left .arrow::before, #conversejs .bs-popover-auto[x-placement^="left"] .arrow::before,
-  #conversejs .bs-popover-left .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="left"] .arrow::after {
-    border-width: 0.5rem 0 0.5rem 0.5rem; }
-  #conversejs .bs-popover-left .arrow::before, #conversejs .bs-popover-auto[x-placement^="left"] .arrow::before {
-    right: 0;
-    border-left-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-left .arrow::after, #conversejs .bs-popover-auto[x-placement^="left"] .arrow::after {
-    right: 1px;
-    border-left-color: #fff; }
-#conversejs .popover-header {
-  padding: 0.5rem 0.75rem;
-  margin-bottom: 0;
-  font-size: 1rem;
-  color: inherit;
-  background-color: #f7f7f7;
-  border-bottom: 1px solid #ebebeb;
-  border-top-left-radius: calc(0.3rem - 1px);
-  border-top-right-radius: calc(0.3rem - 1px); }
-  #conversejs .popover-header:empty {
-    display: none; }
-#conversejs .popover-body {
-  padding: 0.5rem 0.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: #387592 !important; }
-#conversejs a.bg-primary:hover, #conversejs a.bg-primary:focus,
-#conversejs button.bg-primary:hover,
-#conversejs button.bg-primary:focus {
-  background-color: #2a576d !important; }
-#conversejs .bg-secondary {
-  background-color: #6c757d !important; }
-#conversejs a.bg-secondary:hover, #conversejs a.bg-secondary:focus,
-#conversejs button.bg-secondary:hover,
-#conversejs button.bg-secondary:focus {
-  background-color: #545b62 !important; }
-#conversejs .bg-success {
-  background-color: #3AA569 !important; }
-#conversejs a.bg-success:hover, #conversejs a.bg-success:focus,
-#conversejs button.bg-success:hover,
-#conversejs button.bg-success:focus {
-  background-color: #2d7f51 !important; }
-#conversejs .bg-info {
-  background-color: #17a2b8 !important; }
-#conversejs a.bg-info:hover, #conversejs a.bg-info:focus,
-#conversejs button.bg-info:hover,
-#conversejs button.bg-info:focus {
-  background-color: #117a8b !important; }
-#conversejs .bg-warning {
-  background-color: #ffc107 !important; }
-#conversejs a.bg-warning:hover, #conversejs a.bg-warning:focus,
-#conversejs button.bg-warning:hover,
-#conversejs button.bg-warning:focus {
-  background-color: #d39e00 !important; }
-#conversejs .bg-danger {
-  background-color: #E77051 !important; }
-#conversejs a.bg-danger:hover, #conversejs a.bg-danger:focus,
-#conversejs button.bg-danger:hover,
-#conversejs button.bg-danger:focus {
-  background-color: #e14b24 !important; }
-#conversejs .bg-light {
-  background-color: #f8f9fa !important; }
-#conversejs a.bg-light:hover, #conversejs a.bg-light:focus,
-#conversejs button.bg-light:hover,
-#conversejs button.bg-light:focus {
-  background-color: #dae0e5 !important; }
-#conversejs .bg-dark {
-  background-color: #343a40 !important; }
-#conversejs a.bg-dark:hover, #conversejs a.bg-dark:focus,
-#conversejs button.bg-dark:hover,
-#conversejs button.bg-dark:focus {
-  background-color: #1d2124 !important; }
-#conversejs .bg-white {
-  background-color: #fff !important; }
-#conversejs .bg-transparent {
-  background-color: transparent !important; }
-#conversejs .border {
-  border: 1px solid #CCC !important; }
-#conversejs .border-top {
-  border-top: 1px solid #CCC !important; }
-#conversejs .border-right {
-  border-right: 1px solid #CCC !important; }
-#conversejs .border-bottom {
-  border-bottom: 1px solid #CCC !important; }
-#conversejs .border-left {
-  border-left: 1px solid #CCC !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: #387592 !important; }
-#conversejs .border-secondary {
-  border-color: #6c757d !important; }
-#conversejs .border-success {
-  border-color: #3AA569 !important; }
-#conversejs .border-info {
-  border-color: #17a2b8 !important; }
-#conversejs .border-warning {
-  border-color: #ffc107 !important; }
-#conversejs .border-danger {
-  border-color: #E77051 !important; }
-#conversejs .border-light {
-  border-color: #f8f9fa !important; }
-#conversejs .border-dark {
-  border-color: #343a40 !important; }
-#conversejs .border-white {
-  border-color: #fff !important; }
-#conversejs .rounded {
-  border-radius: 0.25rem !important; }
-#conversejs .rounded-top {
-  border-top-left-radius: 0.25rem !important;
-  border-top-right-radius: 0.25rem !important; }
-#conversejs .rounded-right {
-  border-top-right-radius: 0.25rem !important;
-  border-bottom-right-radius: 0.25rem !important; }
-#conversejs .rounded-bottom {
-  border-bottom-right-radius: 0.25rem !important;
-  border-bottom-left-radius: 0.25rem !important; }
-#conversejs .rounded-left {
-  border-top-left-radius: 0.25rem !important;
-  border-bottom-left-radius: 0.25rem !important; }
-#conversejs .rounded-circle {
-  border-radius: 50% !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 iframe,
-  #conversejs .embed-responsive embed,
-  #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.8571428571%; }
-#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 .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 .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 .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 .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 .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 .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: 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: sticky) {
-  #conversejs .sticky-top {
-    position: sticky;
-    top: 0;
-    z-index: 1020; } }
-#conversejs .sr-only {
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  white-space: nowrap;
-  clip-path: inset(50%);
-  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;
-  clip-path: none; }
-#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 .h-25 {
-  height: 25% !important; }
-#conversejs .h-50 {
-  height: 50% !important; }
-#conversejs .h-75 {
-  height: 75% !important; }
-#conversejs .h-100 {
-  height: 100% !important; }
-#conversejs .mw-100 {
-  max-width: 100% !important; }
-#conversejs .mh-100 {
-  max-height: 100% !important; }
-#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: 0.25rem !important; }
-#conversejs .mt-1,
-#conversejs .my-1 {
-  margin-top: 0.25rem !important; }
-#conversejs .mr-1,
-#conversejs .mx-1 {
-  margin-right: 0.25rem !important; }
-#conversejs .mb-1,
-#conversejs .my-1 {
-  margin-bottom: 0.25rem !important; }
-#conversejs .ml-1,
-#conversejs .mx-1 {
-  margin-left: 0.25rem !important; }
-#conversejs .m-2 {
-  margin: 0.5rem !important; }
-#conversejs .mt-2,
-#conversejs .my-2 {
-  margin-top: 0.5rem !important; }
-#conversejs .mr-2,
-#conversejs .mx-2 {
-  margin-right: 0.5rem !important; }
-#conversejs .mb-2,
-#conversejs .my-2 {
-  margin-bottom: 0.5rem !important; }
-#conversejs .ml-2,
-#conversejs .mx-2 {
-  margin-left: 0.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: 0.25rem !important; }
-#conversejs .pt-1,
-#conversejs .py-1 {
-  padding-top: 0.25rem !important; }
-#conversejs .pr-1,
-#conversejs .px-1 {
-  padding-right: 0.25rem !important; }
-#conversejs .pb-1,
-#conversejs .py-1 {
-  padding-bottom: 0.25rem !important; }
-#conversejs .pl-1,
-#conversejs .px-1 {
-  padding-left: 0.25rem !important; }
-#conversejs .p-2 {
-  padding: 0.5rem !important; }
-#conversejs .pt-2,
-#conversejs .py-2 {
-  padding-top: 0.5rem !important; }
-#conversejs .pr-2,
-#conversejs .px-2 {
-  padding-right: 0.5rem !important; }
-#conversejs .pb-2,
-#conversejs .py-2 {
-  padding-bottom: 0.5rem !important; }
-#conversejs .pl-2,
-#conversejs .px-2 {
-  padding-left: 0.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-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: 0.25rem !important; }
-  #conversejs .mt-sm-1,
-  #conversejs .my-sm-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-sm-1,
-  #conversejs .mx-sm-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-sm-1,
-  #conversejs .my-sm-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-sm-1,
-  #conversejs .mx-sm-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-sm-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-sm-2,
-  #conversejs .my-sm-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-sm-2,
-  #conversejs .mx-sm-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-sm-2,
-  #conversejs .my-sm-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-sm-2,
-  #conversejs .mx-sm-2 {
-    margin-left: 0.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: 0.25rem !important; }
-  #conversejs .pt-sm-1,
-  #conversejs .py-sm-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-sm-1,
-  #conversejs .px-sm-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-sm-1,
-  #conversejs .py-sm-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-sm-1,
-  #conversejs .px-sm-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-sm-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-sm-2,
-  #conversejs .py-sm-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-sm-2,
-  #conversejs .px-sm-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-sm-2,
-  #conversejs .py-sm-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-sm-2,
-  #conversejs .px-sm-2 {
-    padding-left: 0.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-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: 0.25rem !important; }
-  #conversejs .mt-md-1,
-  #conversejs .my-md-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-md-1,
-  #conversejs .mx-md-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-md-1,
-  #conversejs .my-md-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-md-1,
-  #conversejs .mx-md-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-md-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-md-2,
-  #conversejs .my-md-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-md-2,
-  #conversejs .mx-md-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-md-2,
-  #conversejs .my-md-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-md-2,
-  #conversejs .mx-md-2 {
-    margin-left: 0.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: 0.25rem !important; }
-  #conversejs .pt-md-1,
-  #conversejs .py-md-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-md-1,
-  #conversejs .px-md-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-md-1,
-  #conversejs .py-md-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-md-1,
-  #conversejs .px-md-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-md-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-md-2,
-  #conversejs .py-md-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-md-2,
-  #conversejs .px-md-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-md-2,
-  #conversejs .py-md-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-md-2,
-  #conversejs .px-md-2 {
-    padding-left: 0.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-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: 0.25rem !important; }
-  #conversejs .mt-lg-1,
-  #conversejs .my-lg-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-lg-1,
-  #conversejs .mx-lg-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-lg-1,
-  #conversejs .my-lg-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-lg-1,
-  #conversejs .mx-lg-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-lg-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-lg-2,
-  #conversejs .my-lg-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-lg-2,
-  #conversejs .mx-lg-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-lg-2,
-  #conversejs .my-lg-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-lg-2,
-  #conversejs .mx-lg-2 {
-    margin-left: 0.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: 0.25rem !important; }
-  #conversejs .pt-lg-1,
-  #conversejs .py-lg-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-lg-1,
-  #conversejs .px-lg-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-lg-1,
-  #conversejs .py-lg-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-lg-1,
-  #conversejs .px-lg-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-lg-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-lg-2,
-  #conversejs .py-lg-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-lg-2,
-  #conversejs .px-lg-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-lg-2,
-  #conversejs .py-lg-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-lg-2,
-  #conversejs .px-lg-2 {
-    padding-left: 0.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-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: 0.25rem !important; }
-  #conversejs .mt-xl-1,
-  #conversejs .my-xl-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-xl-1,
-  #conversejs .mx-xl-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-xl-1,
-  #conversejs .my-xl-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-xl-1,
-  #conversejs .mx-xl-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-xl-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-xl-2,
-  #conversejs .my-xl-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-xl-2,
-  #conversejs .mx-xl-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-xl-2,
-  #conversejs .my-xl-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-xl-2,
-  #conversejs .mx-xl-2 {
-    margin-left: 0.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: 0.25rem !important; }
-  #conversejs .pt-xl-1,
-  #conversejs .py-xl-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-xl-1,
-  #conversejs .px-xl-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-xl-1,
-  #conversejs .py-xl-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-xl-1,
-  #conversejs .px-xl-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-xl-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-xl-2,
-  #conversejs .py-xl-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-xl-2,
-  #conversejs .px-xl-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-xl-2,
-  #conversejs .py-xl-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-xl-2,
-  #conversejs .px-xl-2 {
-    padding-left: 0.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-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-justify {
-  text-align: justify !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-normal {
-  font-weight: 400 !important; }
-#conversejs .font-weight-bold {
-  font-weight: 700 !important; }
-#conversejs .font-italic {
-  font-style: italic !important; }
-#conversejs .text-white {
-  color: #fff !important; }
-#conversejs .text-primary {
-  color: #387592 !important; }
-#conversejs a.text-primary:hover, #conversejs a.text-primary:focus {
-  color: #2a576d !important; }
-#conversejs .text-secondary {
-  color: #6c757d !important; }
-#conversejs a.text-secondary:hover, #conversejs a.text-secondary:focus {
-  color: #545b62 !important; }
-#conversejs .text-success {
-  color: #3AA569 !important; }
-#conversejs a.text-success:hover, #conversejs a.text-success:focus {
-  color: #2d7f51 !important; }
-#conversejs .text-info {
-  color: #17a2b8 !important; }
-#conversejs a.text-info:hover, #conversejs a.text-info:focus {
-  color: #117a8b !important; }
-#conversejs .text-warning {
-  color: #ffc107 !important; }
-#conversejs a.text-warning:hover, #conversejs a.text-warning:focus {
-  color: #d39e00 !important; }
-#conversejs .text-danger {
-  color: #E77051 !important; }
-#conversejs a.text-danger:hover, #conversejs a.text-danger:focus {
-  color: #e14b24 !important; }
-#conversejs .text-light {
-  color: #f8f9fa !important; }
-#conversejs a.text-light:hover, #conversejs a.text-light:focus {
-  color: #dae0e5 !important; }
-#conversejs .text-dark {
-  color: #343a40 !important; }
-#conversejs a.text-dark:hover, #conversejs a.text-dark:focus {
-  color: #1d2124 !important; }
-#conversejs .text-muted {
-  color: #6c757d !important; }
-#conversejs .text-hide {
-  font: 0/0 a;
-  color: transparent;
-  text-shadow: none;
-  background-color: transparent;
-  border: 0; }
-#conversejs .visible {
-  visibility: visible !important; }
-#conversejs .invisible {
-  visibility: hidden !important; }
-
-body.reset {
-  margin: 0; }
-
-@font-face {
-  font-family: 'Converse-js';
-  src: url("../fonticons/fonts/icomoon.eot?wvi0ht");
-  src: url("../fonticons/fonts/icomoon.eot?wvi0ht#iefix") format("embedded-opentype"), url("../fonticons/fonts/icomoon.ttf?wvi0ht") format("truetype"), url("../fonticons/fonts/icomoon.woff?wvi0ht") format("woff"), url("../fonticons/fonts/icomoon.svg?wvi0ht#icomoon") format("svg");
-  font-weight: normal;
-  font-style: normal; }
-.icon-conversejs {
-  padding-right: 0.5em;
-  font-family: 'Converse-js';
-  font-size: 80%;
-  speak: none;
-  font-style: normal;
-  font-weight: normal;
-  font-variant: normal;
-  text-transform: none;
-  line-height: 1;
-  /* Better Font Rendering =========== */
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale; }
-
-.icon-conversejs:before {
-  content: "\e600"; }
-
-.converse-brand-heading {
-  font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-  font-size: 6em;
-  font-weight: normal; }
-  .converse-brand-heading .icon-conversejs {
-    font-size: 60%; }
-
-#conversejs {
-  bottom: 0;
-  height: 100%;
-  position: fixed;
-  padding-left: env(safe-area-inset-left);
-  padding-right: env(safe-area-inset-right);
-  color: #666;
-  font-family: "Helvetica", "Arial", sans-serif;
-  font-size: 16px;
-  direction: ltr;
-  z-index: 1031; }
-  #conversejs .brand-heading {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif; }
-    #conversejs .brand-heading .icon-conversejs {
-      font-size: 80%; }
-  #conversejs .popover {
-    position: fixed; }
-  #conversejs .converse-chatboxes {
-    z-index: 1031;
-    position: fixed;
-    bottom: 0;
-    height: 2.7rem;
-    right: 0; }
-  #conversejs ::-webkit-input-placeholder {
-    /* Chrome/Opera/Safari */
-    color: #A8ABA1; }
-  #conversejs ::-moz-placeholder {
-    /* Firefox 19+ */
-    color: #A8ABA1; }
-  #conversejs :-ms-input-placeholder {
-    /* IE 10+ */
-    color: #A8ABA1; }
-  #conversejs :-moz-placeholder {
-    /* Firefox 18- */
-    color: #A8ABA1; }
-  #conversejs ::placeholder {
-    color: #A8ABA1; }
-  #conversejs ::selection {
-    background-color: #DCF9F6; }
-  #conversejs ::-moz-selection {
-    background-color: #DCF9F6; }
-  @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 div, #conversejs span, #conversejs h1, #conversejs h2, #conversejs h3, #conversejs h4, #conversejs h5, #conversejs h6, #conversejs p, #conversejs blockquote,
-  #conversejs pre, #conversejs a, #conversejs em, #conversejs img, #conversejs strong, #conversejs dl, #conversejs dt, #conversejs dd, #conversejs ol, #conversejs ul, #conversejs li,
-  #conversejs fieldset, #conversejs form, #conversejs legend, #conversejs table, #conversejs caption, #conversejs tbody,
-  #conversejs tfoot, #conversejs thead, #conversejs tr, #conversejs th, #conversejs td, #conversejs article, #conversejs aside, #conversejs canvas, #conversejs details,
-  #conversejs embed, #conversejs figure, #conversejs figcaption, #conversejs footer, #conversejs header, #conversejs hgroup, #conversejs menu,
-  #conversejs nav, #conversejs output, #conversejs ruby, #conversejs section, #conversejs summary, #conversejs time, #conversejs mark, #conversejs audio, #conversejs video {
-    margin: 0;
-    padding: 0;
-    border: 0;
-    font: inherit;
-    vertical-align: baseline; }
-  #conversejs textarea,
-  #conversejs input[type=submit], #conversejs input[type=button],
-  #conversejs input[type=text], #conversejs input[type=password],
-  #conversejs button {
-    font-size: 16px;
-    padding: 0.25em;
-    min-height: 0; }
-  #conversejs strong {
-    font-weight: 700; }
-  #conversejs ol, #conversejs ul {
-    list-style: none; }
-  #conversejs li {
-    height: 10px; }
-  #conversejs ul, #conversejs ol, #conversejs dl {
-    font: inherit;
-    margin: 0; }
-  #conversejs a, #conversejs a:visited, #conversejs a:hover, #conversejs a:not([href]):not([tabindex]) {
-    text-decoration: none;
-    color: #578EA9;
-    text-shadow: none; }
-    #conversejs a.fa, #conversejs a:visited.fa, #conversejs a:hover.fa, #conversejs a:not([href]):not([tabindex]).fa {
-      color: #A8ABA1; }
-      #conversejs a.fa:hover, #conversejs a:visited.fa:hover, #conversejs a:hover.fa:hover, #conversejs a:not([href]):not([tabindex]).fa:hover {
-        color: #818479; }
-  #conversejs canvas {
-    border-radius: 4px; }
-  #conversejs .fa {
-    color: #A8ABA1; }
-  #conversejs .fa:hover {
-    color: #818479; }
-  #conversejs .modal {
-    background-color: rgba(0, 0, 0, 0.4); }
-    #conversejs .modal .modal-body p {
-      padding: 0.25rem 0; }
-  #conversejs .selected {
-    color: #578EA9 !important; }
-  #conversejs .circle {
-    border-radius: 50%; }
-  #conversejs .sidebar {
-    display: none;
-    width: 50px;
-    height: 100vh;
-    padding: 1rem 0;
-    background-color: #578EA9;
-    color: white;
-    text-align: center; }
-    #conversejs .sidebar .chatbox-btn {
-      float: none;
-      margin: 0;
-      font-size: 1.35em; }
-      #conversejs .sidebar .chatbox-btn.fa-vcard {
-        margin-top: 1em; }
-    #conversejs .sidebar .bottom {
-      position: absolute;
-      bottom: 1em; }
-  #conversejs .badge {
-    line-height: 1;
-    font-weight: normal;
-    font-size: 90%; }
-  #conversejs .fa {
-    font: normal normal normal 14px/1 ConverseFontAwesome;
-    display: inline-block;
-    font-size: inherit;
-    text-rendering: auto;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale; }
-  #conversejs .btn {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-    font-weight: normal;
-    color: #fff; }
-    #conversejs .btn .fa {
-      color: #fff;
-      margin-right: 0.5em; }
-  #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, 0.75); }
-  50% {
-    background-color: rgba(141, 216, 174, 0.5); }
-  75% {
-    background-color: rgba(141, 216, 174, 0.25); }
-  100% {
-    background-color: transparent; } }
-@-webkit-keyframes colorchange-chatmessage {
-  0% {
-    background-color: #8dd8ae; }
-  25% {
-    background-color: rgba(141, 216, 174, 0.75); }
-  50% {
-    background-color: rgba(141, 216, 174, 0.5); }
-  75% {
-    background-color: rgba(141, 216, 174, 0.25); }
-  100% {
-    background-color: transparent; } }
-@keyframes colorchange-chatmessage-muc {
-  0% {
-    background-color: #ffb5a2; }
-  25% {
-    background-color: rgba(255, 181, 162, 0.75); }
-  50% {
-    background-color: rgba(255, 181, 162, 0.5); }
-  75% {
-    background-color: rgba(255, 181, 162, 0.25); }
-  100% {
-    background-color: transparent; } }
-@-webkit-keyframes colorchange-chatmessage-muc {
-  0% {
-    background-color: #ffb5a2; }
-  25% {
-    background-color: rgba(255, 181, 162, 0.75); }
-  50% {
-    background-color: rgba(255, 181, 162, 0.5); }
-  75% {
-    background-color: rgba(255, 181, 162, 0.25); }
-  100% {
-    background-color: transparent; } }
-@keyframes fadein {
-  0% {
-    opacity: 0; }
-  100% {
-    opacity: 1; } }
-@-webkit-keyframes fadein {
-  0% {
-    opacity: 0; }
-  100% {
-    opacity: 1; } }
-  #conversejs .fade-in {
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 0.75s;
-    -moz-animation-duration: 0.75s;
-    animation-duration: 0.75s;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease; }
-  #conversejs .visible {
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 500ms;
-    -moz-animation-duration: 500ms;
-    animation-duration: 500ms;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease; }
-  #conversejs .hidden {
-    opacity: 0 !important;
-    display: none !important; }
-  #conversejs .collapsed {
-    height: 0 !important;
-    overflow: hidden !important;
-    padding: 0 !important; }
-  #conversejs .locked {
-    padding-right: 22px; }
-@-webkit-keyframes spin {
-  from {
-    -webkit-transform: rotate(0deg); }
-  to {
-    -webkit-transform: rotate(359deg); } }
-@-moz-keyframes spin {
-  from {
-    -moz-transform: rotate(0deg); }
-  to {
-    -moz-transform: rotate(359deg); } }
-@keyframes spin {
-  from {
-    -webkit-transform: rotate(0deg);
-    -moz-transform: rotate(0deg);
-    -ms-transform: rotate(0deg);
-    -o-transform: rotate(0deg);
-    transform: rotate(0deg); }
-  to {
-    -webkit-transform: rotate(359deg);
-    -moz-transform: rotate(359deg);
-    -ms-transform: rotate(359deg);
-    -o-transform: rotate(359deg);
-    transform: rotate(359deg); } }
-  #conversejs .spinner {
-    -webkit-animation: spin 2s infinite, linear;
-    -moz-animation: spin 2s infinite, linear;
-    animation: spin 2s infinite, linear;
-    display: block;
-    text-align: center;
-    margin: 2em;
-    font-size: 24px; }
-  #conversejs .left {
-    float: left; }
-  #conversejs .right {
-    float: right; }
-  #conversejs .centered {
-    text-align: center;
-    display: block;
-    margin: auto; }
-  #conversejs .hor_centered {
-    text-align: center;
-    display: block;
-    margin: 0 auto;
-    clear: both; }
-  #conversejs .error {
-    color: #A53214; }
-  #conversejs .info {
-    color: #1E9652; }
-  #conversejs .reg-feedback {
-    font-size: 85%;
-    margin-bottom: 1em; }
-  #conversejs .reg-feedback,
-  #conversejs #converse-login .conn-feedback {
-    display: block;
-    text-align: center;
-    width: 100%; }
-  #conversejs .avatar {
-    border-radius: 10%;
-    border: 1px solid lightgrey; }
-  #conversejs .activated {
-    display: block !important; }
-  #conversejs .button-primary {
-    color: white;
-    background-color: #E7A151; }
-  #conversejs .button-secondary {
-    color: white;
-    background-color: #387592; }
-  #conversejs .button-cancel {
-    color: white;
-    background-color: #666; }
-  #conversejs .chat-textarea-chatbox-selected {
-    border: 1px solid #578308;
-    margin: 0; }
-  #conversejs .chat-textarea-chatroom-selected {
-    border: 2px solid #578EA9;
-    margin: 0; }
-
-@media screen and (max-width: 575px) {
-  body .converse-brand-heading {
-    font-size: 3.75em; }
-
-  #conversejs:not(.converse-embedded) .chatbox .chat-body {
-    border-radius: 4px; }
-  #conversejs:not(.converse-embedded) .flyout {
-    border-radius: 4px; } }
-@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; } }
-body {
-  font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
-  color: #ffffff;
-  background-color: #578EA9; }
-  body .brand-heading {
-    font-size: 600%;
-    margin-left: -10%; }
-    body .brand-heading.fade-in {
-      opacity: 0;
-      /* make things invisible upon start */
-      -webkit-animation-name: fadein;
-      -moz-animation-name: fadein;
-      animation-name: fadein;
-      -webkit-animation-fill-mode: forwards;
-      -moz-animation-fill-mode: forwards;
-      animation-fill-mode: forwards;
-      -webkit-animation-duration: 0.75s;
-      -moz-animation-duration: 0.75s;
-      animation-duration: 0.75s;
-      -webkit-animation-timing-function: ease;
-      -moz-animation-timing-function: ease;
-      animation-timing-function: ease;
-      -webkit-animation-delay: 2s;
-      -moz-animation-delay: 2s;
-      animation-delay: 2s; }
-    body .brand-heading .icon-conversejs {
-      font-size: 88%; }
-  body div.content {
-    height: 100vh;
-    width: 100vw;
-    position: fixed;
-    background-color: #578EA9; }
-    body div.content .inner-content {
-      text-align: center;
-      padding: 7%;
-      padding-left: -webkit-calc(5% + 250px);
-      padding-left: calc(5% + 250px); }
-      body div.content .inner-content p.no-chats {
-        padding-right: 10%;
-        font-size: 120%; }
-
-#conversejs.fullscreen .converse-chatboxes {
-  width: 100vw;
-  right: 15px; }
-
-#conversejs form .form-group {
-  margin-bottom: 2em; }
-#conversejs form .form-check-label {
-  margin-top: 0.3rem; }
-#conversejs form .form-control::-webkit-input-placeholder {
-  /* Chrome/Opera/Safari */
-  color: #A8ABA1; }
-#conversejs form .form-control::-moz-placeholder {
-  /* Firefox 19+ */
-  color: #A8ABA1; }
-#conversejs form .form-control:-ms-input-placeholder {
-  /* IE 10+ */
-  color: #A8ABA1; }
-#conversejs form .form-control:-moz-placeholder {
-  /* Firefox 18- */
-  color: #A8ABA1; }
-#conversejs form .form-control::placeholder {
-  color: #A8ABA1; }
-#conversejs form .clear-input {
-  position: absolute;
-  right: 0.2em;
-  cursor: pointer;
-  font-size: 0.75rem; }
-#conversejs form#converse-register legend, #conversejs form#converse-login legend {
-  width: 100%;
-  text-align: center;
-  margin: 0 auto 0.5em auto; }
-#conversejs form#converse-register fieldset.buttons, #conversejs form#converse-login fieldset.buttons {
-  text-align: center; }
-#conversejs form#converse-register .login-anon, #conversejs form#converse-login .login-anon {
-  height: auto;
-  white-space: normal; }
-#conversejs form#converse-register .save-submit, #conversejs form#converse-login .save-submit {
-  color: #3AA569; }
-#conversejs form#converse-register .form-url, #conversejs form#converse-login .form-url {
-  display: block;
-  font-weight: normal;
-  margin: 1em 0; }
-#conversejs form.converse-form {
-  background: white;
-  padding: 1.5em; }
-  #conversejs form.converse-form legend {
-    color: #666;
-    font-size: 125%;
-    margin-bottom: 1.5em; }
-  #conversejs form.converse-form select,
-  #conversejs form.converse-form input[type=password],
-  #conversejs form.converse-form input[type=number],
-  #conversejs form.converse-form input[type=text] {
-    min-width: 50%; }
-  #conversejs form.converse-form input[type=text],
-  #conversejs form.converse-form input[type=password],
-  #conversejs form.converse-form input[type=number],
-  #conversejs form.converse-form input[type=button],
-  #conversejs form.converse-form input[type=submit] {
-    padding: 0.5em; }
-  #conversejs form.converse-form input[type=button],
-  #conversejs form.converse-form input[type=submit] {
-    padding-left: 1em;
-    padding-right: 1em;
-    margin: 0.5em 0;
-    border: none; }
-  #conversejs form.converse-form input.error {
-    border: 1px solid #A53214;
-    color: #666; }
-  #conversejs form.converse-form .text-muted {
-    color: #A8ABA1 !important;
-    font-size: 85%;
-    padding-top: 0.5em; }
-    #conversejs form.converse-form .text-muted a {
-      color: #79a5ba; }
-    #conversejs form.converse-form .text-muted.error {
-      color: #A53214; }
-#conversejs form.converse-centered-form {
-  text-align: center; }
-
-#conversejs #user-profile-modal label {
-  font-weight: bold; }
-
-#conversejs .flyout {
-  border-radius: 4px;
-  bottom: 6px;
-  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: 14px;
-  margin: 0 0.2em;
-  padding: 0 0 0 0.5em;
-  text-decoration: none; }
-  #conversejs .chatbox-btn:active {
-    position: relative;
-    top: 1px; }
-#conversejs .chat-head {
-  flex-wrap: nowrap;
-  color: #ffffff;
-  font-size: 100%;
-  height: 62px;
-  margin: 0;
-  padding: 0.5em;
-  position: relative; }
-  #conversejs .chat-head.chat-head-chatbox {
-    background-color: #3AA569; }
-  #conversejs .chat-head .avatar {
-    height: 36px;
-    width: 36px;
-    margin-right: 0.5em; }
-  #conversejs .chat-head .chatbox-buttons {
-    flex-direction: row-reverse;
-    position: relative;
-    width: 100%;
-    min-height: 1px;
-    padding-right: 15px;
-    padding-left: 15px;
-    flex: 0 0 25%;
-    max-width: 25%;
-    padding: 0; }
-  #conversejs .chat-head .user-custom-message {
-    color: white;
-    font-size: 75%;
-    font-style: italic;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    margin: 0;
-    padding-top: 0.2em; }
-  #conversejs .chat-head a.chatbox-btn.fa, #conversejs .chat-head a:visited.chatbox-btn.fa, #conversejs .chat-head a:hover.chatbox-btn.fa, #conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa {
-    color: white; }
-    #conversejs .chat-head a.chatbox-btn.fa.button-on:before, #conversejs .chat-head a:visited.chatbox-btn.fa.button-on:before, #conversejs .chat-head a:hover.chatbox-btn.fa.button-on:before, #conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before {
-      padding: 0.2em;
-      background-color: white;
-      color: #3AA569; }
-  #conversejs .chat-head .chatbox-btn {
-    color: white; }
-    #conversejs .chat-head .chatbox-btn.fa {
-      color: white; }
-    #conversejs .chat-head .chatbox-btn:active {
-      position: relative;
-      top: 1px; }
-    #conversejs .chat-head .chatbox-btn.button-on:before {
-      border-radius: 5%;
-      background-color: white;
-      color: #3AA569; }
-#conversejs .chatbox {
-  text-align: left;
-  margin: 0 0.5em; }
-  @media screen and (max-height: 450px) {
-    #conversejs .chatbox {
-      margin: 0;
-      width: 100%; } }
-  @media screen and (max-width: 480px) {
-    #conversejs .chatbox {
-      margin: 0;
-      width: 100%; } }
-  #conversejs .chatbox .box-flyout {
-    display: flex;
-    flex-direction: column;
-    justify-content: space-between;
-    background-color: #3AA569;
-    box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-    height: 100%;
-    min-height: 50%;
-    z-index: 1;
-    overflow-y: scroll;
-    width: 100%; }
-    @media screen and (max-height: 450px) {
-      #conversejs .chatbox .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-    @media screen and (max-width: 480px) {
-      #conversejs .chatbox .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-  #conversejs .chatbox .chat-title {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-    color: white;
-    display: block;
-    line-height: 24px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap; }
-    #conversejs .chatbox .chat-title a {
-      color: white;
-      width: 100%; }
-  #conversejs .chatbox .chat-body {
-    display: flex;
-    flex-direction: column;
-    justify-content: space-between;
-    height: 100%;
-    background-color: #3AA569;
-    border-bottom-left-radius: 4px;
-    border-bottom-right-radius: 4px;
-    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: #666;
-      font-size: 14px;
-      margin: 0;
-      padding: 5px; }
-  #conversejs .chatbox .new-msgs-indicator {
-    position: relative;
-    width: 100%;
-    cursor: pointer;
-    background-color: #3AA569;
-    color: #FCFDFD;
-    padding: 0.5em;
-    font-size: 0.9em;
-    text-align: center;
-    z-index: 20;
-    white-space: nowrap;
-    margin-bottom: 0.25em; }
-  #conversejs .chatbox .chat-content {
-    height: 100%;
-    font-size: 14px;
-    color: #666;
-    overflow-y: auto;
-    border: 0;
-    background-color: #ffffff;
-    line-height: 1.3em; }
-    #conversejs .chatbox .chat-content video {
-      width: 100%; }
-    #conversejs .chatbox .chat-content progress {
-      margin: 0.5em 0;
-      width: 100%; }
-  #conversejs .chatbox .chat-content-sendbutton {
-    height: calc(100% - 93px); }
-  #conversejs .chatbox .dropdown {
-    /* status dropdown styles */
-    background-color: #FCFDFD; }
-    #conversejs .chatbox .dropdown dd {
-      margin: 0;
-      padding: 0;
-      position: relative; }
-  #conversejs .chatbox .sendXMPPMessage {
-    -moz-background-clip: padding;
-    -webkit-background-clip: padding-box;
-    border-bottom-right-radius: 4px;
-    border-bottom-left-radius: 4px;
-    background-clip: padding-box;
-    background-color: white;
-    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 .spoiler-hint {
-      width: 100%; }
-    #conversejs .chatbox .sendXMPPMessage .chat-textarea {
-      border-top-left-radius: 0;
-      border-top-right-radius: 0;
-      border-bottom-right-radius: 4px;
-      border-bottom-left-radius: 4px;
-      padding: 0.5em;
-      width: 100%;
-      border: none;
-      min-height: 60px;
-      max-height: 400px;
-      margin-bottom: -4px; }
-      #conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler {
-        height: 42px; }
-    #conversejs .chatbox .sendXMPPMessage .send-button {
-      position: absolute;
-      left: 3px;
-      width: -webkit-calc(100% - 6px);
-      width: calc(100% - 6px);
-      background-color: #3AA569;
-      color: white;
-      font-size: 80%;
-      height: 27px;
-      bottom: -30px; }
-    #conversejs .chatbox .sendXMPPMessage .chat-toolbar {
-      box-sizing: border-box;
-      margin: 0;
-      padding: 0.25em;
-      display: block;
-      border-top: 8px solid #3AA569;
-      background-color: white;
-      color: #3AA569; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .fa, #conversejs .chatbox .sendXMPPMessage .chat-toolbar .fa:hover {
-        color: #3AA569;
-        font-size: 18px; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted {
-        color: #666; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-menu a,
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted .toolbar-menu a {
-          color: #578EA9; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unverified a,
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unverified {
-        color: #cf5300; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .private a,
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .private {
-        color: #4b7003; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .toggle-occupants {
-        float: right; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar li {
-        cursor: pointer;
-        display: inline-block;
-        list-style: none;
-        padding: 0 0.5em; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li:hover {
-          cursor: pointer; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu {
-          background-color: #fff;
-          bottom: 2rem;
-          box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
-          margin-bottom: 0;
-          min-width: 20rem;
-          position: absolute;
-          right: 0;
-          top: auto;
-          z-index: 1000; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu.otr-menu {
-            left: -6em;
-            min-width: 15rem; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu.otr-menu.show {
-              display: flex;
-              flex-direction: column; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu a {
-            color: #578EA9; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker {
-            height: 150px;
-            overflow: scroll;
-            padding: 0.5em; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li {
-            margin-left: 0;
-            cursor: pointer;
-            list-style: none;
-            position: relative; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji {
-              padding: 0.2em; }
-              #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji.picked {
-                background-color: #DCF9F6; }
-              #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji:hover {
-                background-color: #DCF9F6; }
-              #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji a {
-                font-size: 26px; }
-                #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji a:hover {
-                  color: #8f2831; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley a.toggle-smiley {
-          padding: 0; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar {
-          box-shadow: 0 -1px 1px 0 rgba(0, 0, 0, 0.4); }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker {
-            padding-top: 0.5em; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker ul {
-              display: flex;
-              flex-direction: row;
-              justify-content: space-between; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li,
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li {
-            padding: 0.2em;
-            font-size: 26px; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover {
-              background-color: #DCF9F6; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul {
-          z-index: 99; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul li {
-            display: block;
-            padding: 7px; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul li:hover {
-              background-color: #DCF9F6; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul li a {
-              display: block; }
-  #conversejs .chatbox .dragresize {
-    background: transparent;
-    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 {
-      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-fullscreen .chatbox-btn {
-  font-size: 16px; }
-#conversejs.converse-fullscreen .chat-head .chatbox-buttons {
-  flex: 0 0 25%;
-  max-width: 25%; }
-
-@media screen and (max-width: 767px) {
-  #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) .sidebar {
-    display: block; }
-  #conversejs:not(.converse-embedded) .chatbox {
-    width: calc(100% - 50px); }
-    #conversejs:not(.converse-embedded) .chatbox .row .box-flyout {
-      left: 50px;
-      bottom: 0;
-      height: 100vh;
-      box-shadow: none; } }
-#conversejs.fullscreen .chatbox-btn {
-  font-size: 18px;
-  margin: 0 0.3em; }
-#conversejs.fullscreen .flyout {
-  border-radius: 0;
-  border: 1.2em solid #3AA569;
-  border-top: 0.8em solid #3AA569;
-  bottom: 0; }
-#conversejs.fullscreen .chat-head {
-  font-size: 20px;
-  padding: 0; }
-  #conversejs.fullscreen .chat-head .user-custom-message {
-    font-size: 50%;
-    height: auto;
-    line-height: 22px; }
-#conversejs.fullscreen .chatbox {
-  width: 100%;
-  height: 100%;
-  margin: 0;
-  position: relative;
-  width: 100%;
-  min-height: 1px;
-  padding-right: 15px;
-  padding-left: 15px; }
-  @media (min-width: 768px) {
-    #conversejs.fullscreen .chatbox {
-      flex: 0 0 75%;
-      max-width: 75%; } }
-  @media (min-width: 1200px) {
-    #conversejs.fullscreen .chatbox {
-      flex: 0 0 83.3333333333%;
-      max-width: 83.3333333333%; } }
-  #conversejs.fullscreen .chatbox .box-flyout {
-    background-color: #3AA569;
-    height: 100vh;
-    width: 100%;
-    box-shadow: none; }
-  #conversejs.fullscreen .chatbox .chat-body {
-    background-color: #3AA569;
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px; }
-    #conversejs.fullscreen .chatbox .chat-body .chat-message {
-      line-height: 22px;
-      font-size: 14px; }
-      #conversejs.fullscreen .chatbox .chat-body .chat-message .chat-msg-author {
-        line-height: 22px; }
-      #conversejs.fullscreen .chatbox .chat-body .chat-message .chat-msg-content {
-        line-height: 22px; }
-        #conversejs.fullscreen .chatbox .chat-body .chat-message .chat-msg-content .emojione {
-          height: 22px;
-          margin-bottom: -5.5px; }
-  #conversejs.fullscreen .chatbox .chat-content {
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px; }
-  #conversejs.fullscreen .chatbox .chat-title {
-    font-size: 26px;
-    line-height: 30px; }
-  #conversejs.fullscreen .chatbox .sendXMPPMessage ul {
-    width: 100%; }
-  #conversejs.fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category-picker {
-    margin-right: 5em; }
-  #conversejs.fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category {
-    padding-left: 10px;
-    padding-right: 10px; }
-
-@media screen and (max-width: 767px) {
-  #conversejs:not(.converse-embedded).fullscreen .chatbox {
-    width: calc(100% - 50px); } }
-#conversejs .set-xmpp-status .fa-circle, #conversejs .xmpp-status .fa-circle, #conversejs .roster-contacts .fa-circle {
-  color: #3AA569; }
-#conversejs .set-xmpp-status .fa-minus-circle, #conversejs .xmpp-status .fa-minus-circle, #conversejs .roster-contacts .fa-minus-circle {
-  color: #E77051; }
-#conversejs .set-xmpp-status .fa-dot-circle-o, #conversejs .xmpp-status .fa-dot-circle-o, #conversejs .roster-contacts .fa-dot-circle-o {
-  color: #E7A151; }
-#conversejs .set-xmpp-status .fa-circle-o, #conversejs .xmpp-status .fa-circle-o, #conversejs .roster-contacts .fa-circle-o {
-  color: #A8ABA1; }
-#conversejs .set-xmpp-status .fa-times-circle, #conversejs .xmpp-status .fa-times-circle, #conversejs .roster-contacts .fa-times-circle {
-  color: #A8ABA1; }
-#conversejs .room-info {
-  font-size: 14px;
-  font-style: normal;
-  font-weight: normal; }
-  #conversejs .room-info li.room-info {
-    display: block;
-    margin-left: 5px; }
-  #conversejs .room-info p.room-info {
-    line-height: 22px;
-    margin: 0;
-    display: block;
-    white-space: normal; }
-#conversejs div.room-info {
-  padding: 0.3em 0;
-  clear: left;
-  width: 100%; }
-#conversejs #converse-modals .set-xmpp-status {
-  margin: 1em; }
-  #conversejs #converse-modals .set-xmpp-status .custom-control-label {
-    margin-top: 0.25em; }
-#conversejs #controlbox {
-  margin-right: 1.5em; }
-  #conversejs #controlbox .box-flyout {
-    background-color: white; }
-  #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: 0.5em; }
-  #conversejs #controlbox a.subscribe-to-user {
-    padding-left: 2em;
-    font-weight: bold; }
-  #conversejs #controlbox #converse-register {
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 0.75s;
-    -moz-animation-duration: 0.75s;
-    animation-duration: 0.75s;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease;
-    background: white; }
-    #conversejs #controlbox #converse-register .title {
-      font-weight: bold; }
-    #conversejs #controlbox #converse-register .info {
-      color: green;
-      font-size: 90%;
-      margin: 1.5em 0; }
-    #conversejs #controlbox #converse-register .form-errors {
-      color: #A53214;
-      margin: 1em 0; }
-    #conversejs #controlbox #converse-register .provider-title {
-      font-size: 26px;
-      margin: 0; }
-    #conversejs #controlbox #converse-register .provider-score {
-      width: 178px;
-      margin-bottom: 8px; }
-    #conversejs #controlbox #converse-register .form-help .url {
-      font-weight: bold;
-      color: #578EA9; }
-    #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 span, #conversejs #controlbox #converse-register .input-group input[name=username] {
-        display: table-cell;
-        text-align: left; }
-    #conversejs #controlbox #converse-register .instructions {
-      color: gray;
-      font-size: 85%; }
-      #conversejs #controlbox #converse-register .instructions:hover {
-        color: #666; }
-  #conversejs #controlbox .conn-feedback {
-    color: #578EA9; }
-    #conversejs #controlbox .conn-feedback.error {
-      color: #A53214; }
-    #conversejs #controlbox .conn-feedback p {
-      padding-bottom: 1em; }
-      #conversejs #controlbox .conn-feedback p.feedback-subject.error {
-        font-weight: bold; }
-  #conversejs #controlbox .brand-heading-container .brand-heading {
-    text-align: center; }
-  #conversejs #controlbox .brand-heading-container .brand-name {
-    font-size: 120%; }
-  #conversejs #controlbox #converse-login-panel, #conversejs #controlbox #converse-register-panel {
-    padding-top: 0;
-    padding-bottom: 0; }
-  #conversejs #controlbox #converse-login-panel {
-    flex-direction: column; }
-    #conversejs #controlbox #converse-login-panel .brand-heading {
-      color: #578EA9; }
-  #conversejs #controlbox .toggle-register-login {
-    font-weight: bold; }
-  #conversejs #controlbox .oauth-login {
-    margin-left: 0;
-    color: #666; }
-    #conversejs #controlbox .oauth-login .icon-social:before {
-      font-size: 18px; }
-  #conversejs #controlbox .controlbox-pane .userinfo {
-    padding-bottom: 1em; }
-    #conversejs #controlbox .controlbox-pane .userinfo .username {
-      margin-left: 0.5em;
-      overflow: hidden;
-      text-overflow: ellipsis; }
-    #conversejs #controlbox .controlbox-pane .userinfo .profile {
-      margin-bottom: 0.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 {
-    margin: 1em 0 0 0; }
-    #conversejs #controlbox .controlbox-section .controlbox-heading {
-      font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-      margin: 0 0 0.5em 0;
-      text-transform: uppercase; }
-  #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: #FCFDFD; }
-    #conversejs #controlbox .dropdown dd ul li:hover {
-      background-color: #DCF9F6; }
-  #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, 0.4);
-        background-color: white; }
-    #conversejs #controlbox .dropdown dd.search-xmpp li:hover {
-      background-color: #FCFDFD; }
-  #conversejs #controlbox .dropdown dt a span {
-    cursor: pointer;
-    display: block;
-    padding: 4px 7px 0 5px; }
-  #conversejs #controlbox .controlbox-panes {
-    height: 100%;
-    overflow-y: auto;
-    background-color: white; }
-  #conversejs #controlbox .controlbox-pane {
-    background-color: white;
-    border: 0;
-    font-size: 16px;
-    left: 0;
-    text-align: left;
-    overflow-x: hidden;
-    padding: 1em 0 1em 0; }
-    #conversejs #controlbox .controlbox-pane .controlbox-padded {
-      padding-left: 1em;
-      padding-right: 1em; }
-    #conversejs #controlbox .controlbox-pane .add-converse-contact {
-      margin: 0 0 0.75em 0; }
-    #conversejs #controlbox .controlbox-pane .chatbox-btn {
-      margin: 0; }
-    #conversejs #controlbox .controlbox-pane .switch-form {
-      padding: 2em 0; }
-      #conversejs #controlbox .controlbox-pane .switch-form p {
-        margin-top: 0.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 0.5em; }
-    #conversejs #controlbox .add-xmpp-contact input {
-      margin: 0 0 1rem;
-      width: 100%; }
-    #conversejs #controlbox .add-xmpp-contact button {
-      width: 100%; }
-#conversejs .toggle-controlbox {
-  text-align: center;
-  background-color: #578EA9;
-  border-top-left-radius: 5px;
-  border-top-right-radius: 5px;
-  color: #0a0a0a;
-  float: right;
-  height: 100%;
-  margin: 0 0.5em;
-  padding: 1em; }
-  #conversejs .toggle-controlbox span {
-    color: white; }
-
-@media (max-width: 767.98px) {
-  #conversejs:not(.converse-embedded) {
-    left: 0;
-    right: 0;
-    padding-left: env(safe-area-inset-left);
-    padding-right: env(safe-area-inset-right); }
-    #conversejs:not(.converse-embedded) .converse-chatboxes {
-      margin: 0 !important;
-      flex-direction: row !important;
-      justify-content: space-between; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes .converse-chatroom {
-        font-size: 14px; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes .chatbox .box-flyout {
-        top: -100vh;
-        margin-left: 15px;
-        left: 0;
-        bottom: 0;
-        border-radius: 0;
-        width: 100vw !important;
-        height: 100vh !important; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox {
-        order: 0; }
-        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .box-flyout {
-          width: 100vw !important;
-          height: 100vh !important; }
-        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .sidebar {
-          display: block; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open .chatbox:not(#controlbox) {
-        display: none; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open #controlbox .controlbox-pane {
-        display: block; } }
-#conversejs:not(.converse-fullscreen) #controlbox {
-  order: -1;
-  min-width: 250px !important;
-  width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .box-flyout {
-    min-width: 250px !important;
-    width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox:not(.logged-out) .controlbox-head {
-    height: 15px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head {
-    display: flex;
-    flex-direction: row-reverse;
-    flex-wrap: nowrap;
-    justify-content: space-between; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .brand-heading {
-      position: relative;
-      width: 100%;
-      min-height: 1px;
-      padding-right: 15px;
-      padding-left: 15px;
-      flex: 0 0 66.6666666667%;
-      max-width: 66.6666666667%;
-      color: #666;
-      font-size: 2em; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .chatbox-btn {
-      color: #578EA9;
-      margin: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register, #conversejs:not(.converse-fullscreen) #controlbox #converse-login {
-    flex: 0 0 100%;
-    max-width: 100%;
-    padding-bottom: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register .button-cancel {
-    font-size: 90%; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-panes {
-    border-radius: 4px; }
-
-#conversejs.fullscreen #controlbox {
-  position: relative;
-  width: 100%;
-  min-height: 1px;
-  padding-right: 15px;
-  padding-left: 15px;
-  margin: 0; }
-  @media (min-width: 768px) {
-    #conversejs.fullscreen #controlbox {
-      flex: 0 0 25%;
-      max-width: 25%; } }
-  @media (min-width: 1200px) {
-    #conversejs.fullscreen #controlbox {
-      flex: 0 0 16.6666666667%;
-      max-width: 16.6666666667%; } }
-  #conversejs.fullscreen #controlbox.logged-out {
-    flex: 0 0 100%;
-    max-width: 100%; }
-  #conversejs.fullscreen #controlbox .controlbox-pane {
-    border-radius: 0; }
-  #conversejs.fullscreen #controlbox .flyout {
-    border-radius: 0; }
-  #conversejs.fullscreen #controlbox #converse-login-panel {
-    border-radius: 0; }
-    #conversejs.fullscreen #controlbox #converse-login-panel .converse-form {
-      padding: 3em 2em 3em; }
-  #conversejs.fullscreen #controlbox .toggle-register-login {
-    line-height: 30px; }
-  #conversejs.fullscreen #controlbox .brand-heading-container {
-    flex: 0 0 100%;
-    max-width: 100%;
-    text-align: center; }
-    #conversejs.fullscreen #controlbox .brand-heading-container .brand-heading {
-      font-size: 150%;
-      font-size: 600%;
-      padding: 0.7em 0 0 0;
-      opacity: 0.8;
-      color: #387592; }
-    #conversejs.fullscreen #controlbox .brand-heading-container .brand-subtitle {
-      font-size: 90%;
-      padding: 0.5em; }
-    @media screen and (max-width: 480px) {
-      #conversejs.fullscreen #controlbox .brand-heading-container .brand-heading {
-        font-size: 400%; } }
-  #conversejs.fullscreen #controlbox.logged-out {
-    flex: 0 0 100%;
-    max-width: 100%;
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 0.75s;
-    -moz-animation-duration: 0.75s;
-    animation-duration: 0.75s;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease;
-    width: 100%; }
-    #conversejs.fullscreen #controlbox.logged-out .box-flyout {
-      width: 100%; }
-  #conversejs.fullscreen #controlbox .box-flyout {
-    border: 0;
-    width: 100%;
-    z-index: 1;
-    background-color: #578EA9; }
-    #conversejs.fullscreen #controlbox .box-flyout .controlbox-head {
-      display: none; }
-  #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-    position: relative;
-    width: 100%;
-    min-height: 1px;
-    padding-right: 15px;
-    padding-left: 15px;
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%;
-    margin-left: 16.6666666667%; }
-    @media (min-width: 576px) {
-      #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-        flex: 0 0 66.6666666667%;
-        max-width: 66.6666666667%;
-        margin-left: 16.6666666667%; } }
-    @media (min-width: 768px) {
-      #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-        flex: 0 0 66.6666666667%;
-        max-width: 66.6666666667%;
-        margin-left: 16.6666666667%; } }
-    @media (min-width: 992px) {
-      #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-        flex: 0 0 50%;
-        max-width: 50%;
-        margin-left: 25%; } }
-    #conversejs.fullscreen #controlbox #converse-register .title, #conversejs.fullscreen #controlbox #converse-register .instructions, #conversejs.fullscreen #controlbox #converse-login .title, #conversejs.fullscreen #controlbox #converse-login .instructions {
-      margin: 1em 0; }
-    #conversejs.fullscreen #controlbox #converse-register input[type=submit],
-    #conversejs.fullscreen #controlbox #converse-register input[type=button], #conversejs.fullscreen #controlbox #converse-login input[type=submit],
-    #conversejs.fullscreen #controlbox #converse-login input[type=button] {
-      width: auto; }
-
-#conversejs #converse-roster {
-  text-align: left;
-  width: 100%;
-  position: relative;
-  margin: 0;
-  height: 194px;
-  height: calc(~"100% - 60px - 20px");
-  padding: 0;
-  overflow: hidden;
-  height: calc(100% - 70px);
-  /* Custom addition for CSP */ }
-  #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: 0.2em; }
-    #conversejs #converse-roster .roster-filter-form span {
-      padding: 0.3em;
-      cursor: pointer; }
-    #conversejs #converse-roster .roster-filter-form .roster-filter {
-      width: 100%;
-      margin: 0.2em;
-      font-size: calc(16px - 2px); }
-    #conversejs #converse-roster .roster-filter-form .state-type {
-      font-size: calc(16px - 2px);
-      height: 30px;
-      width: 100%; }
-  #conversejs #converse-roster .roster-contacts {
-    padding: 0;
-    margin: 0 0 0.2em 0;
-    height: 100%;
-    overflow-x: hidden;
-    overflow-y: auto; }
-    #conversejs #converse-roster .roster-contacts .roster-group {
-      border: none;
-      color: #666;
-      font-weight: normal;
-      text-shadow: 0 1px 0 #FAFAFA;
-      margin: 0.75em 0 0.75em 0; }
-      #conversejs #converse-roster .roster-contacts .roster-group .group-toggle {
-        font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-        color: #666;
-        display: block;
-        width: 100%;
-        padding-top: 0;
-        padding-bottom: 0.3rem; }
-        #conversejs #converse-roster .roster-contacts .roster-group .group-toggle:hover {
-          color: #585B51; }
-      #conversejs #converse-roster .roster-contacts .roster-group li {
-        border: none;
-        clear: both;
-        color: #666;
-        display: block;
-        overflow-y: hidden;
-        text-shadow: 0 1px 0 #FAFAFA;
-        line-height: 16px;
-        width: 100%;
-        height: 2em;
-        padding-top: 0.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a {
-          line-height: 22px; }
-          #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a.fa {
-            width: 1.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact .req-contact-name {
-          padding: 0 0.2em 0 0; }
-        #conversejs #converse-roster .roster-contacts .roster-group li a:hover {
-          color: #206485; }
-        #conversejs #converse-roster .roster-contacts .roster-group li a .fa:hover {
-          color: white; }
-        #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: bold; }
-            #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: white;
-            background-color: #3AA569;
-            opacity: 1;
-            border-radius: 10%;
-            padding: 0.2em;
-            font-size: 14px; }
-          #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: 80%;
-            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 .avatar {
-            float: left;
-            display: inline-block;
-            height: 30px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.current-xmpp-contact span {
-          font-size: 16px;
-          float: left;
-          margin-right: 0.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.odd {
-          background-color: #DCEAC5;
-          /* Make this difference */ }
-        #conversejs #converse-roster .roster-contacts .roster-group li a, #conversejs #converse-roster .roster-contacts .roster-group li span {
-          display: inline-block;
-          overflow: hidden;
-          white-space: nowrap;
-          text-overflow: ellipsis; }
-        #conversejs #converse-roster .roster-contacts .roster-group li span {
-          padding: 0; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .decline-xmpp-request {
-          margin-left: 5px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .remove-xmpp-contact {
-          font-size: 10px;
-          margin: 0;
-          padding: 0;
-          width: 2em;
-          display: none; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .remove-xmpp-contact:before {
-            font-size: 16px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li:hover {
-          background-color: #eff4f7; }
-          #conversejs #converse-roster .roster-contacts .roster-group li:hover .remove-xmpp-contact {
-            display: inline-block; }
-  #conversejs #converse-roster span.pending-contact-name {
-    line-height: 22px;
-    width: 100%; }
-
-#conversejs .list-container {
-  text-align: left;
-  padding: 0.3em 0; }
-  #conversejs .list-container .rooms-toggle {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-    display: block;
-    color: #666;
-    padding: 0 0 0.5rem 0; }
-    #conversejs .list-container .rooms-toggle:hover {
-      color: #585B51; }
-  #conversejs .list-container .items-list {
-    text-align: left; }
-    #conversejs .list-container .items-list .list-item {
-      border: none;
-      clear: both;
-      color: #666;
-      display: block;
-      height: 2em;
-      overflow: hidden;
-      padding-top: 0.5em;
-      text-shadow: 0 1px 0 #FAFAFA;
-      word-wrap: break-word; }
-    #conversejs .list-container .items-list .available-chatroom:hover,
-    #conversejs .list-container .items-list .open-headline:hover,
-    #conversejs .list-container .items-list .open-chatroom:hover {
-      background-color: #eff4f7; }
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .msgs-indicator,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .msgs-indicator,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .msgs-indicator {
-      border-radius: 10%;
-      opacity: 1; }
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .available-room,
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .open-room,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .available-room,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .open-room,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .available-room,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .open-room {
-      width: 100%;
-      font-weight: bold; }
-    #conversejs .list-container .items-list .available-chatroom a:hover,
-    #conversejs .list-container .items-list .open-headline a:hover,
-    #conversejs .list-container .items-list .open-chatroom a:hover {
-      color: #206485; }
-    #conversejs .list-container .items-list .available-chatroom a.room-info:before,
-    #conversejs .list-container .items-list .open-headline a.room-info:before,
-    #conversejs .list-container .items-list .open-chatroom a.room-info:before {
-      font-size: 15px; }
-    #conversejs .list-container .items-list .available-chatroom a.open-room,
-    #conversejs .list-container .items-list .open-headline a.open-room,
-    #conversejs .list-container .items-list .open-chatroom a.open-room {
-      width: 68%;
-      float: left;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      padding-right: 0.5em; }
-    #conversejs .list-container .items-list .available-chatroom a.available-room,
-    #conversejs .list-container .items-list .open-headline a.available-room,
-    #conversejs .list-container .items-list .open-chatroom a.available-room {
-      width: 85%; }
-    #conversejs .list-container .items-list .available-chatroom .add-bookmark,
-    #conversejs .list-container .items-list .available-chatroom .remove-bookmark,
-    #conversejs .list-container .items-list .open-headline .add-bookmark,
-    #conversejs .list-container .items-list .open-headline .remove-bookmark,
-    #conversejs .list-container .items-list .open-chatroom .add-bookmark,
-    #conversejs .list-container .items-list .open-chatroom .remove-bookmark {
-      color: #A8ABA1; }
-      #conversejs .list-container .items-list .available-chatroom .add-bookmark.button-on,
-      #conversejs .list-container .items-list .available-chatroom .remove-bookmark.button-on,
-      #conversejs .list-container .items-list .open-headline .add-bookmark.button-on,
-      #conversejs .list-container .items-list .open-headline .remove-bookmark.button-on,
-      #conversejs .list-container .items-list .open-chatroom .add-bookmark.button-on,
-      #conversejs .list-container .items-list .open-chatroom .remove-bookmark.button-on {
-        color: #578EA9; }
-        #conversejs .list-container .items-list .available-chatroom .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .available-chatroom .remove-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-headline .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-headline .remove-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-chatroom .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-chatroom .remove-bookmark.button-on:hover {
-          color: #206485; }
-
-#conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room {
-  width: 80%; }
-
-#conversejs #converse-roster {
-  padding-bottom: 3em; }
-
-#conversejs.converse-embedded .add-chatroom input[type="submit"],
-#conversejs.converse-embedded .add-chatroom input[type="button"],
-#conversejs .add-chatroom input[type="submit"],
-#conversejs .add-chatroom input[type="button"] {
-  margin: 0.3em 0; }
-#conversejs.converse-embedded .chat-head-chatroom,
-#conversejs .chat-head-chatroom {
-  background-color: #E77051; }
-  #conversejs.converse-embedded .chat-head-chatroom .chatroom-description,
-  #conversejs .chat-head-chatroom .chatroom-description {
-    color: #f6ccc1;
-    font-size: 18px;
-    font-size: 70%;
-    margin-top: 3px;
-    overflow-y: hidden;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap; }
-  #conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa, #conversejs.converse-embedded .chat-head-chatroom a:visited.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 .chat-head-chatroom a.chatbox-btn.fa,
-  #conversejs .chat-head-chatroom a:visited.chatbox-btn.fa,
-  #conversejs .chat-head-chatroom a:hover.chatbox-btn.fa,
-  #conversejs .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa {
-    color: white; }
-    #conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa.button-on:before, #conversejs.converse-embedded .chat-head-chatroom a:visited.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 .chat-head-chatroom a.chatbox-btn.fa.button-on:before,
-    #conversejs .chat-head-chatroom a:visited.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 {
-      color: #E77051; }
-  #conversejs.converse-embedded .chat-head-chatroom .chatbox-btn.button-on:before,
-  #conversejs .chat-head-chatroom .chatbox-btn.button-on:before {
-    color: #E77051; }
-  #conversejs.converse-embedded .chat-head-chatroom .chat-title .chatroom-jid,
-  #conversejs .chat-head-chatroom .chat-title .chatroom-jid {
-    font-size: 14px; }
-#conversejs.converse-embedded .chatroom,
-#conversejs .chatroom {
-  width: 300px; }
-  @media screen and (max-height: 450px) {
-    #conversejs.converse-embedded .chatroom,
-    #conversejs .chatroom {
-      width: 100%; } }
-  @media screen and (max-width: 480px) {
-    #conversejs.converse-embedded .chatroom,
-    #conversejs .chatroom {
-      width: 100%; } }
-  #conversejs.converse-embedded .chatroom .box-flyout,
-  #conversejs .chatroom .box-flyout {
-    overflow-y: hidden;
-    background-color: #E77051;
-    width: 100%; }
-    @media screen and (max-height: 450px) {
-      #conversejs.converse-embedded .chatroom .box-flyout,
-      #conversejs .chatroom .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-    @media screen and (max-width: 480px) {
-      #conversejs.converse-embedded .chatroom .box-flyout,
-      #conversejs .chatroom .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-    #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body,
-    #conversejs .chatroom .box-flyout .chatroom-body {
-      flex-direction: row;
-      flex-flow: nowrap;
-      border-bottom-right-radius: 4px;
-      border-bottom-left-radius: 4px;
-      background-color: white;
-      border-top: 0;
-      width: 100%;
-      overflow: hidden; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .row,
-      #conversejs .chatroom .box-flyout .chatroom-body .row {
-        flex-direction: row; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-topic,
-      #conversejs .chatroom .box-flyout .chatroom-body .chat-topic {
-        font-weight: bold;
-        color: #E77051; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info,
-      #conversejs .chatroom .box-flyout .chatroom-body .chat-info {
-        color: #E77051;
-        line-height: normal; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info.badge,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-info.badge {
-          color: white; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .mentioned,
-      #conversejs .chatroom .box-flyout .chatroom-body .mentioned {
-        font-weight: bold; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-msg,
-      #conversejs .chatroom .box-flyout .chatroom-body .disconnect-msg {
-        padding: 2em 2em 0 2em; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area,
-      #conversejs .chatroom .box-flyout .chatroom-body .chat-area {
-        display: flex;
-        flex-direction: column;
-        word-wrap: break-word;
-        min-width: 100%; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator {
-          background-color: #E77051; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
-          height: 100%; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area.full {
-          min-width: 100%; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,
-      #conversejs .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: white;
-        border-left: 1px solid #666;
-        border-bottom-right-radius: 4px;
-        padding: 0.5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
-          font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-          padding: 0.3em 0; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features {
-          width: 100%; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature {
-            float: left;
-            margin-right: 0.5em;
-            padding-right: 0;
-            font-size: 1em;
-            cursor: help; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul {
-          padding: 0; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul li,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul li {
-            padding: .5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants ul {
-          padding: 0.5em 0 0 0;
-          margin-bottom: 0.5em;
-          overflow-x: hidden;
-          overflow-y: auto;
-          list-style: none; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list {
-            overflow-y: auto;
-            flex-basis: 0;
-            flex-grow: 1;
-            border-bottom: 1px solid lightgrey; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list {
-            padding-top: 0; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature {
-              width: 100%; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa {
-                color: #666; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li {
-            cursor: default;
-            display: block;
-            font-size: 14px;
-            overflow: hidden;
-            padding: 0.25em 0.25em 0.25em 0;
-            text-overflow: ellipsis; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa {
-              margin-right: 0.5em; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.feature,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.feature {
-              font-size: 10px; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant {
-              cursor: pointer; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters {
-                flex-wrap: nowrap;
-                min-height: 1.5em; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge {
-                margin-bottom: 0.125rem; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status {
-                display: inline-block;
-                margin: 0 0.5em 0.125em 0;
-                width: 0.5em;
-                height: 0.5em; }
-                #conversejs.converse-embedded .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 .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat {
-                  background-color: #1A9707; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd {
-                  background-color: red; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away {
-                  background-color: darkorange; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa {
-                  background-color: orange; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline {
-                  background-color: darkgrey; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container,
-      #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container {
-        background-color: white;
-        border-bottom-left-radius: 4px;
-        border-bottom-right-radius: 4px;
-        border: 0;
-        color: #666;
-        font-size: 16px;
-        height: 100%;
-        width: 100%;
-        overflow-y: auto; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message,
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message {
-          font-size: 90%;
-          color: #A53214; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form label,
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form input[type=text],
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form label,
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form input[type=text] {
-          display: block; }
-        #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],
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit] {
-          margin: 0 0.5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary,
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary {
-          background-color: #E77051; }
-  #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-toolbar,
-  #conversejs .chatroom .sendXMPPMessage .chat-toolbar {
-    background-color: white;
-    border-top: 8px solid #E77051;
-    color: #E77051; }
-    #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-toolbar .fa, #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-toolbar .fa:hover,
-    #conversejs .chatroom .sendXMPPMessage .chat-toolbar .fa,
-    #conversejs .chatroom .sendXMPPMessage .chat-toolbar .fa:hover {
-      color: #E77051; }
-  #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea,
-  #conversejs .chatroom .sendXMPPMessage .chat-textarea {
-    border-bottom-right-radius: 0; }
-  #conversejs.converse-embedded .chatroom .sendXMPPMessage .send-button,
-  #conversejs .chatroom .sendXMPPMessage .send-button {
-    background-color: #E77051; }
-  #conversejs.converse-embedded .chatroom .room-invite .invited-contact,
-  #conversejs .chatroom .room-invite .invited-contact {
-    margin: -1px 0 0 -1px;
-    width: 100%;
-    border: 1px solid #999; }
-
-#conversejs.converse-fullscreen .chat-head-chatroom,
-#conversejs.converse-mobile .chat-head-chatroom {
-  height: 62px;
-  font-size: 20px; }
-  #conversejs.converse-fullscreen .chat-head-chatroom .chat-title .chatroom-description,
-  #conversejs.converse-mobile .chat-head-chatroom .chat-title .chatroom-description {
-    font-size: 65%; }
-#conversejs.converse-fullscreen .chatroom .box-flyout,
-#conversejs.converse-mobile .chatroom .box-flyout {
-  background-color: #E77051;
-  border: 1.2em solid #E77051;
-  border-top: 0.8em solid #E77051;
-  width: 100%; }
-  #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body,
-  #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body {
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px; }
-    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chatroom-form-container,
-    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chatroom-form-container {
-      border-radius: 4px; }
-    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area,
-    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area {
-      border-top-left-radius: 4px;
-      min-width: auto; }
-      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
-      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
-        border-top-left-radius: 4px; }
-      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full,
-      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full {
-        max-width: 100%; }
-        #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-fullscreen .chatroom .box-flyout .chatroom-body .occupants,
-    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants {
-      border-top-right-radius: 4px;
-      padding: 1em; }
-      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
-      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
-        font-size: 18px; }
-      #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: 14px; }
-#conversejs.converse-fullscreen .chatroom .room-invite span .invited-contact,
-#conversejs.converse-mobile .chatroom .room-invite span .invited-contact {
-  margin: 0 0 0.5em -1px; }
-
-#conversejs .chatbox.headlines .chat-head.chat-head-chatbox {
-  background-color: #E7A151; }
-#conversejs .chatbox.headlines .chat-body {
-  background-color: #E7A151;
-  border-radius: 4px; }
-  #conversejs .chatbox.headlines .chat-body .chat-message {
-    color: #D2842B; }
-#conversejs .chatbox.headlines .chat-content {
-  height: 100%; }
-
-#conversejs.fullscreen .chatbox.headlines .box-flyout {
-  background-color: #E7A151; }
-#conversejs.fullscreen .chatbox.headlines .chat-head.chat-head-chatbox {
-  background-color: #E7A151; }
-#conversejs.fullscreen .chatbox.headlines .flyout {
-  border: 1.2em solid #E7A151;
-  border-top: 0.8em solid #E7A151; }
-
-#conversejs .message.date-separator {
-  height: 2em;
-  margin: 0;
-  position: relative;
-  text-align: center;
-  z-index: 0; }
-  #conversejs .message.date-separator .separator {
-    border: 0.5px solid #3AA569;
-    margin: 0 1em;
-    position: relative;
-    top: 1em;
-    z-index: 5; }
-  #conversejs .message.date-separator .separator-text {
-    background: white;
-    bottom: 1px;
-    color: #555;
-    display: inline-block;
-    line-height: 2em;
-    padding: 0 1em;
-    position: relative;
-    z-index: 5; }
-#conversejs .message.chat-info {
-  color: #3AA569;
-  font-size: 14px;
-  line-height: 20px;
-  padding: 0.35rem 1rem; }
-  #conversejs .message.chat-info.badge {
-    color: white; }
-  #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: #D24E2B;
-    font-weight: bold; }
-#conversejs .message .chat-image {
-  height: auto;
-  width: auto;
-  max-height: 15em;
-  max-width: 100%; }
-#conversejs .message.chat-action {
-  font-style: italic; }
-#conversejs .message.chat-msg {
-  display: flex;
-  flex-direction: row;
-  overflow: auto;
-  padding: 0.25rem 1rem; }
-  #conversejs .message.chat-msg.onload {
-    animation: colorchange-chatmessage 1s;
-    -webkit-animation: colorchange-chatmessage 1s; }
-  #conversejs .message.chat-msg:hover {
-    background-color: rgba(0, 0, 0, 0.035); }
-  #conversejs .message.chat-msg .spoiler {
-    margin-top: 0.5em; }
-  #conversejs .message.chat-msg .spoiler-hint {
-    margin-bottom: 0.5em; }
-  #conversejs .message.chat-msg .spoiler-toggle {
-    color: white; }
-    #conversejs .message.chat-msg .spoiler-toggle i {
-      color: white;
-      padding-right: 0.5em; }
-    #conversejs .message.chat-msg .spoiler-toggle:before {
-      padding-right: 0.25em;
-      whitespace: nowrap; }
-  #conversejs .message.chat-msg .chat-msg-content {
-    margin-left: 0.5rem;
-    width: 100%; }
-  #conversejs .message.chat-msg.headline .chat-msg-content {
-    margin-left: 0; }
-  #conversejs .message.chat-msg .chat-msg-text {
-    padding: 0;
-    color: #555; }
-    #conversejs .message.chat-msg .chat-msg-text a {
-      word-wrap: break-word;
-      word-break: break-all; }
-    #conversejs .message.chat-msg .chat-msg-text .emojione {
-      margin-bottom: -6px; }
-  #conversejs .message.chat-msg .chat-msg-media {
-    margin-top: 0.25rem; }
-    #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 .avatar {
-    margin-top: 0.5em;
-    height: 36px;
-    vertical-align: middle;
-    width: 36px; }
-  #conversejs .message.chat-msg .chat-msg-heading {
-    margin-top: 0.5em;
-    padding-right: 0.25rem;
-    padding-bottom: 0.25rem;
-    display: block; }
-    #conversejs .message.chat-msg .chat-msg-heading .chat-msg-author {
-      font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-      font-size: 115%; }
-      #conversejs .message.chat-msg .chat-msg-heading .chat-msg-author .badge {
-        font-size: 80%;
-        font-family: "Helvetica", "Arial", sans-serif; }
-    #conversejs .message.chat-msg .chat-msg-heading .chat-msg-time {
-      padding-left: 0.25em;
-      color: #8c8c8c; }
-  #conversejs .message.chat-msg.chat-action {
-    display: block; }
-    #conversejs .message.chat-msg.chat-action .chat-msg-heading {
-      float: left;
-      margin-top: 0;
-      padding-bottom: 0; }
-  #conversejs .message.chat-msg.chat-msg-followup .chat-msg-heading,
-  #conversejs .message.chat-msg.chat-msg-followup .avatar {
-    display: none; }
-  #conversejs .message.chat-msg.chat-msg-followup .chat-msg-content {
-    margin-left: 2.75rem; }
-#conversejs .chatroom-body .message.onload {
-  animation: colorchange-chatmessage-muc 1s;
-  -webkit-animation: colorchange-chatmessage-muc 1s; }
-#conversejs .chatroom-body .message .separator {
-  border: 0.5px solid #E77051; }
-
-#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; } }
-#converse-embedded-chat [hidden],
-#conversejs [hidden] {
-  display: none; }
-#converse-embedded-chat .visually-hidden,
-#conversejs .visually-hidden {
-  position: absolute;
-  clip: rect(0, 0, 0, 0); }
-#converse-embedded-chat .form-group .awesomplete,
-#conversejs .form-group .awesomplete {
-  width: 100%; }
-#converse-embedded-chat div.awesomplete,
-#conversejs div.awesomplete {
-  display: inline-block;
-  position: relative; }
-  #converse-embedded-chat div.awesomplete mark,
-  #conversejs div.awesomplete mark {
-    background: #FFB9A7; }
-  #converse-embedded-chat div.awesomplete > input,
-  #conversejs div.awesomplete > input {
-    display: block; }
-  #converse-embedded-chat div.awesomplete > ul,
-  #conversejs div.awesomplete > ul {
-    position: absolute;
-    left: 0;
-    right: 0;
-    z-index: 1;
-    min-width: 100%;
-    box-sizing: border-box;
-    list-style: none;
-    padding: 0;
-    border-radius: .3em;
-    margin: .2em 0 0;
-    background: rgba(255, 255, 255, 0.9);
-    background: linear-gradient(to bottom right, white, rgba(255, 255, 255, 0.8));
-    border: 1px solid rgba(0, 0, 0, 0.3);
-    box-shadow: 0.05em 0.2em 0.6em rgba(0, 0, 0, 0.2);
-    text-shadow: none; }
-    #converse-embedded-chat div.awesomplete > ul:before,
-    #conversejs div.awesomplete > ul:before {
-      content: "";
-      position: absolute;
-      top: -.43em;
-      left: 1em;
-      width: 0;
-      height: 0;
-      background: white;
-      border: inherit;
-      border-right: 0;
-      border-bottom: 0;
-      -webkit-transform: rotate(45deg);
-      transform: rotate(45deg); }
-    #converse-embedded-chat div.awesomplete > ul > li,
-    #conversejs div.awesomplete > ul > li {
-      text-overflow: ellipsis;
-      overflow-x: hidden;
-      position: relative;
-      cursor: pointer;
-      padding: 1em; }
-#converse-embedded-chat div.awesomplete > ul[hidden],
-#converse-embedded-chat div.awesomplete > ul:empty,
-#conversejs div.awesomplete > ul[hidden],
-#conversejs div.awesomplete > ul:empty {
-  display: none; }
-@supports (transform: scale(0)) {
-  #converse-embedded-chat div.awesomplete > ul,
-  #conversejs div.awesomplete > ul {
-    transition: 0.3s cubic-bezier(0.4, 0.2, 0.5, 1.4);
-    transform-origin: 1.43em -.43em; }
-  #converse-embedded-chat div.awesomplete > ul[hidden],
-  #converse-embedded-chat div.awesomplete > ul:empty,
-  #conversejs div.awesomplete > ul[hidden],
-  #conversejs div.awesomplete > ul:empty {
-    opacity: 0;
-    transform: scale(0);
-    display: block;
-    transition-timing-function: ease; } }
-#converse-embedded-chat div.awesomplete > ul > li:hover,
-#conversejs div.awesomplete > ul > li:hover {
-  background: #E77051;
-  color: white; }
-#converse-embedded-chat div.awesomplete > ul > li[aria-selected="true"],
-#conversejs div.awesomplete > ul > li[aria-selected="true"] {
-  background: #3d6d8f;
-  color: white; }
-#converse-embedded-chat div.awesomplete li:hover mark,
-#conversejs div.awesomplete li:hover mark {
-  background: #A53214;
-  color: white; }
-#converse-embedded-chat div.awesomplete li[aria-selected="true"] mark,
-#conversejs div.awesomplete li[aria-selected="true"] mark {
-  background: #3d6b00;
-  color: inherit; }
-
-/*# sourceMappingURL=inverse.css.map */

+ 21 - 2
css/website.css

@@ -117,6 +117,14 @@ a:hover, a:focus {
 .outro {
   background: url("images/bgtr.svg") top right no-repeat, url("images/bgbl.svg") bottom left no-repeat, url("images/overlay.png"), linear-gradient(45deg, #384955, #655361, #85505f); }
 
+section h2 {
+  color: #E7A151; }
+section h3 {
+  color: #89B7CD; }
+section h4 {
+  color: #5CBC86;
+  font-size: 1.5em; }
+
 .brand-heading {
   font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif;
   font-weight: normal;
@@ -181,7 +189,17 @@ a:hover, a:focus {
   -moz-animation-timing-function: linear; }
 
 .content-section {
-  padding-top: 100px; }
+  padding-top: 100px;
+  padding-top: 100px;
+  min-height: 100vh; }
+  .content-section .privacy-policy {
+    padding-top: 2em; }
+    .content-section .privacy-policy h4 {
+      padding-top: 1.5em; }
+    .content-section .privacy-policy p {
+      font-size: 1.2em;
+      padding-bottom: 0;
+      margin-bottom: 1em; }
 
 .donate-section {
   width: 100%;
@@ -194,7 +212,6 @@ a:hover, a:focus {
 
 @media (min-width: 767px) {
   .content-section {
-    padding-top: 150px;
     padding-bottom: 50px; }
 
   .donate-section {
@@ -304,6 +321,8 @@ ul.features {
   clear: both;
   font-size: 1.4em;
   padding: 2em 0 6em 0; }
+  .sponsors ul {
+    padding: 0; }
 
 .sponsors h2 {
   text-align: center; }

+ 22 - 24
dev.html

@@ -9,35 +9,33 @@
     <meta name="author" content="JC Brand" />
     <meta name="keywords" content="xmpp chat webchat converse.js" />
     <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
-    <link type="text/css" rel="stylesheet" media="screen" href="css/inverse.css" />
-    <script src="node_modules/requirejs/require.js"></script>
-    <script src="src/config.js"></script>
+    <link type="text/css" rel="stylesheet" media="screen" href="css/fullpage.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
+    <script src="dist/converse.js"></script>
 </head>
 
 <body class="reset">
 
 <script>
-    require(['converse', 'converse-omemo'], function (converse) {
-        converse.initialize({
-            auto_away: 300,
-            i18n: 'en',
-            // auto_join_rooms: [
-            //     'discuss@conference.conversejs.org',
-            //     'prosody@conference.prosody.im',
-            //     'jdev@conference.jabber.org'
-            // ],
-            // websocket_url: 'ws://chat.example.org:5280/xmpp-websocket',
-            view_mode: 'fullscreen',
-            archived_messages_page_size: '500',
-            allow_public_bookmarks: true,
-            notify_all_room_messages: [
-                'discuss@conference.conversejs.org'
-            ],
-            // bosh_service_url: 'http://chat.example.org:5280/http-bind/',
-            bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
-            message_archiving: 'always',
-            debug: true
-        });
+    converse.initialize({
+        auto_away: 300,
+        i18n: 'en',
+        // auto_join_rooms: [
+        //     'discuss@conference.conversejs.org',
+        //     'prosody@conference.prosody.im',
+        //     'jdev@conference.jabber.org'
+        // ],
+        // websocket_url: 'ws://chat.example.org:5280/xmpp-websocket',
+        view_mode: 'fullscreen',
+        archived_messages_page_size: '500',
+        allow_public_bookmarks: true,
+        notify_all_room_messages: [
+            'discuss@conference.conversejs.org'
+        ],
+        // bosh_service_url: 'http://chat.example.org:5280/http-bind/',
+        bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
+        message_archiving: 'always',
+        debug: true
     });
 </script>
 </body>

File diff suppressed because it is too large
+ 3933 - 2026
dist/converse-no-dependencies.js


File diff suppressed because it is too large
+ 5614 - 5251
dist/converse.js


+ 97 - 83
docs/source/configuration.rst

@@ -7,10 +7,10 @@ Configuration
 =============
 
 The included minified JavaScript and CSS files can be used for demoing or testing, but
-you'll want to configure *Converse.js* to suit your needs before you deploy it
+you'll want to configure *Converse* to suit your needs before you deploy it
 on your website.
 
-*Converse.js* is passed its configuration settings when you call its *initialize* method.
+*Converse* is passed its configuration settings when you call its *initialize* method.
 
 You'll most likely want to call the *initialize* method in your HTML page. For
 an example of how this is done, please see the bottom of the *./index.html* page.
@@ -18,7 +18,7 @@ an example of how this is done, please see the bottom of the *./index.html* page
 Please refer to the `Configuration settings`_ section below for info on
 all the available configuration settings.
 
-After you have configured *Converse.js*, you'll have to regenerate the minified
+After you have configured *Converse*, you'll have to regenerate the minified
 JavaScript file so that it will include the new settings. Please refer to the
 :ref:`minification` section for more info on how to do this.
 
@@ -83,7 +83,7 @@ requiring them to log in manually.
 When a BOSH session is initially created, you'll receive three tokens.
 A JID (jabber ID), SID (session ID) and RID (Request ID).
 
-Converse.js needs these tokens in order to attach to that same session.
+Converse needs these tokens in order to attach to that same session.
 
 There are two complementary configuration settings to ``prebind``.
 They are :ref:`keepalive` and `prebind_url`_.
@@ -200,7 +200,7 @@ allow_public_bookmarks
 Some XMPP servers don't support private PEP/PubSub nodes, as required for
 private bookmarks and outlined in `XEP-0223 <https://xmpp.org/extensions/xep-0223.html>`_.
 
-Even though Converse.js asks for the bookmarks to be kept private (via the
+Even though Converse asks for the bookmarks to be kept private (via the
 `<publish-options>` XML node), the server simply ignores the privacy settings
 and publishes the node contents under the default privacy setting, which makes
 the information available to all roster contacts.
@@ -376,13 +376,13 @@ For example::
 blacklisted_plugins
 -------------------
 
-* Default: ``[]`` (``['converse-minimize', 'converse-dragresize']`` for inVerse)
+* Default: ``[]``
 
 A list of plugin names that are blacklisted and will therefore not be
 initialized once ``converse.initialize`` is called, even if the same plugin is
 whitelisted.
 
-From Converse.js 3.0 onwards most of the API is available only to plugins and
+From Converse 3.0 onwards most of the API is available only to plugins and
 all plugins need to be whitelisted first.
 
 The usecase for blacklisting is generally to disable removed core plugins
@@ -495,7 +495,7 @@ connection_options
 * Default:  ``{}``
 * Type:  Object
 
-Converse.js relies on `Strophe.js <http://strophe.im>`_ to establish and
+Converse relies on `Strophe.js <http://strophe.im>`_ to establish and
 maintain a connection to the XMPP server.
 
 This option allows you to pass a map of configuration options to be passed into
@@ -672,7 +672,7 @@ geouri_regex
 Regular expression used to extract geo coordinates from links to openstreetmap.
 
 geouri_replacement
-----------------
+------------------
 
 * Default:  ``'https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2'``
 
@@ -698,7 +698,7 @@ If set to ``true``, then don't show offline users.
 hide_open_bookmarks
 -------------------
 
-* Default:  ``false`` (``true`` for inVerse).
+* Default:  ``false`` (``true`` when the ``view_mode`` is set to ``fullscreen``).
 
 This setting applies to the ``converse-bookmarks`` plugin and specfically the
 list of bookmarks shown in the ``Rooms`` tab of the control box.
@@ -711,48 +711,6 @@ Makes sense to set this to ``true`` when also using the non-core
 ``converse-roomslist`` plugin, which shows a list of currently open (i.e.
 "joined") rooms.
 
-include_offline_state
----------------------
-
-* Default: `false`
-
-Originally, converse.js included an `offline` state which the user could
-choose (along with `online`, `busy` and `away`).
-
-Eventually it was however decided to remove this state, since the `offline`
-state doesn't propagate across tabs like the others do.
-
-What's meant by "propagate across tabs", is that when you set the state to
-`offline` in one tab, and you have instances of converse.js open in other tabs
-in your browser, then those instances will not have their states changed to
-`offline` as well. For the other statees the change is however propagated.
-
-The reason for this is that according to the XMPP spec, there is no `offline`
-state. The only defined states are:
-
-* away -- The entity or resource is temporarily away.
-* chat -- The entity or resource is actively interested in chattiIng.
-* dnd -- The entity or resource is busy (dnd = "Do Not Disturb").
-* xa -- The entity or resource is away for an extended period (xa = "eXtended Away").
-
-Read the `relevant section in the XMPP spec <https://xmpp.org/rfcs/rfc6121.html#presence-syntax-children-show>`_
-for more info.
-
-What used to happen in converse.js when the `offline` state was chosen, is
-that a presence stanza with a `type` of `unavailable` was sent out.
-
-This is actually exactly what happens when you log out of converse.js as well,
-with the notable exception that in the `offline` state, the connection is not
-terminated. So you can at any time change your state to something else and
-start chatting again.
-
-This might be useful to people, however the fact that the `offline` state
-doesn't propagate across tabs means that the user experience is inconsistent,
-confusing and appears "broken".
-
-If you are however aware of this issue and still want to allow the `offline`
-state, then you can set this option to `true` to enable it.
-
 .. _`i18n`:
 
 i18n
@@ -767,7 +725,7 @@ The translations for that locale must be available in JSON format at the
 
 If an explicit locale is specified via the ``i18n`` setting and the
 translations for that locale are not found at the `locales_url``, then 
-then Converse.js will fall back to trying to determine the browser's language
+then Converse will fall back to trying to determine the browser's language
 and fetching those translations, or if that fails the default English texts
 will be used.
 
@@ -789,7 +747,7 @@ keepalive
 
 * Default:    ``true``
 
-Determines whether Converse.js will maintain the chat session across page
+Determines whether Converse will maintain the chat session across page
 loads.
 
 This setting should also be used in conjunction with ``authentication`` set to `prebind`_.
@@ -827,7 +785,7 @@ locales
         'ru', 'uk', 'zh'
     ]
 
-This setting restricts the locales that are supported by Converse.js and
+This setting restricts the locales that are supported by Converse and
 therefore what may be given as value for the :ref:`i18n` option.
 
 Any other locales will be ignored.
@@ -842,7 +800,7 @@ locales_url
 
 * Default: ``/locale/{{{locale}}}/LC_MESSAGES/converse.json``,
 
-The URL from where Converse.js should fetch translation JSON.
+The URL from where Converse should fetch translation JSON.
 
 The three curly braces ``{{{ }}}`` are
 `Mustache <https://github.com/janl/mustache.js#readme>`_-style
@@ -854,7 +812,7 @@ The variable being interpolated via the curly braces is ``locale``, which is
 the value passed in to the `i18n`_ setting, or the browser's locale or the
 default local or `en` (resolved in that order).
 
-From version 3.3.0, Converse.js no longer bundles all translations into its
+From version 3.3.0, Converse no longer bundles all translations into its
 final build file. Instead, only the relevant translations are fetched at
 runtime.
 
@@ -995,7 +953,7 @@ muc_show_join_leave
 
 * Default; ``true``
 
-Determines whether Converse.js will show info messages inside a chatroom
+Determines whether Converse will show info messages inside a chatroom
 whenever a user joins or leaves it.
 
 nickname
@@ -1028,6 +986,39 @@ This option specifies which icon is shown in HTML5 notifications, as provided
 by the ``src/converse-notification.js`` plugin.
 
 
+oauth_providers
+---------------
+
+* Default: ``[]``
+
+Allows you to specify a list of OAuth providers that the user may use to log in
+with.
+
+.. note::
+    Your XMPP server will have to support Oauth logins
+
+.. code-block:: javascript
+
+        converse.initialize({
+            oauth_providers: {
+                'github': {
+                    'client_id': '1338d9f7ff52b1309b29',
+                    'host': 'chat.example.org',
+                    'class': 'fa-github-alt',
+                    'id': 'github',
+                    'name': 'Github'
+                },
+                'twitter': {
+                    'client_id': '0332d98cff83b1999b22',
+                    'host': 'chat.example.org',
+                    'class': 'fa-twitter',
+                    'id': 'twitter',
+                    'name': 'Twitter'
+                }
+            },
+        });
+
+
 ping_interval
 -------------
 
@@ -1049,7 +1040,7 @@ play_sounds
 Plays a notification sound when you receive a personal message or when your
 nickname is mentioned in a chatroom.
 
-Inside the ``./sounds`` directory of the Converse.js repo you'll see MP3 and Ogg
+Inside the ``./sounds`` directory of the Converse repo you'll see MP3 and Ogg
 formatted sound files. We need both, because neither format is supported by all browsers.
 
 You can set the URL where the sound files are hosted with the `sounds_path`_
@@ -1089,12 +1080,12 @@ priority
 * Type:     Number
 
 Determines the priority used for presence stanzas sent out from this resource
-(i.e. this instance of Converse.js).
+(i.e. this instance of Converse).
 
 The priority of a given XMPP chat client determines the importance of its presence
 stanzas in relation to stanzas received from other clients of the same user.
 
-In Converse.js, the indicated chat status of a roster contact will be taken from the
+In Converse, the indicated chat status of a roster contact will be taken from the
 presence stanza (and associated resource) with the highest priority.
 
 If multiple resources have the same top priority, then the chat status will be
@@ -1110,6 +1101,39 @@ providers_link
 The hyperlink on the registration form which points to a directory of public
 XMPP servers.
 
+push_app_servers
+----------------
+
+* Default: ``[]``
+
+This option lets you enable or disable so-called push notification "App Servers"
+(as per `XEP-0357 <https://xmpp.org/extensions/xep-0357.html>`_).
+
+For each "App Server" an object needs to be passed in. When enabling, you need
+to specify ``jid`` and ``node`` values. You can also provide a
+``secret``, if required by your App Server.
+
+When disabling, you need to specify at least a ``jid`` and set ``disabled`` to
+``true``. This will disable notifications to all pubsub nodes on that "App
+Server". If you want to disable only a particular node, then specify a ``node``
+value as well.
+
+For example:
+
+
+.. code-block:: javascript
+
+        converse.initialize({
+            'push_app_servers':  [{
+                'jid': 'push-4@client.example',
+                'node': 'yxs32uqsflafdk3iuqo',
+                'disable': true
+            }, {
+                'jid': 'push-5@client.example',
+                'node': 'yxs32uqsflafdk3iuqo',
+            }]
+        });
+
 root
 ----
 
@@ -1150,7 +1174,7 @@ configured.
 
 .. note::
     It's currently not possible to use converse.js to assign contacts to groups.
-    Converse.js can only show users and groups that were previously configured
+    Converse can only show users and groups that were previously configured
     elsewhere.
 
 show_chatstate_notifications
@@ -1163,7 +1187,7 @@ Specifies whether chat state (online, dnd, away) HTML5 desktop notifications sho
 show_controlbox_by_default
 --------------------------
 
-* Default:  ``false`` (``true`` for inVerse)
+* Default:  ``false`` (``true`` when the ``view_mode`` is set to ``fullscreen``)
 
 The "controlbox" refers to the special chatbox containing your contacts roster,
 status widget, chatrooms and other controls.
@@ -1280,7 +1304,7 @@ See also `trusted`_.
 sticky_controlbox
 -----------------
 
-* Default: ``false`` (``true`` for inVerse).
+* Default: ``false`` (``true`` when the ``view_mode`` is set to ``fullscreen``).
 
 If set to ``true``, the control box (which includes the login, registration,
 contacts and rooms tabs) will not be closeable. It won't have a close button at
@@ -1304,10 +1328,10 @@ loaded), then an error will be raised.
 
 Otherwise a message will simply be logged and the override instruction ignored.
 
-The Converse.js plugins architecture can have an :ref:`dependencies`
+The Converse plugins architecture can have an :ref:`dependencies`
 plugin attribute. This enables you to specify an array of other plugins which
 this one depends on.
-Converse.js (more specifically, `pluggable.js <https://jcbrand.github.io/pluggable.js/>`_)
+Converse (more specifically, `pluggable.js <https://jcbrand.github.io/pluggable.js/>`_)
 will first load these dependencies before executing the plugin's overrides and
 calling its ``initialize`` method.
 
@@ -1344,7 +1368,7 @@ This setting determines whether the default value of the "This is a trusted devi
 When the current device is not trusted, then localStorage and sessionStorage
 will be cleared when the user logs out, thereby removing all cached data.
 
-Clearing the cache in this way makes Converse.js much slower when the user logs
+Clearing the cache in this way makes Converse much slower when the user logs
 in again, because all data needs to be fetch anew.
 
 See also `storage`_.
@@ -1365,7 +1389,7 @@ use_otr_by_default
 
 * Default:  ``false``
 
-If set to ``true``, Converse.js will automatically try to initiate an OTR (off-the-record)
+If set to ``true``, Converse will automatically try to initiate an OTR (off-the-record)
 encrypted chat session every time you open a chatbox.
 
 visible_toolbar_buttons
@@ -1424,7 +1448,7 @@ support.
     configuration setting).
 
 .. note::
-    Converse.js does not yet support "keepalive" with websockets.
+    Converse does not yet support "keepalive" with websockets.
 
 .. _`view_mode`:
 
@@ -1468,6 +1492,9 @@ Since version 3.3.0, the ``inverse.js`` and ``converse-mobile.js`` builds no
 longer exist. Instead the standard ``converse.js`` build is used, together with
 the appropriate ``view_mode`` value.
 
+Since verseion 4.0.0, there is now also only one CSS file to be used for all
+the different view modes, ``converse.css``.
+
 The ``converse-muc-embedded.js`` build is still kept, because it's smaller than
 ``converse.js`` due to unused code being removed. It doesn't however contain
 any new code, so the full ``converse.js`` build could be used instead, as long
@@ -1476,19 +1503,6 @@ as ``view_mode`` is set to ``embedded``.
 Furthermore, it's no longer necessary to whitelist or blacklist any plugins
 when switching view modes.
 
-.. note::
-    Although the ``view_mode`` setting has removed the need for different
-    JavaScript builds, you'll still need to use different CSS files depending
-    on the view mode.
-
-    * For ``embedded`` you need to use ``./css/converse-muc-embedded.css``
-    * For ``fullscreen`` you need ``./css/inverse.css``
-    * For ``mobile`` you need to use both ``./css/converse.css`` and ``./css/mobile.css``
-    * For ``overlayed`` this is ``./css/converse.css``
-
-    Hopefully in a future release the CSS files will be combined and you'll
-    only need ``converse.css``
-
 
 .. _`whitelisted_plugins`:
 
@@ -1500,7 +1514,7 @@ whitelisted_plugins
 A list of plugin names that are whitelisted and will therefore be
 initialized once ``converse.initialize`` is called.
 
-From Converse.js 3.0 onwards most of the API is available only to plugins and
+From Converse 3.0 onwards most of the API is available only to plugins and
 all plugins need to be whitelisted first.
 
 This is done to prevent malicious scripts from using the API to trick users or

+ 39 - 22
docs/source/events.rst

@@ -7,7 +7,7 @@
 Events and promises
 ===================
 
-Converse.js and its plugins emit various events which you can listen to via the
+Converse and its plugins emit various events which you can listen to via the
 :ref:`listen-grouping`.
 
 Some of these events are also available as `ES2015 Promises <http://es6-features.org/#PromiseUsage>`_,
@@ -294,6 +294,25 @@ Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
         // Your code here...
     });
 
+privateChatsAutoJoined
+~~~~~~~~~~~~~~~~~~~~~~
+
+Emitted once any private chats have been automatically joined as specified by
+the _`auto_join_private_chats` settings.
+
+.. code-block:: javascript
+
+    _converse.api.listen.on('privateChatsAutoJoined', function () { ... });
+
+Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_.
+
+.. code-block:: javascript
+
+    _converse.api.waitUntil('privateChatsAutoJoined').then(function () {
+        // Your code here...
+    });
+
+
 reconnecting
 ~~~~~~~~~~~~
 
@@ -311,24 +330,14 @@ have to be registered anew.
 
     _converse.api.listen.on('reconnected', function () { ... });
 
+registeredGlobalEventHandlers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-privateChatsAutoJoined
-~~~~~~~~~~~~~~~~~~~~~~
-
-Emitted once any private chats have been automatically joined as specified by
-the _`auto_join_private_chats` settings.
+Called once Converse has registered its global event handlers (for events such
+as window resize or unload).
 
-.. code-block:: javascript
-
-    _converse.api.listen.on('privateChatsAutoJoined', function () { ... });
-
-Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_.
-
-.. code-block:: javascript
-
-    _converse.api.waitUntil('privateChatsAutoJoined').then(function () {
-        // Your code here...
-    });
+Plugins can listen to this event as cue to register their own global event
+handlers.
 
 roomsAutoJoined
 ---------------
@@ -466,6 +475,14 @@ Similar to `rosterInitialized`, but instead pertaining to reconnection. This
 event indicates that the Backbone collections representing the roster and its
 groups are now again available after converse.js has reconnected.
 
+serviceDiscovered
+~~~~~~~~~~~~~~~~~
+
+When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
+
+``_converse.api.listen.on('serviceDiscovered', function (service) { ... });``
+
+
 .. _`statusInitialized`:
 
 statusInitialized
@@ -497,12 +514,12 @@ When own custom status message has changed.
 
 ``_converse.api.listen.on('statusMessageChanged', function (message) { ... });``
 
-serviceDiscovered
-~~~~~~~~~~~~~~~~~
-
-When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
+streamFeaturesAdded
+~~~~~~~~~~~~~~~~~~~
 
-``_converse.api.listen.on('serviceDiscovered', function (service) { ... });``
+Emitted as soon as Converse has processed the stream features as advertised by
+the server. If you want to check whether a stream feature is supported before
+proceeding, then you'll first want to wait for this event.
 
 windowStateChanged
 ~~~~~~~~~~~~~~~~~~

+ 9 - 12
docs/source/features.rst

@@ -19,7 +19,7 @@ and a private chat with a URL fragment such as
 Off-the-record encryption
 =========================
 
-Converse.js supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
+Converse supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
 encrypted messaging.
 
 The OTR protocol not only **encrypts your messages**, it provides ways to
@@ -38,17 +38,17 @@ secure crypto.
 For harsh but fairly valid criticism of JavaScript cryptography, read:
 `JavaScript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_.
 
-To get an idea on how this applies to OTR support in Converse.js, please read
+To get an idea on how this applies to OTR support in Converse, please read
 `my thoughts on it <https://opkode.com/media/blog/2013/11/11/conversejs-otr-support>`_.
 
 For now, suffice to say that although its useful to have OTR support in
-Converse.js in order to avoid most eavesdroppers, if you need serious
+Converse in order to avoid most eavesdroppers, if you need serious
 communications privacy, then you're much better off using native software.
 
 Notifications
 =============
 
-From version 0.8.1 Converse.js can play a sound notification when you receive a
+From version 0.8.1 Converse can play a sound notification when you receive a
 message.
 
 For more info, refer to the :ref:`play-sounds` configuration setting.
@@ -61,13 +61,10 @@ For more info, refer to the :ref:`show-desktop-notifications` configuration sett
 Multilingual Support
 ====================
 
-Converse.js is translated into multiple languages. The default build,
-``converse.min.js``, includes all languages.
-
-Languages increase the size of the Converse.js significantly.
-
-If you only need one, or a subset of the available languages, it's better to
-make a custom build which includes only those languages that you need.
+Converse is translated into multiple languages. Translations are supplied in
+JSON format and are loaded on demand. Converse will expect to find the
+translations in the ``/locales`` path of your site. This can be changed via the
+:ref:`locales-url` configuration setting.
 
 Moderating chatrooms
 ====================
@@ -103,7 +100,7 @@ Here are the different commands that may be used to moderate a chatroom:
 Passwordless login with client certificates
 ===========================================
 
-Converse.js supports the SASL-EXTERNAL authentication mechanism, which can be
+Converse supports the SASL-EXTERNAL authentication mechanism, which can be
 used together with x509 client certificates to enable passwordless login or
 even 2-factor authentication.
 

+ 2 - 10
docs/source/quickstart.rst

@@ -34,8 +34,6 @@ via the *script* and *link* tags:
     <script src="https://cdn.conversejs.org/dist/converse.min.js" charset="utf-8"></script>
 
 
-.. note:: For the fullscreen :ref:`view_mode` version of converse.js, replace ``converse.min.css`` with ``inverse.min.css``.
-
 .. note:: Instead of always loading the latest version of Converse.js via the
     CDN, it's generally better to load a specific version (preferably the
     latest one), to avoid breakage when new backwards-incompatible versions are
@@ -111,19 +109,13 @@ split up into two parts, with the UI part dropped for this build.
 Fullscreen version
 ------------------
 
-Converse.js also comes in a fullscreen version (often referred to as Inverse).
+Converse.js also comes in a fullscreen version.
 A hosted version is available online at `inverse.chat <https://inverse.chat>`_.
 
 Originally this version was available as a separate build file, but 
 as of version 4.0.0 and higher, the difference between the "overlay" and the
 "fullscreen" versions of converse.js is simply a matter of configuring the 
-:ref:`view_mode` and including the right CSS file.
-
-For the default "overlay" version, ``converse.css`` is used, and for the
-"fullscreen" version ``inverse.css`` is used.
-
-We'd like to eventually not require two different CSS files, and to allow you
-to seamlessly switch between the different view modes.
+:ref:`view_mode`.
 
 To generate the headless build, run ``make dist/converse-headless.js`` and/or 
 ``make dist/converse-headless.min.js``.

+ 3 - 2
fullscreen.html

@@ -3,11 +3,12 @@
 <head>
     <meta charset="utf-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-    <title>inVerse</title>
+    <title>Converse</title>
     <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
     <script type="text/javascript" src="inverse-analytics.js"></script>
     <noscript><p><img src="//stats.opkode.com/piwik.php?idsite=5" style="border:0;" alt="" /></p></noscript>
-    <link type="text/css" rel="stylesheet" media="screen" href="css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="css/fullpage.css" />
     <script src="dist/converse.js"></script>
 </head>
 <body class="reset">

+ 101 - 12
index.html

@@ -5,7 +5,7 @@
     <meta charset="utf-8">
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="description" content="Converse.js: An XMPP chat client which can be integrated into any website" />
+    <meta name="description" content="Converse: An XMPP chat client which can be integrated into any website" />
     <meta name="author" content="JC Brand" />
     <meta name="keywords" content="xmpp chat webchat converse.js" />
 
@@ -56,8 +56,8 @@
                     <li class="page-scroll">
                         <a href="#sponsors">Sponsor</a>
                     </li>
-                    <li>
-                        <a href="/docs/html/manual.html">User Manual</a>
+                    <li class="page-scroll">
+                        <a href="#hosting">Hosting</a>
                     </li>
                     <li>
                         <a href="/docs/html/index.html">Documentation</a>
@@ -107,7 +107,7 @@
             <div class="col-lg-8 col-lg-offset-2">
                 <h2>Converse is written in JavaScript and runs in your browser.</h2>
                 <p>You can start using it here immediately, or you can <a href="/docs/html/index.html">integrate it into your own website</a>.</p>
-                <p>Take a look at the <a href="/demo">demo page</a> for other examples of how Converse.js can be configured and used.</a>
+                <p>Take a look at the <a href="/demo">demo page</a> for other examples of how Converse can be configured and used.</a>
 
                 <p>
                     You can connect to any publically accessible <a href="http://xmpp.org" target="_blank" rel="noopener">XMPP/Jabber</a> server,
@@ -193,7 +193,7 @@
                             or <a href="https://mastodon.xyz/@jcbrand" target="_blank" rel="noopener">Mastodon</a>
                         <li>Chat with me via XMPP at <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">jc@opkode.com</a></li>
                         <li>For technical support, you can ask on <a href="http://stackoverflow.com/questions/tagged/converse.js">Stack Overflow</a>
-                        <li>The Converse.js XMPP chatroom: <a href="xmpp:discuss@conference.conversejs.org" class="xmpp JSnocheck" title="Converse.js chat room">discuss@conference.conversejs.org</a>.</li>
+                        <li>The Converse XMPP chatroom: <a href="xmpp:discuss@conference.conversejs.org" class="xmpp JSnocheck" title="Converse chat room">discuss@conference.conversejs.org</a>.</li>
                         <li>Please file bugs and feature requests on <a target="_blank" rel="noopener" href="https://github.com/jcbrand/converse.js/issues">Github</a>.</li>
                     </ul>
                 </div>
@@ -217,17 +217,19 @@
             <div class="row">
                 <div class="col-lg-8 col-lg-offset-2" style="margin-top: 3em">
                     <div class="sponsors">
-                        <h2>Converse.js is supported by:</h2>
+                        <h2>Converse is supported by:</h2>
                         <ul>
-                            <li><a href="https://www.keycdn.com/" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
-                            <li><a href="https://wikisuite.org" target="_blank" rel="noopener"><img style="height: 4em" src="/logo/wikisuite-white.png" alt="WikiSuite"></a></li>
+                            <li><a href="https://www.keycdn.com/?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
+                            <li><a href="https://wikisuite.org/?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 4em" src="/logo/wikisuite-white.png" alt="WikiSuite"></a></li>
+                            <li><a href="https://hostpresto.com/?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/hostpresto.png" alt="HostPresto"></a></li>
                         </ul>
                     </div>
 
-                    <p class="sponsors-text">Converse.js is a software commons; available at no cost to you or anyone else.
-                       Sponsorships allow us to fund further development and improvements and are greatly appreciated.
-                       If you'd like to sponsor this project, please visit <a href="https://www.patreon.com/jcbrand" target="_blank" rel="noopener">Patreon</a>
-                       or <a href="https://liberapay.com/jcbrand" target="_blank" rel="noopener">Liberapay</a>.
+                    <p class="sponsors-text">Converse is a software commons, available at no cost to you or anyone else.
+                       Sponsorships allow us to fund further development and improvements.
+                       If you'd like to sponsor this project, please visit <a href="https://www.patreon.com/jcbrand" target="_blank" rel="noopener">Patreon</a>,
+                       <a href="https://liberapay.com/jcbrand" target="_blank" rel="noopener">Liberapay</a> or
+                       <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
                     </p>
                 </div>
             </div>
@@ -235,6 +237,93 @@
     </section>
 </body>
 
+    <section class="outro content-section text-center" id="hosting">
+        <div class="container">
+            <div class="row">
+                <div class="col-lg-8 col-lg-offset-2" style="margin-top: 3em">
+                    <h2>XMPP Account Hosting</h2>
+                    <p>
+                        We provide free XMPP accounts under the domain <strong>conversejs.org</strong>.
+                        You can create an account directly through the app on
+                        this website or on <a href="https://inverse.chat" target="_blank" rel="noopener">inverse.chat</a>.
+                    </p>
+                    <p>
+                        If you're interested in professional XMPP hosting under your
+                        own domain name, please <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
+                    </p>
+
+                    <div class="privacy-policy">
+                        <h3>Privacy policy and GDPR compliance</h3>
+                        <p>
+                            This service is provided on a pro bono basis. An email
+                            address is not needed to sign up and we don't sell or
+                            monetize any of your data.
+                        </p>
+                        <h4>Sharing of data with 3rd parties</h4>
+                        <p>
+                            We don't share any of your data with 3rd parties,
+                            except when necessary to run the service. For example,
+                            when you send a message to a user on a differerent XMPP
+                            server.
+                            Your presence information (whether you're online or
+                            not) is shared with contacts that you've added from
+                            other servers.
+                        </p>
+                        <p>
+                            Users on other XMPP servers
+                            can request access to your (optionally filled-in) VCard data.
+                            You can remove your VCard data through an XMPP client.
+                            The latest version of Converse supports this, and you can
+                            <a href="https://conversejs.org/4.0.0-alpha/fullscreen.html" target="_blank" rel="noopener">use it here</a>.
+                        </p>
+                        <h4>Data storage</h4>
+                        <p>
+                            Our XMPP server runs in a Hetzner data centre in
+                            Strasbourg, France.
+                        </p>
+                        <p>
+                            Your chat messages are archived for a period of 1
+                            month, after which they are deleted.
+                        </p>
+                        <p>
+                            Currently the <strong>conversejs.org</strong> XMPP
+                            server does not support HTTP-file upload, which means
+                            that we don't host any uploaded files of users.
+                        </p>
+                        <p>
+                            During normal operations we don't log or process IP
+                            addresses, although it might be necessary in certain
+                            cases where a problem needs to be debugged (hasn't
+                            happened yet). Logs older than 6 months are deleted.
+                        </p>
+                        <h4>Data portability</h4>
+                        <p>
+                            Currently there is no standardized way to move a
+                            user account from one XMPP server to another.
+                        </p>
+                        <p>
+                            If you'd like to have a copy of your data for
+                            transferal to another account, please <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
+                        </p>
+                        <h4>Account deletion</h4>
+                        <p>
+                            Currently it's not possible to automatically delete
+                            your account via Converse, although you might be
+                            able to do so via other XMPP clients that support
+                            account deletion via
+                            <a href="https://xmpp.org/extensions/xep-0077.html" target="_blank" rel="noopener">XEP-0077</a>.
+                        </p>
+                        <p>
+                            You can always <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>
+                            and we'll delete your account manually.
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+</body>
+
 <script>
     /*
     @licstart

+ 602 - 737
locale/converse.pot

@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Converse.js 3.3.4\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-05-17 11:19+0200\n"
+"POT-Creation-Date: 2018-06-04 18:44+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,688 +17,402 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: dist/converse-no-dependencies.js:9853 dist/converse-no-dependencies.js:9882
-msgid "Download"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9872
-#, javascript-format
-msgid "Download: \"%1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9895
-msgid "Download video file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9908
-msgid "Download audio file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11229
-msgid "The connection has dropped, attempting to reconnect."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11327
-msgid "An error occurred while connecting to the chat server."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11334
-msgid "Your Jabber ID and/or password is incorrect. Please try again."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11346
-#, javascript-format
-msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11348
-msgid "The XMPP server did not offer a supported authentication mechanism"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16016
-#, javascript-format
-msgid "%1$s has invited you to join a chat room: %2$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16018
-#, javascript-format
-msgid ""
-"%1$s has invited you to join a chat room: %2$s, and left the following "
-"reason: \"%3$s\""
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16379
-#: dist/converse-no-dependencies.js:16464
-#: dist/converse-no-dependencies.js:33114
+#: dist/converse-no-dependencies.js:34242
+#: dist/converse-no-dependencies.js:34327
+#: dist/converse-no-dependencies.js:46646
 msgid "Bookmark this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16465
+#: dist/converse-no-dependencies.js:34328
 msgid "The name for this bookmark:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16466
+#: dist/converse-no-dependencies.js:34329
 msgid "Would you like this room to be automatically joined upon startup?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16467
+#: dist/converse-no-dependencies.js:34330
 msgid "What should your nickname for this room be?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16469
-#: dist/converse-no-dependencies.js:25296
-#: dist/converse-no-dependencies.js:25380
+#: dist/converse-no-dependencies.js:34332
+#: dist/converse-no-dependencies.js:42768
+#: dist/converse-no-dependencies.js:45592
+#: dist/converse-no-dependencies.js:45677
 msgid "Save"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16470
-#: dist/converse-no-dependencies.js:25376
-#: dist/converse-no-dependencies.js:32190
+#: dist/converse-no-dependencies.js:34333
+#: dist/converse-no-dependencies.js:42769
+#: dist/converse-no-dependencies.js:45673
+#: dist/converse-no-dependencies.js:51631
 msgid "Cancel"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16543
+#: dist/converse-no-dependencies.js:34406
 #, javascript-format
 msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16659
+#: dist/converse-no-dependencies.js:34522
 msgid "Sorry, something went wrong while trying to save your bookmark."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16738
-#: dist/converse-no-dependencies.js:33112
+#: dist/converse-no-dependencies.js:34601
+#: dist/converse-no-dependencies.js:46644
 msgid "Leave this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16739
+#: dist/converse-no-dependencies.js:34602
 msgid "Remove this bookmark"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16740
-#: dist/converse-no-dependencies.js:33113
+#: dist/converse-no-dependencies.js:34603
+#: dist/converse-no-dependencies.js:46645
 msgid "Unbookmark this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16741
-#: dist/converse-no-dependencies.js:28819
-#: dist/converse-no-dependencies.js:33115
+#: dist/converse-no-dependencies.js:34604
+#: dist/converse-no-dependencies.js:42041
+#: dist/converse-no-dependencies.js:46647
 msgid "Show more information on this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16744
-#: dist/converse-no-dependencies.js:28818
-#: dist/converse-no-dependencies.js:33117
+#: dist/converse-no-dependencies.js:34607
+#: dist/converse-no-dependencies.js:42040
+#: dist/converse-no-dependencies.js:46649
 msgid "Click to open this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16780
+#: dist/converse-no-dependencies.js:34643
 msgid "Click to toggle the bookmarks list"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16781
+#: dist/converse-no-dependencies.js:34644
 msgid "Bookmarks"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21217
+#: dist/converse-no-dependencies.js:35089
 msgid "Sorry, could not determine file upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21225
+#: dist/converse-no-dependencies.js:35097
 msgid "Sorry, could not determine upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21257
+#: dist/converse-no-dependencies.js:35129
 msgid "Sorry, could not succesfully upload your file."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21260
+#: dist/converse-no-dependencies.js:35132
 #, javascript-format
 msgid "Your server's response: \"%1$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21442
+#: dist/converse-no-dependencies.js:35306
 msgid "Sorry, looks like file upload is not supported by your server."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21452
+#: dist/converse-no-dependencies.js:35316
 #, javascript-format
 msgid ""
 "The size of your file, %1$s, exceeds the maximum allowed by your server, "
 "which is %2$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22197
-msgid "Show more"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22248
-msgid "Typing from another device"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22250
-msgid "is typing"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22254
-msgid "Stopped typing on the other device"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22256
-msgid "has stopped typing"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22259
-#: dist/converse-no-dependencies.js:23256
-#: dist/converse-no-dependencies.js:30521
-msgid "has gone away"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22488
+#: dist/converse-no-dependencies.js:36039
 msgid "Close this chat box"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22516
+#: dist/converse-no-dependencies.js:36067
 msgid "The User's Profile Image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22519
-#: dist/converse-no-dependencies.js:25289
-#: dist/converse-no-dependencies.js:25374
+#: dist/converse-no-dependencies.js:36070
+#: dist/converse-no-dependencies.js:45585
+#: dist/converse-no-dependencies.js:45671
 msgid "Close"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22520
-#: dist/converse-no-dependencies.js:25290
+#: dist/converse-no-dependencies.js:36071
+#: dist/converse-no-dependencies.js:45586
 msgid "Email"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22521
-#: dist/converse-no-dependencies.js:25291
+#: dist/converse-no-dependencies.js:36072
+#: dist/converse-no-dependencies.js:45587
 msgid "Full Name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22522
+#: dist/converse-no-dependencies.js:36073
 msgid "Jabber ID"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22523
-#: dist/converse-no-dependencies.js:25292
-#: dist/converse-no-dependencies.js:29617
+#: dist/converse-no-dependencies.js:36074
+#: dist/converse-no-dependencies.js:42924
+#: dist/converse-no-dependencies.js:45588
 msgid "Nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22524
+#: dist/converse-no-dependencies.js:36075
 msgid "Remove as contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22525
+#: dist/converse-no-dependencies.js:36076
 msgid "Refresh"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22526
-#: dist/converse-no-dependencies.js:25294
+#: dist/converse-no-dependencies.js:36077
+#: dist/converse-no-dependencies.js:45590
 msgid "Role"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22527
-#: dist/converse-no-dependencies.js:25297
+#: dist/converse-no-dependencies.js:36078
+#: dist/converse-no-dependencies.js:45593
 msgid "URL"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22566
-#: dist/converse-no-dependencies.js:24293
+#: dist/converse-no-dependencies.js:36117
+#: dist/converse-no-dependencies.js:48307
 msgid "Are you sure you want to remove this contact?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:25325
+#: dist/converse-no-dependencies.js:36126
+#: dist/converse-no-dependencies.js:45621
 msgid "Error"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:24301
+#: dist/converse-no-dependencies.js:36126
+#: dist/converse-no-dependencies.js:48315
 #, javascript-format
 msgid "Sorry, there was an error while trying to remove %1$s as a contact."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22629
-#: dist/converse-no-dependencies.js:22667
-#: dist/converse-no-dependencies.js:29029
+#: dist/converse-no-dependencies.js:36180
+#: dist/converse-no-dependencies.js:36218
+#: dist/converse-no-dependencies.js:42291
 msgid "You have unread messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22653
+#: dist/converse-no-dependencies.js:36204
 msgid "Hidden message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22655
+#: dist/converse-no-dependencies.js:36206
 msgid "Personal message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22662
-#: dist/converse-no-dependencies.js:29026
+#: dist/converse-no-dependencies.js:36213
+#: dist/converse-no-dependencies.js:42288
 msgid "Send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22663
+#: dist/converse-no-dependencies.js:36214
 msgid "Optional hint"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22692
+#: dist/converse-no-dependencies.js:36252
 msgid "Choose a file to send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22748
+#: dist/converse-no-dependencies.js:36308
 msgid "Click to write as a normal (non-spoiler) message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22750
+#: dist/converse-no-dependencies.js:36310
 msgid "Click to write your message as a spoiler"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22754
+#: dist/converse-no-dependencies.js:36314
 msgid "Clear all messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:36315
 msgid "Insert emojis"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22756
+#: dist/converse-no-dependencies.js:36316
 msgid "Start a call"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29265
+#: dist/converse-no-dependencies.js:36629
+#: dist/converse-no-dependencies.js:42567
 msgid "Remove messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
+#: dist/converse-no-dependencies.js:36629
 msgid "Write in the third person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29267
+#: dist/converse-no-dependencies.js:36629
+#: dist/converse-no-dependencies.js:42567
 msgid "Show this menu"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:36728
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23254
-#: dist/converse-no-dependencies.js:30519
+#: dist/converse-no-dependencies.js:36817
+#: dist/converse-no-dependencies.js:45285
 msgid "has gone offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23258
-#: dist/converse-no-dependencies.js:30523
-msgid "is busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23260
-msgid "is online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23501
-msgid "XMPP Username:"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23507
-msgid "Password:"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23509
-msgid "password"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23513
-#: dist/converse-no-dependencies.js:29643
-msgid "Submit"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23519
-msgid "Click here to log in anonymously"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23864
-msgid "This contact is busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23865
-msgid "This contact is online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23866
-msgid "This contact is offline"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23867
-msgid "This contact is unavailable"
+#: dist/converse-no-dependencies.js:36819
+#: dist/converse-no-dependencies.js:41017
+#: dist/converse-no-dependencies.js:45287
+msgid "has gone away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23868
-msgid "This contact is away for an extended period"
+#: dist/converse-no-dependencies.js:36821
+#: dist/converse-no-dependencies.js:45289
+msgid "is busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23869
-msgid "This contact is away"
+#: dist/converse-no-dependencies.js:36823
+msgid "is online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23872
-#: dist/converse-no-dependencies.js:24584
-#: dist/converse-no-dependencies.js:25680
+#: dist/converse-no-dependencies.js:37209
+#: dist/converse-no-dependencies.js:47885
+#: dist/converse-no-dependencies.js:48606
 msgid "Contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23874
-msgid "Groups"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23876
-msgid "My contacts"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23878
-msgid "Pending contacts"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23880
-msgid "Contact requests"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23882
-msgid "Ungrouped"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23925
-msgid "Contact name"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23925
-#: dist/converse-no-dependencies.js:28905
-msgid "Optional nickname"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23928
-msgid "Add a Contact"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23929
-msgid "XMPP Address"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23931
-msgid "name@example.org"
+#: dist/converse-no-dependencies.js:37447
+msgid "Username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23932
-msgid "Add"
+#: dist/converse-no-dependencies.js:37447
+msgid "user@domain"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24003
-#: dist/converse-no-dependencies.js:25917
+#: dist/converse-no-dependencies.js:37455
+#: dist/converse-no-dependencies.js:48016
 msgid "Please enter a valid XMPP address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24040
-msgid "Filter"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24041
-msgid "Filter by contact name"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24042
-msgid "Filter by group name"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24043
-msgid "Filter by status"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24044
-msgid "Any"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24045
-msgid "Unread"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24046
-#: dist/converse-no-dependencies.js:25379
-msgid "Online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24047
-msgid "Chatty"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24048
-#: dist/converse-no-dependencies.js:25375
-msgid "Busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24049
-#: dist/converse-no-dependencies.js:25373
-msgid "Away"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24050
-msgid "Extended Away"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24051
-#: dist/converse-no-dependencies.js:25378
-msgid "Offline"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24205
-#: dist/converse-no-dependencies.js:24247
-#, javascript-format
-msgid "Click to remove %1$s as a contact"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24214
-#, javascript-format
-msgid "Click to accept the contact request from %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24215
-#, javascript-format
-msgid "Click to decline the contact request from %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24246
-#, javascript-format
-msgid "Click to chat with %1$s (JID: %2$s)"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24323
-msgid "Are you sure you want to decline this contact request?"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24585
-msgid "Add a contact"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25288
-msgid "Your Profile"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25293
-msgid "XMPP Address (JID)"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25295
-msgid ""
-"Use commas to separate multiple roles. Your roles are shown next to your "
-"name on your chat messages."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25298
-msgid "Your avatar image"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25325
-msgid "Sorry, an error happened while trying to save your profile data."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25325
-msgid "You can check your browser's developer console for any error output."
+#: dist/converse-no-dependencies.js:37544
+msgid "Chat Contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25377
-msgid "Custom status"
+#: dist/converse-no-dependencies.js:37544
+msgid "Toggle chat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25381
-msgid "Away for long"
+#: dist/converse-no-dependencies.js:38122
+msgid "The connection has dropped, attempting to reconnect."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25382
-msgid "Change chat status"
+#: dist/converse-no-dependencies.js:38220
+msgid "An error occurred while connecting to the chat server."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25383
-msgid "Personal status message"
+#: dist/converse-no-dependencies.js:38227
+msgid "Your Jabber ID and/or password is incorrect. Please try again."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25427
+#: dist/converse-no-dependencies.js:38239
 #, javascript-format
-msgid "I am %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25430
-msgid "Change settings"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25431
-msgid "Click to change your chat status"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25432
-msgid "Log out"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25433
-msgid "Your profile"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25456
-msgid "Are you sure you want to log out?"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25464
-#: dist/converse-no-dependencies.js:25474
-msgid "online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25466
-msgid "busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25468
-msgid "away for long"
+msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25470
-msgid "away"
+#: dist/converse-no-dependencies.js:38241
+msgid "The XMPP server did not offer a supported authentication mechanism"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25472
-msgid "offline"
+#: dist/converse-no-dependencies.js:40963
+msgid "Show more"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25909
-msgid "Username"
+#: dist/converse-no-dependencies.js:41006
+msgid "Typing from another device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25909
-msgid "user@domain"
+#: dist/converse-no-dependencies.js:41008
+msgid "is typing"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:26003
-msgid "Chat Contacts"
+#: dist/converse-no-dependencies.js:41012
+msgid "Stopped typing on the other device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:26003
-msgid "Toggle chat"
+#: dist/converse-no-dependencies.js:41014
+msgid "has stopped typing"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27529
-#: dist/converse-no-dependencies.js:27572
+#: dist/converse-no-dependencies.js:41245
+#: dist/converse-no-dependencies.js:41288
 msgid "Minimize this chat box"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27705
+#: dist/converse-no-dependencies.js:41421
 msgid "Click to restore this chat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27892
+#: dist/converse-no-dependencies.js:41608
 msgid "Minimized"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28650
+#: dist/converse-no-dependencies.js:41937
 msgid "This room is not anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28651
+#: dist/converse-no-dependencies.js:41938
 msgid "This room now shows unavailable members"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28652
+#: dist/converse-no-dependencies.js:41939
 msgid "This room does not show unavailable members"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28653
+#: dist/converse-no-dependencies.js:41940
 msgid "The room configuration has changed"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28654
+#: dist/converse-no-dependencies.js:41941
 msgid "Room logging is now enabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28655
+#: dist/converse-no-dependencies.js:41942
 msgid "Room logging is now disabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28656
+#: dist/converse-no-dependencies.js:41943
 msgid "This room is now no longer anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28657
+#: dist/converse-no-dependencies.js:41944
 msgid "This room is now semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28658
+#: dist/converse-no-dependencies.js:41945
 msgid "This room is now fully-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28659
+#: dist/converse-no-dependencies.js:41946
 msgid "A new room has been created"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28663
+#: dist/converse-no-dependencies.js:41949
 msgid "You have been banned from this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28664
+#: dist/converse-no-dependencies.js:41950
 msgid "You have been kicked from this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28665
+#: dist/converse-no-dependencies.js:41951
 msgid "You have been removed from this room because of an affiliation change"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28666
+#: dist/converse-no-dependencies.js:41952
 msgid ""
 "You have been removed from this room because the room has changed to members-"
 "only and you're not a member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28667
+#: dist/converse-no-dependencies.js:41953
 msgid ""
 "You have been removed from this room because the MUC (Multi-user chat) "
 "service is being shut down"
@@ -714,798 +428,949 @@ msgstr ""
 #. * can then at least tell gettext to scan for it so that these
 #. * strings are picked up by the translation machinery.
 #.
-#: dist/converse-no-dependencies.js:28681
+#: dist/converse-no-dependencies.js:41966
 #, javascript-format
 msgid "%1$s has been banned"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28682
+#: dist/converse-no-dependencies.js:41967
 #, javascript-format
 msgid "%1$s's nickname has changed"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28683
+#: dist/converse-no-dependencies.js:41968
 #, javascript-format
 msgid "%1$s has been kicked out"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28684
+#: dist/converse-no-dependencies.js:41969
 #, javascript-format
 msgid "%1$s has been removed because of an affiliation change"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28685
+#: dist/converse-no-dependencies.js:41970
 #, javascript-format
 msgid "%1$s has been removed for not being a member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28689
+#: dist/converse-no-dependencies.js:41973
 #, javascript-format
 msgid "Your nickname has been automatically set to %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28690
+#: dist/converse-no-dependencies.js:41974
 #, javascript-format
 msgid "Your nickname has been changed to %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28724
-msgid "Description:"
+#: dist/converse-no-dependencies.js:41992
+msgid "Query for Chatrooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28725
-msgid "Room Address (JID):"
+#: dist/converse-no-dependencies.js:41993
+msgid "Server address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28726
-msgid "Occupants:"
+#: dist/converse-no-dependencies.js:41994
+msgid "Show rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28727
-msgid "Features:"
+#: dist/converse-no-dependencies.js:41995
+msgid "conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28728
-msgid "Requires authentication"
+#: dist/converse-no-dependencies.js:42053
+msgid "No rooms found"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28729
-#: dist/converse-no-dependencies.js:30122
-msgid "Hidden"
+#: dist/converse-no-dependencies.js:42070
+msgid "Rooms found:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28730
-msgid "Requires an invitation"
+#: dist/converse-no-dependencies.js:42122
+msgid "Enter a new Chatroom"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28731
-#: dist/converse-no-dependencies.js:30125
-msgid "Moderated"
+#: dist/converse-no-dependencies.js:42123
+msgid "Room address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28732
-#: dist/converse-no-dependencies.js:30126
-msgid "Non-anonymous"
+#: dist/converse-no-dependencies.js:42124
+#: dist/converse-no-dependencies.js:47938
+msgid "Optional nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28733
-msgid "Open room"
+#: dist/converse-no-dependencies.js:42125
+msgid "name@conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28734
-msgid "Permanent room"
+#: dist/converse-no-dependencies.js:42126
+msgid "Join"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28735
-#: dist/converse-no-dependencies.js:30130
-msgid "Public"
+#: dist/converse-no-dependencies.js:42169
+msgid "Description:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28736
-#: dist/converse-no-dependencies.js:30131
-msgid "Semi-anonymous"
+#: dist/converse-no-dependencies.js:42170
+msgid "Features:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28737
-msgid "Temporary room"
+#: dist/converse-no-dependencies.js:42171
+#: dist/converse-no-dependencies.js:43424
+msgid "Hidden"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28738
-#: dist/converse-no-dependencies.js:30133
-msgid "Unmoderated"
+#: dist/converse-no-dependencies.js:42172
+#: dist/converse-no-dependencies.js:43427
+msgid "Moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28777
-msgid "Query for Chatrooms"
+#: dist/converse-no-dependencies.js:42173
+#: dist/converse-no-dependencies.js:43428
+msgid "Non-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28778
-msgid "Server address"
+#: dist/converse-no-dependencies.js:42174
+msgid "Online users:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28779
-msgid "Show rooms"
+#: dist/converse-no-dependencies.js:42175
+msgid "Open room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28780
-msgid "conference.example.org"
+#: dist/converse-no-dependencies.js:42176
+msgid "Permanent room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28833
-msgid "No rooms found"
+#: dist/converse-no-dependencies.js:42177
+#: dist/converse-no-dependencies.js:43432
+msgid "Public"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28850
-msgid "Rooms found:"
+#: dist/converse-no-dependencies.js:42178
+msgid "Requires authentication"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28903
-msgid "Enter a new Chatroom"
+#: dist/converse-no-dependencies.js:42179
+msgid "Requires an invitation"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28904
-msgid "Room address"
+#: dist/converse-no-dependencies.js:42180
+#: dist/converse-no-dependencies.js:43433
+msgid "Semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28906
-msgid "name@conference.example.org"
+#: dist/converse-no-dependencies.js:42181
+msgid "Temporary room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28907
-msgid "Join"
+#: dist/converse-no-dependencies.js:42182
+#: dist/converse-no-dependencies.js:43435
+msgid "Unmoderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29025
+#: dist/converse-no-dependencies.js:42287
 msgid "Message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29058
+#: dist/converse-no-dependencies.js:42322
 #, javascript-format
 msgid "%1$s is no longer a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29061
+#: dist/converse-no-dependencies.js:42326
 #, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:42330
 #, javascript-format
 msgid "%1$s has been muted"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29067
+#: dist/converse-no-dependencies.js:42334
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29077
+#: dist/converse-no-dependencies.js:42342
 msgid "Close and leave this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29078
+#: dist/converse-no-dependencies.js:42343
 msgid "Configure this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29122
+#: dist/converse-no-dependencies.js:42383
 msgid "Hide the list of occupants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29206
+#: dist/converse-no-dependencies.js:42499
 #, javascript-format
 msgid ""
 "Error: the \"%1$s\" command takes two arguments, the user's nickname and "
 "optionally a reason."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29218
+#: dist/converse-no-dependencies.js:42508
 msgid ""
 "Sorry, an error happened while running the command. Check your browser's "
 "developer console for details."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29263
+#: dist/converse-no-dependencies.js:42567
 msgid "Change user's affiliation to admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29264
+#: dist/converse-no-dependencies.js:42567
 msgid "Ban user from room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29266
+#: dist/converse-no-dependencies.js:42567
 msgid "Change user role to participant"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29268
+#: dist/converse-no-dependencies.js:42567
 msgid "Kick user from room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29269
+#: dist/converse-no-dependencies.js:42567
 msgid "Write in 3rd person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29270
+#: dist/converse-no-dependencies.js:42567
 msgid "Grant membership to a user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29271
+#: dist/converse-no-dependencies.js:42567
 msgid "Remove user's ability to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29272
+#: dist/converse-no-dependencies.js:42567
 msgid "Change your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29273
+#: dist/converse-no-dependencies.js:42567
 msgid "Grant moderator role to user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29274
+#: dist/converse-no-dependencies.js:42567
 msgid "Grant ownership of this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29275
+#: dist/converse-no-dependencies.js:42567
 msgid "Revoke user's membership"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29276
+#: dist/converse-no-dependencies.js:42567
 msgid "Set room subject"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29277
+#: dist/converse-no-dependencies.js:42567
 msgid "Set room subject (alias for /subject)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29278
+#: dist/converse-no-dependencies.js:42567
 msgid "Allow muted user to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29590
+#: dist/converse-no-dependencies.js:42897
 msgid ""
 "The nickname you chose is reserved or currently in use, please choose a "
 "different one."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29616
+#: dist/converse-no-dependencies.js:42923
 msgid "Please choose your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29618
+#: dist/converse-no-dependencies.js:42925
 msgid "Enter room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29641
+#: dist/converse-no-dependencies.js:42946
 msgid "This chatroom requires a password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29642
+#: dist/converse-no-dependencies.js:42947
 msgid "Password: "
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29740
+#: dist/converse-no-dependencies.js:42948
+msgid "Submit"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:43062
 #, javascript-format
 msgid "This action was done by %1$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29743
-#: dist/converse-no-dependencies.js:29759
+#: dist/converse-no-dependencies.js:43066
+#: dist/converse-no-dependencies.js:43083
 #, javascript-format
 msgid "The reason given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29781
+#: dist/converse-no-dependencies.js:43104
 #, javascript-format
 msgid "%1$s has left and re-entered the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29786
+#: dist/converse-no-dependencies.js:43110
 #, javascript-format
 msgid "%1$s has entered the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29788
+#: dist/converse-no-dependencies.js:43112
 #, javascript-format
 msgid "%1$s has entered the room. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29818
+#: dist/converse-no-dependencies.js:43143
 #, javascript-format
 msgid "%1$s has entered and left the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29820
+#: dist/converse-no-dependencies.js:43145
 #, javascript-format
 msgid "%1$s has entered and left the room. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29832
+#: dist/converse-no-dependencies.js:43158
 #, javascript-format
 msgid "%1$s has left the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29834
+#: dist/converse-no-dependencies.js:43160
 #, javascript-format
 msgid "%1$s has left the room. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29877
+#: dist/converse-no-dependencies.js:43206
 msgid "You are not on the member list of this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29879
+#: dist/converse-no-dependencies.js:43208
 msgid "You have been banned from this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29883
+#: dist/converse-no-dependencies.js:43212
 msgid "No nickname was specified."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29887
+#: dist/converse-no-dependencies.js:43216
 msgid "You are not allowed to create new rooms."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29889
+#: dist/converse-no-dependencies.js:43218
 msgid "Your nickname doesn't conform to this room's policies."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29893
+#: dist/converse-no-dependencies.js:43222
 msgid "This room does not (yet) exist."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29895
+#: dist/converse-no-dependencies.js:43224
 msgid "This room has reached its maximum number of occupants."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29950
+#: dist/converse-no-dependencies.js:43274
 #, javascript-format
 msgid "Topic set by %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29981
+#: dist/converse-no-dependencies.js:43297
 msgid "Chatrooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29982
+#: dist/converse-no-dependencies.js:43298
 msgid "Add a new room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29983
+#: dist/converse-no-dependencies.js:43299
 msgid "Query for rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30022
+#: dist/converse-no-dependencies.js:43337
 #, javascript-format
 msgid "Click to mention %1$s in your message."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30023
+#: dist/converse-no-dependencies.js:43338
 msgid "This user is a moderator."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30024
+#: dist/converse-no-dependencies.js:43339
 msgid "This user can send messages in this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30025
+#: dist/converse-no-dependencies.js:43340
 msgid "This user can NOT send messages in this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30026
+#: dist/converse-no-dependencies.js:43341
 msgid "Moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30027
+#: dist/converse-no-dependencies.js:43342
 msgid "Visitor"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30028
+#: dist/converse-no-dependencies.js:43343
 msgid "Owner"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30029
+#: dist/converse-no-dependencies.js:43344
 msgid "Member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30030
+#: dist/converse-no-dependencies.js:43345
 msgid "Admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30082
+#: dist/converse-no-dependencies.js:43387
 msgid "Occupants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30102
-#: dist/converse-no-dependencies.js:30209
+#: dist/converse-no-dependencies.js:43404
+#: dist/converse-no-dependencies.js:43511
 msgid "Invite"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30121
+#: dist/converse-no-dependencies.js:43423
 msgid "Features"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30123
+#: dist/converse-no-dependencies.js:43425
 msgid "Message archiving"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30124
+#: dist/converse-no-dependencies.js:43426
 msgid "Members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30127
+#: dist/converse-no-dependencies.js:43429
 msgid "Open"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30128
+#: dist/converse-no-dependencies.js:43430
 msgid "Password protected"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30129
+#: dist/converse-no-dependencies.js:43431
 msgid "Persistent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30132
+#: dist/converse-no-dependencies.js:43434
 msgid "Temporary"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30134
+#: dist/converse-no-dependencies.js:43436
 msgid "No password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30135
+#: dist/converse-no-dependencies.js:43437
 msgid "This room is not publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30136
+#: dist/converse-no-dependencies.js:43438
 msgid "Messages are archived on the server"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30137
+#: dist/converse-no-dependencies.js:43439
 msgid "This room is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30138
+#: dist/converse-no-dependencies.js:43440
 msgid "This room is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30139
+#: dist/converse-no-dependencies.js:43441
 msgid "All other room occupants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30140
+#: dist/converse-no-dependencies.js:43442
 msgid "Anyone can join this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30141
+#: dist/converse-no-dependencies.js:43443
 msgid "This room requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30142
+#: dist/converse-no-dependencies.js:43444
 msgid "This room persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30143
+#: dist/converse-no-dependencies.js:43445
 msgid "This room is publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30144
+#: dist/converse-no-dependencies.js:43446
 msgid "Only moderators can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30145
+#: dist/converse-no-dependencies.js:43447
 msgid "This room will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30146
+#: dist/converse-no-dependencies.js:43448
 msgid "This room is not being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30147
+#: dist/converse-no-dependencies.js:43449
 msgid "This room does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30187
+#: dist/converse-no-dependencies.js:43488
 #, javascript-format
 msgid ""
 "You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
 "include a message, explaining the reason for the invitation."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30208
+#: dist/converse-no-dependencies.js:43510
 msgid "Please enter a valid XMPP username"
 msgstr ""
 
+#: dist/converse-no-dependencies.js:44865
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:44867
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
+msgstr ""
+
 #. workaround for Prosody which doesn't give type "headline"
-#: dist/converse-no-dependencies.js:30469
-#: dist/converse-no-dependencies.js:30475
+#: dist/converse-no-dependencies.js:45235
+#: dist/converse-no-dependencies.js:45241
 #, javascript-format
 msgid "Notification from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30477
-#: dist/converse-no-dependencies.js:30488
-#: dist/converse-no-dependencies.js:30491
+#: dist/converse-no-dependencies.js:45243
+#: dist/converse-no-dependencies.js:45254
+#: dist/converse-no-dependencies.js:45257
 #, javascript-format
 msgid "%1$s says"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30525
+#: dist/converse-no-dependencies.js:45291
 msgid "has come online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30542
+#: dist/converse-no-dependencies.js:45308
 msgid "wants to be your contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30824
-msgid "Re-establishing encrypted session"
+#: dist/converse-no-dependencies.js:45584
+msgid "Your Profile"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45589
+msgid "XMPP Address (JID)"
 msgstr ""
 
-#. We need to generate a new key and instance tag
-#: dist/converse-no-dependencies.js:30835
-msgid "Generating private key."
+#: dist/converse-no-dependencies.js:45591
+msgid ""
+"Use commas to separate multiple roles. Your roles are shown next to your "
+"name on your chat messages."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30835
-msgid "Your browser might become unresponsive."
+#: dist/converse-no-dependencies.js:45594
+msgid "Your avatar image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30878
-#, javascript-format
-msgid ""
-"Authentication request from %1$s\n"
-"\n"
-"Your chat contact is attempting to verify your identity, by asking you the "
-"question below.\n"
-"\n"
-"%2$s"
+#: dist/converse-no-dependencies.js:45621
+msgid "Sorry, an error happened while trying to save your profile data."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30887
-msgid "Could not verify this user's identify."
+#: dist/converse-no-dependencies.js:45621
+msgid "You can check your browser's developer console for any error output."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30941
-msgid "Exchanging private key with contact."
+#: dist/converse-no-dependencies.js:45670
+#: dist/converse-no-dependencies.js:48062
+msgid "Away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31038
-msgid "Your messages are not encrypted anymore"
+#: dist/converse-no-dependencies.js:45672
+#: dist/converse-no-dependencies.js:48061
+msgid "Busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31040
-msgid ""
-"Your messages are now encrypted but your contact's identity has not been "
-"verified."
+#: dist/converse-no-dependencies.js:45674
+msgid "Custom status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31042
-msgid "Your contact's identify has been verified."
+#: dist/converse-no-dependencies.js:45675
+#: dist/converse-no-dependencies.js:48064
+msgid "Offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31044
-msgid "Your contact has ended encryption on their end, you should do the same."
+#: dist/converse-no-dependencies.js:45676
+#: dist/converse-no-dependencies.js:48059
+msgid "Online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31054
-msgid "Your message could not be sent"
+#: dist/converse-no-dependencies.js:45678
+msgid "Away for long"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31056
-msgid "We received an unencrypted message"
+#: dist/converse-no-dependencies.js:45679
+msgid "Change chat status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31058
-msgid "We received an unreadable encrypted message"
+#: dist/converse-no-dependencies.js:45680
+msgid "Personal status message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31084
+#: dist/converse-no-dependencies.js:45724
 #, javascript-format
-msgid ""
-"Here are the fingerprints, please confirm them with %1$s, outside of this "
-"chat.\n"
-"\n"
-"Fingerprint for you, %2$s: %3$s\n"
-"\n"
-"Fingerprint for %1$s: %4$s\n"
-"\n"
-"If you have confirmed that the fingerprints match, click OK, otherwise click "
-"Cancel."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:31096
-msgid ""
-"You will be prompted to provide a security question and then an answer to "
-"that question.\n"
-"\n"
-"Your contact will then be prompted the same question and if they type the "
-"exact same answer (case sensitive), their identity will be verified."
+msgid "I am %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31097
-msgid "What is your security question?"
+#: dist/converse-no-dependencies.js:45727
+msgid "Change settings"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31100
-msgid "What is the answer to the security question?"
+#: dist/converse-no-dependencies.js:45728
+msgid "Click to change your chat status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31104
-msgid "Invalid authentication scheme provided"
+#: dist/converse-no-dependencies.js:45729
+msgid "Log out"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31121
-msgid "Your messages are not encrypted. Click here to enable OTR encryption."
+#: dist/converse-no-dependencies.js:45730
+msgid "Your profile"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31123
-msgid "Your messages are encrypted, but your contact has not been verified."
+#: dist/converse-no-dependencies.js:45753
+msgid "Are you sure you want to log out?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31125
-msgid "Your messages are encrypted and your contact verified."
+#: dist/converse-no-dependencies.js:45761
+#: dist/converse-no-dependencies.js:45771
+msgid "online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31127
-msgid ""
-"Your contact has closed their end of the private session, you should do the "
-"same"
+#: dist/converse-no-dependencies.js:45763
+msgid "busy"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45765
+msgid "away for long"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45767
+msgid "away"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45769
+msgid "offline"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45923
+msgid " e.g. conversejs.org"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45970
+msgid "Fetch registration form"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45971
+msgid "Tip: A list of public XMPP providers is available"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31141
-msgid "End encrypted conversation"
+#: dist/converse-no-dependencies.js:45972
+msgid "here"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31142
-msgid "Refresh encrypted conversation"
+#: dist/converse-no-dependencies.js:46020
+msgid "Sorry, we're unable to connect to your chosen provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31143
-msgid "Start encrypted conversation"
+#: dist/converse-no-dependencies.js:46036
+msgid ""
+"Sorry, the given provider does not support in band account registration. "
+"Please try with a different provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31144
-msgid "Verify with fingerprints"
+#: dist/converse-no-dependencies.js:46060
+#, javascript-format
+msgid ""
+"Something went wrong while establishing a connection with \"%1$s\". Are you "
+"sure it exists?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31145
-msgid "Verify with SMP"
+#: dist/converse-no-dependencies.js:46223
+msgid "Now logging you in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31146
-msgid "What's this?"
+#: dist/converse-no-dependencies.js:46227
+msgid "Registered successfully"
 msgstr ""
 
-#. Translation aware constants
-#. ---------------------------
-#. We can only call the __ translation method *after* converse.js
-#. has been initialized and with it the i18n machinery. That's why
-#. we do it here in the "initialize" method and not at the top of
-#. the module.
-#: dist/converse-no-dependencies.js:31189
-msgid "unencrypted"
+#: dist/converse-no-dependencies.js:46336
+msgid ""
+"The provider rejected your registration attempt. Please check the values you "
+"entered for correctness."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31190
-msgid "unverified"
+#: dist/converse-no-dependencies.js:46705
+msgid "Click to toggle the rooms list"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31191
-msgid "verified"
+#: dist/converse-no-dependencies.js:46706
+msgid "Open Rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31192
-msgid "finished"
+#: dist/converse-no-dependencies.js:46750
+#, javascript-format
+msgid "Are you sure you want to leave the room %1$s?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31788
+#: dist/converse-no-dependencies.js:47359
 #, javascript-format
 msgid "Sorry, there was an error while trying to add %1$s as a contact."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31936
+#: dist/converse-no-dependencies.js:47570
 msgid "This client does not allow presence subscriptions"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32028
+#: dist/converse-no-dependencies.js:47678
 msgid "Click to hide these contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32112
-msgid "Don't have a chat account?"
+#: dist/converse-no-dependencies.js:47877
+msgid "This contact is busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32114
-msgid "Create an account"
+#: dist/converse-no-dependencies.js:47878
+msgid "This contact is online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32126
-msgid "Create your account"
+#: dist/converse-no-dependencies.js:47879
+msgid "This contact is offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32128
-msgid "Please enter the XMPP provider to register with:"
+#: dist/converse-no-dependencies.js:47880
+msgid "This contact is unavailable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32148
-msgid "Already have a chat account?"
+#: dist/converse-no-dependencies.js:47881
+msgid "This contact is away for an extended period"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32150
-msgid "Log in here"
+#: dist/converse-no-dependencies.js:47882
+msgid "This contact is away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32162
-msgid "Account Registration:"
+#: dist/converse-no-dependencies.js:47887
+msgid "Groups"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32170
-msgid "Register"
+#: dist/converse-no-dependencies.js:47889
+msgid "My contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32174
-msgid "Choose a different provider"
+#: dist/converse-no-dependencies.js:47891
+msgid "Pending contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32186
-msgid "Hold tight, we're fetching the registration form…"
+#: dist/converse-no-dependencies.js:47893
+msgid "Contact requests"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32321
-msgid " e.g. conversejs.org"
+#: dist/converse-no-dependencies.js:47895
+msgid "Ungrouped"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32367
-msgid "Fetch registration form"
+#: dist/converse-no-dependencies.js:47938
+msgid "Contact name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32368
-msgid "Tip: A list of public XMPP providers is available"
+#: dist/converse-no-dependencies.js:47941
+msgid "Add a Contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32369
-msgid "here"
+#: dist/converse-no-dependencies.js:47942
+msgid "XMPP Address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32417
-msgid "Sorry, we're unable to connect to your chosen provider."
+#: dist/converse-no-dependencies.js:47944
+msgid "name@example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32433
-msgid ""
-"Sorry, the given provider does not support in band account registration. "
-"Please try with a different provider."
+#: dist/converse-no-dependencies.js:47945
+msgid "Add"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48053
+msgid "Filter"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48054
+msgid "Filter by contact name"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48055
+msgid "Filter by group name"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48056
+msgid "Filter by status"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48057
+msgid "Any"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48058
+msgid "Unread"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48060
+msgid "Chatty"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48063
+msgid "Extended Away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32457
+#: dist/converse-no-dependencies.js:48219
+#: dist/converse-no-dependencies.js:48261
 #, javascript-format
-msgid ""
-"Something went wrong while establishing a connection with \"%1$s\". Are you "
-"sure it exists?"
+msgid "Click to remove %1$s as a contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32620
-msgid "Now logging you in"
+#: dist/converse-no-dependencies.js:48228
+#, javascript-format
+msgid "Click to accept the contact request from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32624
-msgid "Registered successfully"
+#: dist/converse-no-dependencies.js:48229
+#, javascript-format
+msgid "Click to decline the contact request from %1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48260
+#, javascript-format
+msgid "Click to chat with %1$s (JID: %2$s)"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48337
+msgid "Are you sure you want to decline this contact request?"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48607
+msgid "Add a contact"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:50080
+msgid "Room Address (JID)"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:50084
+msgid "Title"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:50088
+msgid "Description"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51158
+msgid "XMPP Username:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51164
+msgid "Password:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51166
+msgid "password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32733
+#: dist/converse-no-dependencies.js:51174
+msgid "This is a trusted device"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51176
 msgid ""
-"The provider rejected your registration attempt. Please check the values you "
-"entered for correctness."
+"To improve performance, we cache your data in this browser. Uncheck this box "
+"if this is a public computer or if you want your data to be deleted when you "
+"log out. It's important that you explicitly log out, otherwise not all "
+"cached data might be deleted."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33149
-msgid "Click to toggle the rooms list"
+#: dist/converse-no-dependencies.js:51178
+msgid "Log in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33150
-msgid "Open Rooms"
+#: dist/converse-no-dependencies.js:51184
+msgid "Click here to log in anonymously"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51526
+msgid "Don't have a chat account?"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51528
+msgid "Create an account"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51549
+msgid "Create your account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33194
+#: dist/converse-no-dependencies.js:51551
+msgid "Please enter the XMPP provider to register with:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51571
+msgid "Already have a chat account?"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51573
+msgid "Log in here"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51594
+msgid "Account Registration:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51602
+msgid "Register"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51606
+msgid "Choose a different provider"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51627
+msgid "Hold tight, we're fetching the registration form…"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52762
+#: dist/converse-no-dependencies.js:52791
+msgid "Download"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52781
 #, javascript-format
-msgid "Are you sure you want to leave the room %1$s?"
+msgid "Download: \"%1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52804
+msgid "Download video file"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52817
+msgid "Download audio file"
 msgstr ""

BIN
logo/hostpresto.png


+ 1 - 1
mockup/chatbox.html

@@ -5,7 +5,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Converse.js Mockups</title>
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/font-awesome/css/font-awesome.css" />
-    <link type="text/css" rel="stylesheet" media="screen" href="../../css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="../../css/converse.css" />
 </head>
 
 <body class="reset">

+ 2 - 3
mockup/chatroom.html

@@ -5,7 +5,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Chatroom Fullscreen</title>
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/font-awesome/css/font-awesome.css" />
-    <link type="text/css" rel="stylesheet" media="screen" href="../../css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="../../css/converse.css" />
 </head>
 
 <body class="reset">
@@ -23,12 +23,11 @@
             <div class="chatbox chatroom" id="chatroom">
                 <div class="flyout box-flyout">
                     <div class="chat-head chat-head-chatroom row no-gutters">
-                        <div class="col col-9">
+                        <div class="chatbox-title">
                             <div class="chat-title">Capulet's orchard</div>
                             <p class="chatroom-description">Two households, both alike in dignity, In fair Verona, where we lay our scene.</p>
                         </div>
                         <div class="chatbox-buttons row no-gutters">
-                            <a class="chatbox-btn fa fa-minus"></a>
                             <a class="chatbox-btn fa fa-close"></a>
                             <a class="chatbox-btn fa fa-wrench"></a>
                         </div>

+ 1 - 1
mockup/fullscreen-login.html

@@ -6,7 +6,7 @@
     <title>Login Fullscreen</title>
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/bootstrap/dist/css/bootstrap.css" />
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/font-awesome/css/font-awesome.css" />
-    <link type="text/css" rel="stylesheet" media="screen" href="../../css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="../../css/converse.css" />
 </head>
 
 <body>

File diff suppressed because it is too large
+ 790 - 338
package-lock.json


+ 21 - 13
package.json

@@ -1,8 +1,8 @@
 {
   "name": "converse.js",
   "version": "3.3.4",
-  "description": "Browser based XMPP instant messaging client",
-  "main": "main.js",
+  "description": "Browser based XMPP chat client",
+  "main": "dist/converse.js",
   "directories": {
     "doc": "docs",
     "locale": "locale",
@@ -20,20 +20,24 @@
     "chatrooms",
     "webchat"
   ],
-  "author": "JC Brand",
+  "author": {
+    "name": "JC Brand",
+    "email": "jc@opkode.com"
+  },
   "license": "MPL-2.0",
   "bugs": {
-    "url": "https://github.com/jcbrand/converse.js/issues"
+    "url": "https://github.com/conversejs/converse.js/issues"
   },
   "engines": {
     "browser": "*"
   },
   "devDependencies": {
-    "@babel/cli": "^7.0.0-beta.35",
-    "@babel/core": "^7.0.0-beta.35",
-    "@babel/preset-env": "^7.0.0-beta.35",
-    "almond": "~0.3.3",
+    "@babel/cli": "^7.0.0-beta.48",
+    "@babel/core": "^7.0.0-beta.48",
+    "@babel/preset-env": "^7.0.0-beta.48",
+    "@babel/preset-es2015": "^7.0.0-beta.49",
     "awesomplete-avoid-xss": "^1.1.2",
+    "babel-loader": "^8.0.0-beta.3",
     "backbone": "1.3.3",
     "backbone.browserStorage": "0.0.3",
     "backbone.nativeview": "^0.3.3",
@@ -48,9 +52,12 @@
     "es6-promise": "^4.1.0",
     "eslint": "4.19.1",
     "eslint-plugin-lodash": "^2.3.3",
+    "exports-loader": "^0.7.0",
     "filesize": "^3.6.1",
     "font-awesome": "^4.7.0",
+    "hellojs": "^1.16.1",
     "http-server": "^0.10.0",
+    "imports-loader": "^0.8.0",
     "install": "^0.9.5",
     "jasmine-core": "2.6.4",
     "jed": "1.1.1",
@@ -60,7 +67,10 @@
     "lodash": "4.17.4",
     "lodash-template-loader": "^2.0.0",
     "long": "^3.1.0",
+    "lodash-template-webpack-loader": "jcbrand/lodash-template-webpack-loader",
+    "minimist": "^1.2.0",
     "moment": "~> 2.19.3 ",
+    "npm": "^5.7.1",
     "otr": "0.2.16",
     "pluggable.js": "2.0.0",
     "po2json": "^0.4.4",
@@ -70,17 +80,15 @@
     "sinon": "^2.1.0",
     "sizzle": "^2.3.3",
     "snabbdom": "0.7.1",
-    "strophe.js": "1.2.14",
+    "strophe.js": "1.2.15",
     "strophejs-plugin-ping": "0.0.1",
     "strophejs-plugin-register": "0.0.1",
     "strophejs-plugin-rsm": "0.0.1",
-    "text": "requirejs/text#2.0.15",
     "uglify-es": "^3.0.24",
     "urijs": "^1.19.1",
     "wait-until-promise": "^1.0.0",
+    "webpack": "^4.0.1",
+    "webpack-cli": "^2.1.4",
     "xss": "^0.3.3"
-  },
-  "dependencies": {
-    "npm": "^5.7.1"
   }
 }

+ 18 - 0
redirect.html

@@ -0,0 +1,18 @@
+<!doctype html>
+<html class="no-js" lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>Converse</title>
+    <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
+    <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
+    <script src="node_modules/hellojs/dist/hello.all.js"></script>
+</head>
+<body>
+    <div class="content">
+        <div class="inner-content">
+            <h1 class="brand-heading"><i class="icon-conversejs"></i> Converse</h1>
+        </div>
+    </div>
+</body>
+</html>

+ 1 - 0
requirements.txt

@@ -0,0 +1 @@
+zc.buildout==2.11.4

+ 0 - 1
sass/_awesomplete.scss

@@ -1,4 +1,3 @@
-#converse-embedded-chat,
 #conversejs {
     [hidden] { display: none; }
 

+ 232 - 14
sass/_chatbox.scss

@@ -1,7 +1,9 @@
 #conversejs {
+    .chatbox-navback {
+        display: none;
+    }
     .flyout {
         border-radius: $chatbox-border-radius;
-        bottom: $chatbox-hover-height;
         position: absolute;
 
         @media screen and (max-height: $mobile-landscape-height) {
@@ -38,7 +40,6 @@
         flex-wrap: nowrap;
         color: #ffffff;
         font-size: 100%;
-        height: $chat-head-height;
         margin: 0;
         padding: 0.5em;
         position: relative;
@@ -53,6 +54,11 @@
             margin-right: 0.5em;
         }
 
+        .chatbox-title {
+            .chatroom-description {
+                font-size: 80%;
+            }
+        }
         .chatbox-buttons {
             flex-direction: row-reverse;
             @include make-col-ready();
@@ -120,8 +126,6 @@
             justify-content: space-between;
             background-color: $chat-head-color;
             box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-            height: $chat-height;
-            min-height: $chat-height/2;
             z-index: 1;
             overflow-y: scroll;
             width: 100%;
@@ -246,7 +250,6 @@
                 width: 100%;
                 border: none;
                 min-height: $chat-textarea-height;
-                max-height: $max-chat-textarea-height;
                 margin-bottom: -4px; // Not clear why this is necessar :(
                 &.spoiler {
                     height: 42px;
@@ -330,7 +333,6 @@
                         }
                         ul {
                             &.emoji-picker {
-                                height: $emoji-picker-height;
                                 overflow: scroll;
                                 padding: 0.5em;
                             }
@@ -434,33 +436,224 @@
     }
 }
 
+/* ******************* Overlay and embedded styles *************************** */
+
+#conversejs.converse-embedded,
+#conversejs.converse-overlayed {
+    .chat-head {
+        border-top-left-radius: $chatbox-border-radius;
+        border-top-right-radius: $chatbox-border-radius;
+        @media screen and (max-height: $mobile-landscape-height) {
+            border-top-left-radius: 0;
+            border-top-right-radius: 0;
+        }
+        @media screen and (max-width: $mobile-portrait-length) {
+            border-top-left-radius: 0;
+            border-top-right-radius: 0;
+        }
+        .chatbox-title {
+            @include make-col(8);
+        }
+        .chatbox-buttons {
+            @include make-col(4);
+        }
+    }
+
+    .chatbox {
+        min-width: $overlayed-chat-width!important;
+        width: $overlayed-chat-width;
+
+        .box-flyout {
+            min-width: $overlayed-chat-width!important;
+            width: $overlayed-chat-width;
+        }
+
+        .chat-body {
+            .chat-message {
+                line-height: $line-height-large;
+                .chat-msg-author {
+                    line-height: $line-height-large;
+                }
+                .chat-msg-content {
+                    line-height: $line-height-large;
+                    .emojione {
+                        margin-bottom: -5px;
+                    }
+                }
+            }
+        }
+    }
+    .chatbox {
+        form.sendXMPPMessage {
+            .chat-toolbar {
+                li {
+                    .toolbar-menu {
+                        min-width: 235px;
+
+                        ul {
+                            &.emoji-toolbar {
+                                width: 100%;
+                                .emoji-category {
+                                    float: left;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+#conversejs.converse-overlayed  {
+    .flyout {
+        bottom: $overlayed-chatbox-hover-height;
+    }
+    .box-flyout {
+        height: $overlayed-chat-height;
+        min-height: $overlayed-chat-height/2;
+    }
+    .chat-head {
+        height: $overlayed-chat-head-height;
+    }
+    .chat-textarea {
+        max-height: $overlayed-max-chat-textarea-height;
+    }
+    .emoji-picker {
+        height: $overlayed-emoji-picker-height;
+    }
+}
+
+@include media-breakpoint-down(sm) {
+	#conversejs.converse-overlayed {
+		> .row {
+			flex-direction: column;
+
+            &.no-gutters {
+                margin: -1em;
+            }
+		}
+	}
+}
+
+/* ******************* Fullpage styles *************************** */
+
 #conversejs.converse-fullscreen  {
+    .flyout {
+        border-radius: 0;
+        border-top: 0.8em solid $chat-head-color;
+        border: $flyout-padding solid $chat-head-color;
+        bottom: 0;
+    }
     .chatbox-btn {
         font-size: $fullpage-chatbox-button-size;
+        margin: 0 0.3em;
     }
     .chat-head {
+        height: $fullpage-chat-head-height;
+        font-size: $font-size-huge;
+        padding: 0;
+        .user-custom-message {
+            font-size: 50%;
+            height: auto;
+            line-height: $line-height;
+        }
+        .chatbox-title {
+            @include make-col(10);
+        }
         .chatbox-buttons {
-            @include make-col(3);
+            @include make-col(2);
+        }
+    }
+    .chat-textarea {
+        max-height: $fullpage-max-chat-textarea-height;
+    }
+    .emoji-picker {
+        height: $fullpage-emoji-picker-height;
+    }
+
+    .chatbox {
+        width: 100%;
+        height: 100%;
+        margin: 0;
+
+        @include make-col-ready();
+        @include media-breakpoint-up(md) {
+            @include make-col(9);
+        }
+        @include media-breakpoint-up(lg) {
+            @include make-col(9);
+        }
+        @include media-breakpoint-up(xl) {
+            @include make-col(10);
+        }
+
+        .box-flyout {
+            background-color: $chat-head-color;
+            box-shadow: none;
+            height: $fullpage-chat-height;
+            min-height: $fullpage-chat-height/2;
+            width: $fullpage-chat-width;
+        }
+        .chat-body {
+            background-color: $chat-head-color;
+            border-top-left-radius: $chatbox-border-radius;
+            border-top-right-radius: $chatbox-border-radius;
+
+            .chat-message {
+                line-height: $line-height;
+                font-size: $font-size-small;
+                .chat-msg-author {
+                    line-height: $line-height;
+                }
+                .chat-msg-content {
+                    line-height: $line-height;
+                    .emojione {
+                        height: $line-height;
+                        margin-bottom: -$line-height/4;
+                    }
+                }
+            }
+        }
+        .chat-content {
+            border-top-left-radius: $chatbox-border-radius;
+            border-top-right-radius: $chatbox-border-radius;
+        }
+        .chat-title {
+            font-size: $font-size-huge;
+            line-height: $line-height-huge;
+        }
+        .sendXMPPMessage {
+            ul {
+                width: 100%;
+            }
+            .toggle-smiley {
+                ul {
+                    &.emoji-toolbar {
+                        .emoji-category-picker {
+                            margin-right: 5em;
+                        }
+                        .emoji-category {
+                            padding-left: 10px;
+                            padding-right: 10px;
+                        }
+                    }
+                }
+            }
         }
     }
 }
 
-@media screen and (max-width: 767px) {
+@include media-breakpoint-down(sm) {
     #conversejs:not(.converse-embedded)  {
         > .row {
             flex-direction: row-reverse;
         }
-
         #converse-login-panel {
             .converse-form {
                 padding: 3em 2em 3em;
             }
         }
-
-        .sidebar {
-            display: block;
-        }
-
         .chatbox {
             width: calc(100% - 50px);
             .row {
@@ -473,4 +666,29 @@
             }
         }
     }
+
+    #conversejs.converse-mobile,
+    #conversejs.converse-overlayed,
+    #conversejs.converse-embedded,
+    #conversejs.converse-fullscreen {
+        .chatbox {
+            .box-flyout {
+                .chatbox-navback {
+                    display: flex;
+                    @include make-col(2);
+                    .fa-arrow-left {
+                        &:before {
+                            color: white;
+                        }
+                    }
+                }
+                .chatbox-title {
+                    @include make-col(7);
+                }
+                .chatbox-buttons {
+                    @include make-col(3);
+                }
+            }
+        }
+    }
 }

+ 157 - 32
sass/_chatrooms.scss

@@ -7,12 +7,37 @@
         }
     }
 
+    #room-details-modal {
+        .features-list {
+            margin-left: 1em;
+        }
+    }
+
+    .chatroom-features {
+        width: 100%;
+        .features-list {
+            padding-top: 0;
+            .feature {
+                width: 100%;
+                margin-right: 0.5em;
+                padding-right: 0;
+                font-size: 1em;
+                cursor: help;
+                .fa {
+                    margin-right: 0.5em;
+                    color: $text-color;
+                }
+            }
+        }
+    }
+
+
     .chat-head-chatroom {
         background-color: $chatroom-head-color;
 
         .chatroom-description {
             color: lighten($chatroom-head-color, 25%);
-            font-size: $font-size-large;
+            font-size: $font-size;
             font-size: 70%;
             margin-top: 3px;
             overflow-y: hidden;
@@ -101,16 +126,12 @@
                     display: flex;
                     flex-direction: column;
                     word-wrap: break-word; 
-                    min-width: $chat-width;
                     .new-msgs-indicator {
                         background-color: $chatroom-head-color;
                     }
                     .chat-content {
                         height: 100%;
                     }
-                    &.full {
-                        min-width: 100%;
-                    }
                 }
                 .occupants {
                     display: flex;
@@ -124,21 +145,19 @@
                     border-bottom-right-radius: $chatbox-border-radius;
                     padding: 0.5em;
 
-                    .occupants-heading {
-                        font-family: $heading-font; 
-                        padding: 0.3em 0;
-                    }
-
-                    .chatroom-features {
-                        width: 100%;
-                        .feature {
-                            float: left;
-                            margin-right: 0.5em;
-                            padding-right: 0;
-                            font-size: 1em;
-                            cursor: help;
+                    .occupants-header {
+                        display: flex;
+                        flex-direction: column;
+                        .hide-occupants {
+                            align-self: flex-end;
+                            cursor: pointer;
+                        }
+                        .occupants-heading {
+                            font-family: $heading-font; 
+                            padding: 0.3em 0;
                         }
                     }
+
                     .awesomplete {
                         ul {
                             padding: 0;
@@ -160,15 +179,6 @@
                             flex-grow: 1;
                             border-bottom: 1px solid lightgrey;
                         }
-                        &.features-list {
-                            padding-top: 0;
-                            .feature {
-                                width: 100%;
-                                .fa {
-                                    color: $text-color;
-                                }
-                            }
-                        }
                         li {
                             cursor: default;
                             display: block;
@@ -279,13 +289,128 @@
     }
 }
 
-@media screen and (max-width: 767px) {
-    #conversejs:not(.converse-embedded)  {
-        .chatbox {
+/* ******************* Overlay  styles *************************** */
+
+#conversejs.converse-overlayed {
+    .chatbox {
+        &.chatroom {
+            min-width: $chatroom-width !important;
+            width: $chatroom-width;
+            .box-flyout {
+                min-width: $chatroom-width !important;
+                width: $chatroom-width;
+            }
+            .chatbox-title {
+                @include make-col(8);
+                .chatroom-description {
+                    font-size: 80%;
+                }
+            }
+            .chatbox-buttons {
+                @include make-col(4);
+            }
+            .chatroom-body {
+                .occupants {
+                    .chatroom-features {
+                        .feature {
+                            font-size: $font-size-small;
+                        }
+                    }
+                }
+                .chat-area {
+                    min-width: $overlayed-chat-width;
+                }
+            }
+        }
+    }
+}
+
+#conversejs.converse-fullscreen {
+    .chatroom {
+        .box-flyout {
+            .chatbox-title {
+                @include make-col(9);
+            }
+            .chatbox-buttons {
+                @include make-col(3);
+            }
+        }
+    }
+}
+
+@include media-breakpoint-down(sm) {
+
+    #conversejs:not(.converse-embedded) {
+        .chatroom {
+            width: 100vw !important;
             .box-flyout {
-                .chatroom-body {
-                    .chat-area {
+                .chatbox-navback {
+                    @include make-col(2);
+                }
+                .chatbox-title {
+                    @include make-col(7);
+                }
+                .chatbox-buttons {
+                    @include make-col(3);
+                }
+            }
+        }
+    }
+}
+
+#conversejs.converse-fullscreen,
+#conversejs.converse-mobile {
+
+    .chatroom {
+        .box-flyout {
+            background-color: $chatroom-head-color;
+            border: $flyout-padding solid $chatroom-head-color;
+            border-top: 0.8em solid $chatroom-head-color;
+            width: 100%;
+
+            .chatbox-title {
+                .chatroom-description {
+                    font-size: 70%;
+                }
+            }
+
+            .chatroom-body {
+                @include border-top-radius($chatbox-border-radius);
+                .chatroom-form-container {
+                    border-radius: $chatbox-border-radius;
+                }
+                .chat-area {
+                    border-top-left-radius: $chatbox-border-radius;
+                    .chat-content {
+                        border-top-left-radius: $chatbox-border-radius;
                     }
+                    &.full {
+                        max-width: 100%;
+                        .new-msgs-indicator {
+                            max-width: 100%;
+                        }
+                    }
+                }
+                .occupants {
+                    border-top-right-radius: $chatbox-border-radius;;
+                    padding: $occupants-padding;
+                    .occupants-heading {
+                        font-size: $font-size-large;
+                    }
+                    ul {
+                        &.occupant-list {
+                            li {
+                                font-size: $font-size-small;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        .room-invite {
+            span {
+                .invited-contact {
+                    margin: 0 0 0.5em -1px;
                 }
             }
         }

+ 131 - 12
sass/_controlbox.scss

@@ -1,4 +1,24 @@
 #conversejs {
+    .oauth-providers {
+        text-align: center;
+        .oauth-provider {
+            margin: 1em 0;
+
+            .oauth-login {
+                margin-left: 0;
+                color: $link-color;
+                font-size: $font-size-large;
+                &:hover {
+                    color: darken($link-color, 20%);
+                }
+                i {
+                    color: $link-color;
+                    font-size: $font-size-huge;
+                    margin-right: 0.5em;
+                }
+            }
+        }
+    }
 
     .set-xmpp-status, .xmpp-status, .roster-contacts {
         .fa-circle {
@@ -173,15 +193,6 @@
             font-weight: bold;
         }
 
-        .oauth-login {
-            margin-left: 0;
-            color: $text-color;
-            .icon-social:before {
-                font-size: $font-size-large;
-            }
-        }
-
-
         .controlbox-pane {
             .userinfo {
                 padding-bottom: 1em;
@@ -296,6 +307,7 @@
             }
 
             .switch-form {
+                text-align: center;
                 padding: 2em 0;
                 p {
                     margin-top: 0.5em;
@@ -357,7 +369,6 @@
 
             .chatbox { 
                 .box-flyout {
-                    top: -100vh;
                     margin-left: 15px; // Counteracts Bootstrap margins, but
                                        // not clear why needed...
                     left: 0;
@@ -369,10 +380,11 @@
             }
 
             #controlbox {
-                order: 0;
+                width: 100vw !important;
                 .box-flyout {
                     width: 100vw !important;
                     height: 100vh !important;
+                    margin-left: 30px;
                 }
                 .sidebar {
                     display: block;
@@ -393,7 +405,7 @@
     }
 }
 
-#conversejs:not(.converse-fullscreen) {
+#conversejs.converse-overlayed {
     #controlbox {
         order: -1;
         min-width: $controlbox-width !important;
@@ -444,3 +456,110 @@
         }
     }
 }
+
+#conversejs.converse-fullscreen,
+#conversejs.converse-mobile {
+    #controlbox {
+        @include make-col-ready();
+        @include media-breakpoint-up(md) {
+            @include make-col(3);
+        }
+        @include media-breakpoint-up(lg) {
+            @include make-col(3);
+        }
+        @include media-breakpoint-up(xl) {
+            @include make-col(2);
+        }
+
+        &.logged-out {
+            @include make-col(12);
+        }
+
+        margin: 0;
+
+        .controlbox-pane {
+            border-radius: 0;
+        }
+
+        .flyout {
+            border-radius: 0;
+        }
+
+        #converse-login-panel {
+            border-radius: 0;
+            .converse-form {
+                padding: 3em 2em 3em;
+            }
+        }
+
+        .toggle-register-login {
+            line-height: $line-height-huge;
+        }
+
+        .brand-heading-container {
+            @include make-col(12);
+            text-align: center;
+            .brand-heading {
+                font-size: 150%;
+                font-size: 600%;
+                padding: 0.7em 0 0 0;
+                opacity: 0.8;
+                color: $blue;
+            }
+            .brand-subtitle {
+                font-size: 90%;
+                padding: 0.5em;
+            }
+            @media screen and (max-width: $mobile-portrait-length) {
+                .brand-heading {
+                    font-size: 400%;
+                }
+            }
+        }
+
+        &.logged-out {
+            @include make-col(12);
+            @include fade-in;
+            width: 100%;
+            .box-flyout {
+                width: 100%;
+            }
+        }
+        .box-flyout {
+            border: 0;
+            width: 100%;
+            z-index: 1;
+            background-color: $controlbox-head-color;
+
+            .controlbox-head {
+                display: none;
+            }
+        }
+
+        #converse-register, #converse-login {
+            @include make-col-ready();
+            @include make-col(8);
+            @include make-col-offset(2);
+
+            @include media-breakpoint-up(sm) {
+                @include make-col(8);
+                @include make-col-offset(2);
+            }
+            @include media-breakpoint-up(md) {
+                @include make-col(8);
+                @include make-col-offset(2);
+            }
+            @include media-breakpoint-up(lg) {
+                @include make-col(6);
+                @include make-col-offset(3);
+            }
+            .title, .instructions {
+                margin: 1em 0;
+            }
+            input[type=submit],
+            input[type=button] {
+                width: auto;
+            }
+        }
+    }
+}

+ 28 - 2
sass/_core.scss

@@ -61,6 +61,23 @@ body.reset {
     direction: ltr;
     z-index: 1031; // One more than bootstrap navbar
 
+    &.converse-overlayed {
+        > .row {
+            flex-direction: row-reverse;
+        }
+    }
+
+    &.converse-fullscreen,
+    &.converse-mobile {
+        .converse-chatboxes {
+            width: 100vw;
+            right: 15px; // Hack due to padding added by bootstrap
+        }
+    }
+    &.converse-overlayed {
+        height: 3em;
+    }
+
     .brand-heading {
         font-family: $heading-font; 
         .icon-conversejs {
@@ -76,7 +93,6 @@ body.reset {
         z-index: 1031; // One more than bootstrap navbar
         position: fixed;
         bottom: 0;
-        height: 2.7rem;
         right: 0;
     }
 
@@ -143,6 +159,10 @@ body.reset {
         font-weight: 700;
     }
 
+    em {
+        font-style: italic;
+    }
+
     ol, ul {
         list-style: none;
     }
@@ -156,10 +176,16 @@ body.reset {
         margin: 0;
     }
 
-    a, a:visited, a:hover, a:not([href]):not([tabindex]) {
+    a, a:visited, a:not([href]):not([tabindex]) {
         text-decoration: none;
         color: $link-color;
         text-shadow: none;
+        &:hover {
+            color: darken($link-color, 20%);
+            text-decoration: none;
+            text-shadow: none;
+        }
+
         &.fa {
             color: $subdued-color;
             &:hover {

+ 0 - 1
sass/_embedded.scss

@@ -1,5 +1,4 @@
 @import "bourbon";
-@import "converse/variables";
 #conversejs.converse-embedded {
 
     @include box-sizing(border-box);

+ 17 - 0
sass/_headline.scss

@@ -18,3 +18,20 @@
     }
 }
 
+#conversejs.converse-fullscreen {
+    .chatbox.headlines {
+        .box-flyout {
+            background-color: $headline-head-color;
+        }
+        .chat-head {
+            &.chat-head-chatbox {
+                background-color: $headline-head-color;
+            }
+        }
+        .flyout {
+            border: $flyout-padding solid $headline-head-color;
+            border-top: 0.8em solid $headline-head-color;
+        }
+    }
+}
+

+ 1 - 1
sass/converse/_minimized_chats.scss → sass/_minimized_chats.scss

@@ -1,4 +1,4 @@
-#conversejs:not(.fullscreen) {
+#conversejs.converse-overlayed {
     #minimized-chats {
         order: 100;
 

+ 6 - 0
sass/_roomslist.scss

@@ -32,6 +32,10 @@
             .open-chatroom {
                 &:hover {
                     background-color: lighten($controlbox-head-color, 45%);
+                    a.add-bookmark,
+                    a.room-info {
+                        display: block !important;
+                    }
                 }
                 &.unread-msgs {
                     .msgs-indicator {
@@ -48,7 +52,9 @@
                     &:hover {
                         color: $dark-link-color;
                     }
+                    &.add-bookmark,
                     &.room-info {
+                        display: none;
                         &:before {
                             font-size: 15px;
                         }

+ 0 - 4
sass/_roster.scss

@@ -4,10 +4,8 @@
     position: relative;
     margin: 0;
     height: $roster-height;
-    height: calc(~"100% - #{$controlbox-dropdown-height*2} - 20px");
     padding: 0;
     overflow: hidden;
-
     // XXX: FIXME
     height: calc(100% - 70px);
 
@@ -43,7 +41,6 @@
         }
         .state-type {
             font-size: calc(#{$font-size} - 2px);
-            height: $controlbox-dropdown-height;
             width: 100%;
         }
     }
@@ -142,7 +139,6 @@
                     .avatar {
                         float: left;
                         display: inline-block;
-                        height: $roster-item-height;
                     }
                 }
                 &.current-xmpp-contact span {

+ 32 - 2
sass/_variables.scss

@@ -63,6 +63,8 @@ $message-them-color: $green !default;
 
 $roster-height: 194px !default;
 
+$flyout-padding: 1.2em;
+
 $chat-head-color: $green !default;
 $chat-head-text-color: white !default;
 $chat-head-inverse-text-color: white !default;
@@ -110,10 +112,11 @@ $font-path: "../fonticons/fonts/" !default;
 $normal-font: "Helvetica", "Arial", sans-serif;
 $heading-font: 'Century Gothic', futura, 'URW Gothic L', Verdana, sans-serif !default;
 
-$chatroom-head-color: $red !default;
-$chatroom-color-light: $light-red !default;
 $chatroom-color-dark: $darkest-red !default;
+$chatroom-color-light: $light-red !default;
+$chatroom-head-color: $red !default;
 $chatroom-message-them-color: $green !default;
+$chatroom-width: 400px !default;
 
 $headline-head-color: $orange !default;
 
@@ -124,3 +127,30 @@ $box-close-button-padding-right: 4px !default;
 
 $chatbox-button-size: 14px !default;
 $fullpage-chatbox-button-size: 16px !default;
+
+$font-size-small: 12px !default;
+$font-size: 14px !default;
+$font-size-large: 16px !default;
+$font-size-huge: 20px !default;
+
+$legend-font-size: 16px !default;
+
+$line-height-small:  14px !default;
+$line-height:  16px !default;
+$line-height-large:  20px !default;
+$line-height-huge:  24px !default;
+
+$occupants-padding: 1em;
+
+$fullpage-chat-head-height: 62px !default;
+$fullpage-chat-height: 100vh;
+$fullpage-chat-width: 100%;
+$fullpage-emoji-picker-height: 150px !default;
+$fullpage-max-chat-textarea-height: 400px !default;
+
+$overlayed-chat-head-height: 55px !default;
+$overlayed-chat-height: 450px !default;
+$overlayed-chat-width: 250px !default;
+$overlayed-chatbox-hover-height: 1em !default;
+$overlayed-emoji-picker-height: 100px !default;
+$overlayed-max-chat-textarea-height: 200px !default;

+ 54 - 26
sass/_website.scss

@@ -113,29 +113,41 @@ a:hover, a:focus {
 .features-section,
 .outro,
 .intro {
-  width: 100%;
-  padding: 100px 0;
-  text-align: center;
-  color: #fff;
+    width: 100%;
+    padding: 100px 0;
+    text-align: center;
+    color: #fff;
 }
 .intro {
-  background: url(images/header.jpg) no-repeat bottom center scroll;
-  background-color: #211018;
-  -webkit-background-size: cover;
-  -moz-background-size: cover;
-  background-size: cover;
-  -o-background-size: cover;
+    background: url(images/header.jpg) no-repeat bottom center scroll;
+    background-color: #211018;
+    -webkit-background-size: cover;
+    -moz-background-size: cover;
+    background-size: cover;
+    -o-background-size: cover;
 }
 .features-section {
-  background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #85505f, #384955, #655361);
+    background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #85505f, #384955, #655361);
 }
 .features-section a {
-  color: #82B397;
+    color: #82B397;
 }
 .outro {
-  background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #384955, #655361, #85505f);
+    background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #384955, #655361, #85505f);
 }
 
+section {
+    h2 {
+        color: #E7A151;
+    }
+    h3 {
+        color: #89B7CD;
+    }
+    h4 {
+        color: #5CBC86;
+        font-size: 1.5em;
+    }
+}
 
 .brand-heading {
     font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif;
@@ -205,25 +217,38 @@ a:hover, a:focus {
 }
 
 .content-section {
-  padding-top: 100px;
+    padding-top: 100px;
+    padding-top: 100px;
+    min-height: 100vh;
+
+    .privacy-policy {
+        padding-top: 2em;
+        h4 {
+            padding-top: 1.5em;
+        }
+        p {
+            font-size: 1.2em;
+            padding-bottom: 0;
+            margin-bottom: 1em;
+        }
+    }
 }
 .donate-section {
-  width: 100%;
-  padding: 50px 0;
-  color: #ffffff;
-  background-color: #211018;
+    width: 100%;
+    padding: 50px 0;
+    color: #ffffff;
+    background-color: #211018;
 }
 .donate-section p.bitcoin-header {
-  margin: 0 0 5px;
+    margin: 0 0 5px;
 }
 @media (min-width: 767px) {
-  .content-section {
-    padding-top: 150px;
-    padding-bottom: 50px;
-  }
-  .donate-section {
-    padding: 100px 0;
-  }
+    .content-section {
+        padding-bottom: 50px;
+    }
+    .donate-section {
+        padding: 100px 0;
+    }
 }
 .btn {
   font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif;
@@ -332,6 +357,9 @@ ul.features {
     clear: both;
     font-size: 1.4em;
     padding: 2em 0 6em 0;
+    ul {
+        padding: 0;
+    }
 }
 .sponsors h2 {
     text-align: center;

+ 2 - 6
sass/converse.scss

@@ -2,13 +2,12 @@
  * Converse.js (Web-based XMPP instant messaging client)
  * http://conversejs.org
  *
- * Copyright (c) 2012-2016, JC Brand <jc@opkode.com>
+ * Copyright (c) 2013-2018, JC Brand <jc@opkode.com>
  * Licensed under the Mozilla Public License
  */
 @import "font-awesome";
 @import "bourbon";
 @import "variables";
-@import "converse/variables";
 
 @import "bootstrap/scss/functions";
 @import "bootstrap/scss/variables";
@@ -40,19 +39,16 @@
     @import "bootstrap/scss/utilities";
 }
 @import "core";
-@import "converse/core";
 @import "forms";
 @import "profile";
 @import "chatbox";
-@import "converse/chatbox";
 @import "controlbox";
 @import "roomslist";
 @import "roster";
 @import "chatrooms";
-@import "converse/chatrooms";
 @import "headline";
 @import "messages";
-@import "converse/minimized_chats";
+@import "minimized_chats";
 @import "bookmarks";
 @import "awesomplete";
 @import "embedded";

+ 0 - 71
sass/converse/_chatbox.scss

@@ -1,71 +0,0 @@
-#converse-embedded-chat,
-#conversejs:not(.fullscreen) {
-    .chat-head {
-        border-top-left-radius: $chatbox-border-radius;
-        border-top-right-radius: $chatbox-border-radius;
-        @media screen and (max-height: $mobile-landscape-height) {
-            border-top-left-radius: 0;
-            border-top-right-radius: 0;
-        }
-        @media screen and (max-width: $mobile-portrait-length) {
-            border-top-left-radius: 0;
-            border-top-right-radius: 0;
-        }
-    }
-    .chatbox {
-        min-width: $chat-width!important;
-        width: $chat-width;
-
-        .box-flyout {
-            min-width: $chat-width!important;
-            width: $chat-width;
-        }
-
-        .chat-body {
-            .chat-message {
-                line-height: $line-height-large;
-                .chat-msg-author {
-                    line-height: $line-height-large;
-                }
-                .chat-msg-content {
-                    line-height: $line-height-large;
-                    .emojione {
-                        margin-bottom: -5px;
-                    }
-                }
-            }
-        }
-    }
-    .chatbox {
-        form.sendXMPPMessage {
-            .chat-toolbar {
-                li {
-                    .toolbar-menu {
-                        min-width: 235px;
-
-                        ul {
-                            &.emoji-toolbar {
-                                width: 100%;
-                                .emoji-category {
-                                    float: left;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-@include media-breakpoint-down(sm) {
-	#conversejs:not(.converse-fullscreen):not(.converse-embedded) {
-		> .row {
-			flex-direction: column;
-
-            &.no-gutters {
-                margin: -1em;
-            }
-		}
-	}
-}

+ 0 - 22
sass/converse/_chatrooms.scss

@@ -1,22 +0,0 @@
-#conversejs {
-    .chatbox {
-        &.chatroom {
-            min-width: $chatroom-width !important;
-            width: $chatroom-width;
-            .box-flyout {
-                min-width: $chatroom-width !important;
-                width: $chatroom-width;
-            }
-
-            .chatroom-body {
-                .occupants {
-                    .chatroom-features {
-                        .feature {
-                            font-size: $font-size-small;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}

+ 0 - 5
sass/converse/_core.scss

@@ -1,5 +0,0 @@
-#conversejs {
-    > .row {
-        flex-direction: row-reverse;
-    }
-}

+ 0 - 26
sass/converse/_variables.scss

@@ -1,26 +0,0 @@
-$max-chat-textarea-height: 200px !default;
-$emoji-picker-height: 100px !default;
-
-$roster-item-height: 60px !default;
-
-$chat-head-height: 55px !default;
-
-$controlbox-dropdown-height: 25px !default;
-$controlbox-head-height: 55px !default;
-
-$chatbox-hover-height: 1em !default;
-
-$font-size-small: 12px !default;
-$font-size: 14px !default;
-$font-size-large: 16px !default;
-$font-size-huge: 20px !default;
-$legend-font-size: 16px !default;
-
-$line-height-small:  14px !default;
-$line-height:  16px !default;
-$line-height-large:  20px !default;
-
-$chat-width: 250px !default;
-$chat-height: 450px !default;
-
-$chatroom-width: 400px !default;

+ 0 - 58
sass/inverse.scss

@@ -1,58 +0,0 @@
-/*!
- * Converse.js (Web-based XMPP instant messaging client)
- * http://conversejs.org
- *
- * Copyright (c) 2012-2014, JC Brand <jc@opkode.com>
- * Licensed under the Mozilla Public License
- */
-@import "font-awesome";
-@import "bourbon";
-@import "variables";
-@import "inverse/variables";
-
-@import "bootstrap/scss/functions";
-@import "bootstrap/scss/variables";
-@import "bootstrap/scss/mixins";
-#conversejs {
-    @import "bootstrap/scss/root";
-    @import "bootstrap/scss/reboot";
-    @import "bootstrap/scss/type";
-    @import "bootstrap/scss/images";
-    @import "bootstrap/scss/grid";
-    @import "bootstrap/scss/forms";
-    @import "bootstrap/scss/buttons";
-    @import "bootstrap/scss/transitions";
-    @import "bootstrap/scss/dropdown";
-    @import "bootstrap/scss/button-group";
-    @import "bootstrap/scss/input-group";
-    @import "bootstrap/scss/custom-forms";
-    @import "bootstrap/scss/card";
-    @import "bootstrap/scss/breadcrumb";
-    @import "bootstrap/scss/badge";
-    @import "bootstrap/scss/alert";
-    @import "bootstrap/scss/media";
-    @import "bootstrap/scss/list-group";
-    @import "bootstrap/scss/close";
-    @import "bootstrap/scss/modal";
-    @import "bootstrap/scss/tooltip";
-    @import "bootstrap/scss/popover";
-    @import "bootstrap/scss/utilities";
-}
-@import "core";
-@import "inverse/core";
-@import "forms";
-@import "profile";
-@import "chatbox";
-@import "inverse/chatbox";
-@import "controlbox";
-@import "inverse/controlbox";
-@import "roster";
-@import "roomslist";
-@import "inverse/roster";
-@import "bookmarks";
-@import "chatrooms";
-@import "inverse/chatrooms";
-@import "headline";
-@import "inverse/headline";
-@import "messages";
-@import "awesomplete"

+ 0 - 96
sass/inverse/_chatbox.scss

@@ -1,96 +0,0 @@
-#conversejs.fullscreen {
-    .chatbox-btn {
-        font-size: $font-size-large;
-        margin: 0 0.3em;
-    }
-    .flyout {
-        border-radius: 0;
-        border: $flyout-padding solid $chat-head-color;
-        border-top: 0.8em solid $chat-head-color;
-        bottom: 0;
-    }
-    .chat-head {
-        font-size: 20px;
-        padding: 0;
-        .user-custom-message {
-            font-size: 50%;
-            height: auto;
-            line-height: $line-height;
-        }
-    }
-    .chatbox {
-        width: 100%;
-        height: 100%;
-        margin: 0;
-
-        @include make-col-ready();
-        @include media-breakpoint-up(md) {
-            @include make-col(9);
-        }
-        @include media-breakpoint-up(xl) {
-            @include make-col(10);
-        }
-
-        .box-flyout {
-            background-color: $chat-head-color;
-            height: 100vh;
-            width: 100%;
-            box-shadow: none;
-        }
-        .chat-body {
-            background-color: $chat-head-color;
-            border-top-left-radius: $chatbox-border-radius;
-            border-top-right-radius: $chatbox-border-radius;
-
-            .chat-message {
-                line-height: $line-height;
-                font-size: $font-size-small;
-                .chat-msg-author {
-                    line-height: $line-height;
-                }
-                .chat-msg-content {
-                    line-height: $line-height;
-                    .emojione {
-                        height: $line-height;
-                        margin-bottom: -$line-height/4;
-                    }
-                }
-            }
-        }
-        .chat-content {
-            border-top-left-radius: $chatbox-border-radius;
-            border-top-right-radius: $chatbox-border-radius;
-        }
-        .chat-title {
-            font-size: $font-size-huge;
-            line-height: $line-height-huge;
-        }
-
-        .sendXMPPMessage {
-            ul {
-                width: 100%;
-            }
-            .toggle-smiley {
-                ul {
-                    &.emoji-toolbar {
-                        .emoji-category-picker {
-                            margin-right: 5em;
-                        }
-                        .emoji-category {
-                            padding-left: 10px;
-                            padding-right: 10px;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-@media screen and (max-width: 767px) {
-    #conversejs:not(.converse-embedded).fullscreen {
-        .chatbox {
-            width: calc(100% - 50px);
-        }
-    }
-}

+ 0 - 64
sass/inverse/_chatrooms.scss

@@ -1,64 +0,0 @@
-#conversejs.converse-fullscreen,
-#conversejs.converse-mobile {
-
-    .chat-head-chatroom {
-        height: $chatroom-head-height;
-        font-size: 20px;
-        .chat-title {
-            .chatroom-description {
-                font-size: 65%;
-            }
-        }
-    }
-
-    .chatroom {
-        .box-flyout {
-            background-color: $chatroom-head-color;
-            border: $flyout-padding solid $chatroom-head-color;
-            border-top: 0.8em solid $chatroom-head-color;
-            width: 100%;
-
-            .chatroom-body {
-                @include border-top-radius($chatbox-border-radius);
-                .chatroom-form-container {
-                    border-radius: $chatbox-border-radius;
-                }
-                .chat-area {
-                    border-top-left-radius: $chatbox-border-radius;
-                    min-width: auto;
-
-                    .chat-content {
-                        border-top-left-radius: $chatbox-border-radius;
-                    }
-                    &.full {
-                        max-width: 100%;
-                        .new-msgs-indicator {
-                            max-width: 100%;
-                        }
-                    }
-                }
-                .occupants {
-                    border-top-right-radius: $chatbox-border-radius;;
-                    padding: $padding;
-                    .occupants-heading {
-                        font-size: $font-size-large;
-                    }
-                    ul {
-                        &.occupant-list {
-                            li {
-                                font-size: $font-size-small;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        .room-invite {
-            span {
-                .invited-contact {
-                    margin: 0 0 0.5em -1px;
-                }
-            }
-        }
-    }
-}

+ 0 - 102
sass/inverse/_controlbox.scss

@@ -1,102 +0,0 @@
-#conversejs.fullscreen {
-    #controlbox {
-        @include make-col-ready();
-        @include media-breakpoint-up(md) {
-            @include make-col(3);
-        }
-        @include media-breakpoint-up(xl) {
-            @include make-col(2);
-        }
-
-        &.logged-out {
-            @include make-col(12);
-        }
-
-        margin: 0;
-
-        .controlbox-pane {
-            border-radius: 0;
-        }
-
-        .flyout {
-            border-radius: 0;
-        }
-
-        #converse-login-panel {
-            border-radius: 0;
-            .converse-form {
-                padding: 3em 2em 3em;
-            }
-        }
-
-        .toggle-register-login {
-            line-height: $line-height-huge;
-        }
-
-        .brand-heading-container {
-            @include make-col(12);
-            text-align: center;
-            .brand-heading {
-                font-size: 150%;
-                font-size: 600%;
-                padding: 0.7em 0 0 0;
-                opacity: 0.8;
-                color: $blue;
-            }
-            .brand-subtitle {
-                font-size: 90%;
-                padding: 0.5em;
-            }
-            @media screen and (max-width: $mobile-portrait-length) {
-                .brand-heading {
-                    font-size: 400%;
-                }
-            }
-        }
-
-        &.logged-out {
-            @include make-col(12);
-            @include fade-in;
-            width: 100%;
-            .box-flyout {
-                width: 100%;
-            }
-        }
-        .box-flyout {
-            border: 0;
-            width: 100%;
-            z-index: 1;
-            background-color: $controlbox-head-color;
-
-            .controlbox-head {
-                display: none;
-            }
-        }
-
-        #converse-register, #converse-login {
-            @include make-col-ready();
-            @include make-col(8);
-            @include make-col-offset(2);
-
-            @include media-breakpoint-up(sm) {
-                @include make-col(8);
-                @include make-col-offset(2);
-            }
-            @include media-breakpoint-up(md) {
-                @include make-col(8);
-                @include make-col-offset(2);
-            }
-            @include media-breakpoint-up(lg) {
-                @include make-col(6);
-                @include make-col-offset(3);
-            }
-            .title, .instructions {
-                margin: 1em 0;
-            }
-            input[type=submit],
-            input[type=button] {
-                width: auto;
-            }
-        }
-    }
-}

+ 0 - 42
sass/inverse/_core.scss

@@ -1,42 +0,0 @@
-body {
-    font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
-    color: #ffffff;
-    background-color: $global-background-color;
-
-    .brand-heading {
-        font-size: 600%;
-        margin-left: -10%;
-        &.fade-in {
-            @include fade-in;
-            @include animation-delay(2s);
-        }
-        .icon-conversejs {
-            font-size: 88%;
-        }
-    }
-
-    div.content {
-        height: 100vh;
-        width: 100vw;
-        position: fixed;
-        background-color: $global-background-color;
-
-        .inner-content {
-            text-align: center;
-            padding: 7%;
-            @include calc(padding-left, '5% + #{$controlbox-width}');
-
-            p.no-chats {
-                padding-right: 10%;
-                font-size: 120%;
-            }
-        }
-    }
-}
-
-#conversejs.fullscreen {
-    .converse-chatboxes {
-        width: 100vw;
-        right: 15px; // Hack due to padding added by bootstrap
-    }
-}

+ 0 - 17
sass/inverse/_headline.scss

@@ -1,17 +0,0 @@
-#conversejs.fullscreen {
-    .chatbox.headlines {
-        .box-flyout {
-            background-color: $headline-head-color;
-        }
-        .chat-head {
-            &.chat-head-chatbox {
-                background-color: $headline-head-color;
-            }
-        }
-        .flyout {
-            border: $flyout-padding solid $headline-head-color;
-            border-top: 0.8em solid $headline-head-color;
-        }
-    }
-}
-

+ 0 - 58
sass/inverse/_minimized_chats.scss

@@ -1,58 +0,0 @@
-#conversejs.fullscreen {
-    #minimized-chats {
-        border-top-left-radius: $chatbox-border-radius;
-        border-top-right-radius: $chatbox-border-radius;
-        color: $inverse-link-color;
-        display: none;
-        float: right;
-        font-weight: bold;
-        height: 100%;
-        margin: 0 $chat-gutter;
-        padding: 0;
-        width: 130px;
-
-        #toggle-minimized-chats {
-            border-top-left-radius: $chatbox-border-radius;
-            border-top-right-radius: $chatbox-border-radius;
-            background-color: $link-color;
-            color: white;
-            position: relative;
-            padding: 10px 0 0 0;
-            display: block;
-            width: 100%;
-            height: 100%;
-            text-align: center;
-        }
-
-        .minimized-chats-flyout {
-            height: auto;
-            bottom: $bottom-gutter-height;
-            .chat-head {
-                padding: 0.3em;
-                border-radius: $chatbox-border-radius;
-                width: $minimized-chats-width;
-                height: 35px;
-                margin-bottom: 0.2em;
-                box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-            }
-            &.minimized {
-                height: auto;
-            }
-        }
-
-        .unread-message-count {
-            font-weight: bold;
-            background-color: white;
-            border: 1px solid;
-            text-shadow: 1px 1px 0 $text-shadow-color;
-            color: $warning-color;
-            border-radius: 5px;
-            padding: 2px 4px;
-            font-size: 16px;
-            text-align: center;
-            position: absolute;
-            right: 116px;
-            bottom: 10px;
-        }
-    }
-}

+ 0 - 5
sass/inverse/_roster.scss

@@ -1,5 +0,0 @@
-#conversejs {
-    #converse-roster {
-        padding-bottom: 3em;
-    }
-}

+ 0 - 34
sass/inverse/_variables.scss

@@ -1,34 +0,0 @@
-$max-chat-textarea-height: 400px !default;
-$emoji-picker-height: 150px !default;
-
-$roster-item-height: 30px !default;
-
-$flyout-padding: 1.2em;
-
-$chat-head-height: 62px !default;
-
-$controlbox-dropdown-height: 30px !default;
-$controlbox-head-height: 63px !default;
-
-$rounded-border-radius: 4px !default;
-
-$chatbox-hover-height: 6px !default;
-
-$font-size-small: 14px !default;
-$font-size: 16px !default;
-$font-size-large: 18px !default;
-$font-size-huge: 26px !default;
-$legend-font-size: 18px !default;
-
-$line-height-small:  20px !default;
-$line-height:  22px !default;
-$line-height-large:  24px !default;
-$line-height-huge:  30px !default;
-
-$chat-width: 100% !default;
-$chat-height: 100%;
-
-$padding: 1em;
-
-$chatroom-head-height: 62px !default;
-$chatroom-width: 300px !default;

+ 34 - 32
spec/bookmarks.js

@@ -4,12 +4,10 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
-        "utils",
         "mock",
         "test-utils"
         ], factory);
-} (this, function (jasmine, $, converse, utils, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var $iq = converse.env.$iq,
         $msg = converse.env.$msg,
@@ -381,14 +379,14 @@
                 ['http://jabber.org/protocol/pubsub#publish-options']
             ).then(function () {
                 /* Client requests all items
-                * -------------------------
-                *
-                *  <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
-                *  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-                *      <items node='storage:bookmarks'/>
-                *  </pubsub>
-                *  </iq>
-                */
+                 * -------------------------
+                 *
+                 *  <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
+                 *  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+                 *      <items node='storage:bookmarks'/>
+                 *  </pubsub>
+                 *  </iq>
+                 */
                 var IQ_id;
                 expect(_.filter(_converse.connection.send.calls.all(), function (call) {
                     var stanza = call.args[0];
@@ -411,27 +409,29 @@
                 }).length).toBe(1);
 
                 /*
-                * Server returns all items
-                * ------------------------
-                * <iq type='result'
-                *     to='juliet@capulet.lit/randomID'
-                *     id='retrieve1'>
-                * <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-                *     <items node='storage:bookmarks'>
-                *     <item id='current'>
-                *         <storage xmlns='storage:bookmarks'>
-                *         <conference name='The Play&apos;s the Thing'
-                *                     autojoin='true'
-                *                     jid='theplay@conference.shakespeare.lit'>
-                *             <nick>JC</nick>
-                *         </conference>
-                *         </storage>
-                *     </item>
-                *     </items>
-                * </pubsub>
-                * </iq>
-                */
+                 * Server returns all items
+                 * ------------------------
+                 * <iq type='result'
+                 *     to='juliet@capulet.lit/randomID'
+                 *     id='retrieve1'>
+                 * <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+                 *     <items node='storage:bookmarks'>
+                 *     <item id='current'>
+                 *         <storage xmlns='storage:bookmarks'>
+                 *         <conference name='The Play&apos;s the Thing'
+                 *                     autojoin='true'
+                 *                     jid='theplay@conference.shakespeare.lit'>
+                 *             <nick>JC</nick>
+                 *         </conference>
+                 *         </storage>
+                 *     </item>
+                 *     </items>
+                 * </pubsub>
+                 * </iq>
+                 */
                 expect(_converse.bookmarks.models.length).toBe(0);
+
+                spyOn(_converse.bookmarks, 'onBookmarksReceived').and.callThrough();
                 var stanza = $iq({'to': _converse.connection.jid, 'type':'result', 'id':IQ_id})
                     .c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
                         .c('items', {'node': 'storage:bookmarks'})
@@ -448,11 +448,13 @@
                                         'jid': 'another@conference.shakespeare.lit'
                                     }); // Purposefully exclude the <nick> element to test #1043
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
+                return test_utils.waitUntil(() => _converse.bookmarks.onBookmarksReceived.calls.count(), 300)
+            }).then(() => {
                 expect(_converse.bookmarks.models.length).toBe(2);
                 expect(_converse.bookmarks.findWhere({'jid': 'theplay@conference.shakespeare.lit'}).get('autojoin')).toBe(true);
                 expect(_converse.bookmarks.findWhere({'jid': 'another@conference.shakespeare.lit'}).get('autojoin')).toBe(false);
                 done();
-            });
+            }).catch(_.partial(console.error, _));
         }));
 
         describe("The rooms panel", function () {

+ 7 - 9
spec/chatbox.js

@@ -2,12 +2,10 @@
     define([
         "jquery",
         "jasmine",
-        "utils",
-        "converse-core",
         "mock",
         "test-utils"
         ], factory);
-} (this, function ($, jasmine, utils, converse, mock, test_utils) {
+} (this, function ($, jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $iq = converse.env.$iq;
@@ -429,9 +427,9 @@
                     var view = _converse.chatboxviews.get(contact_jid);
                     expect(chatbox).toBeDefined();
                     expect(view).toBeDefined();
-                    var $toolbar = $(view.el).find('ul.chat-toolbar');
-                    expect($toolbar.length).toBe(1);
-                    expect($toolbar.children('li').length).toBe(1);
+                    var toolbar = view.el.querySelector('ul.chat-toolbar');
+                    expect(_.isElement(toolbar)).toBe(true);
+                    expect(toolbar.querySelectorAll(':scope > li').length).toBe(1);
                     done();
                 }));
 
@@ -458,7 +456,7 @@
                     var timeout = false;
 
                     test_utils.waitUntil(function () {
-                        return utils.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container'));
+                        return u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container'));
                     }, 500).then(function () {
                         var picker = view.el.querySelector('.toggle-smiley .emoji-picker-container');
                         var items = picker.querySelectorAll('.emoji-picker li');
@@ -747,7 +745,7 @@
                             expect(chatbox.messages.length).toEqual(1);
                             var msg_obj = chatbox.messages.models[0];
                             expect(msg_obj.get('sender')).toEqual('me');
-                            expect(msg_obj.get('delayed')).toEqual(false);
+                            expect(msg_obj.get('is_delayed')).toEqual(false);
                             var $chat_content = $(chatboxview.el).find('.chat-content');
                             var status_text = $chat_content.find('.chat-info.chat-state-notification').text();
                             expect(status_text).toBe('Typing from another device');
@@ -895,7 +893,7 @@
                             expect(chatbox.messages.length).toEqual(1);
                             var msg_obj = chatbox.messages.models[0];
                             expect(msg_obj.get('sender')).toEqual('me');
-                            expect(msg_obj.get('delayed')).toEqual(false);
+                            expect(msg_obj.get('is_delayed')).toEqual(false);
                             var $chat_content = $(chatboxview.el).find('.chat-content');
                             var status_text = $chat_content.find('.chat-info.chat-state-notification').text();
                             expect(status_text).toBe('Stopped typing on the other device');

+ 190 - 133
spec/chatroom.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils", "utils" ], factory);
-} (this, function ($, jasmine, mock, converse, test_utils, utils) {
+    define(["jquery", "jasmine", "mock", "test-utils" ], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $pres = converse.env.$pres;
     var $iq = converse.env.$iq;
@@ -657,6 +657,7 @@
                     expect(indicator.getAttribute('data-isodate')).toEqual(moment().startOf('day').format());
                     expect(indicator.querySelector('time').getAttribute('class')).toEqual('separator-text');
                     expect(indicator.querySelector('time').textContent).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(2);
                     expect(chat_content.querySelector('div.chat-info:last-child').textContent).toBe(
                         "some1 has entered the room"
                     );
@@ -672,9 +673,9 @@
                         .c('status', 'Disconnected: Replaced by new connection').up()
                         .c('x', {xmlns: Strophe.NS.MUC_USER})
                             .c('item', {
-                                'affiliation': 'none',
+                                'affiliation': 'owner',
                                 'jid': 'some1@localhost/_converse.js-290929789',
-                                'role': 'none'
+                                'role': 'moderator'
                             });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
 
@@ -685,7 +686,7 @@
                     expect(indicator.getAttribute('data-isodate')).toEqual(moment().startOf('day').format());
 
                     expect(indicator.querySelector('time').textContent).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
-                    expect($(chat_content).find('div.chat-info').length).toBe(4);
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(3);
                     expect($(chat_content).find('div.chat-info:last').html()).toBe(
                         'some1 has left the room. '+
                         '"Disconnected: Replaced by new connection"');
@@ -713,14 +714,14 @@
                         });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
 
-                    var $time = $chat_content.find('time');
-                    expect($time.length).toEqual(4);
+                    let time = chat_content.querySelectorAll('time.separator-text');
+                    expect(time.length).toEqual(4);
 
                     var $indicator = $chat_content.find('.date-separator:eq(3)');
                     expect($indicator.attr('class')).toEqual('message date-separator');
                     expect($indicator.data('isodate')).toEqual(moment().startOf('day').format());
                     expect($indicator.find('time').text()).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
-                    expect($chat_content.find('div.chat-info').length).toBe(5);
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(4);
                     expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the room");
 
                     jasmine.clock().tick(ONE_DAY_LATER);
@@ -752,15 +753,15 @@
                             });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
 
-                    $time = $chat_content.find('time');
-                    expect($time.length).toEqual(6);
+                    time = chat_content.querySelectorAll('time.separator-text');
+                    expect(time.length).toEqual(6);
 
                     $indicator = $chat_content.find('.date-separator:eq(5)');
                     expect($indicator.attr('class')).toEqual('message date-separator');
                     expect($indicator.data('isodate')).toEqual(moment().startOf('day').format());
 
                     expect($indicator.find('time').text()).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
-                    expect($chat_content.find('div.chat-info').length).toBe(6);
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(5);
                     expect($chat_content.find('div.chat-info:last').html()).toBe(
                         'newguy has left the room. '+
                         '"Disconnected: Replaced by new connection"');
@@ -813,9 +814,8 @@
                             .c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
                                 .c('value').t(0);
                 _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
-                test_utils.waitUntil(function () {
-                    return _.get(view.el.querySelector('.chatroom-description'), 'textContent');
-                }).then(function () {
+                test_utils.waitUntil(() => _.get(view.el.querySelector('.chatroom-description'), 'textContent'))
+                .then(function () {
                     expect($(view.el.querySelector('.chatroom-description')).text()).toBe('This is the description');
                     done();
                 });
@@ -1113,7 +1113,7 @@
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
             }));
 
-            it("shows users currently present in the room",
+            it("shows all members even if they're not currently present in the room",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -1145,6 +1145,61 @@
                         expect(occupants.querySelectorAll('li .occupant-nick')[index].textContent.trim()).toBe(mock.chatroom_names[i]);
                     }
 
+                    // Test users leaving the room
+                    // http://xmpp.org/extensions/xep-0045.html#exit
+                    for (i=mock.chatroom_names.length-1; i>-1; i--) {
+                        name = mock.chatroom_names[i];
+                        role = mock.chatroom_roles[name].role;
+                        // See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres
+                        presence = $pres({
+                            to:'dummy@localhost/pda',
+                            from:'lounge@localhost/'+name,
+                            type: 'unavailable'
+                        }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
+                        .c('item').attrs({
+                            affiliation: mock.chatroom_roles[name].affiliation,
+                            jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
+                            role: 'none'
+                        }).nodeTree;
+                        _converse.connection._dataRecv(test_utils.createRequest(presence));
+                        expect(occupants.querySelectorAll('li').length).toBe(7);
+                    }
+                    done();
+                }).catch(_.partial(console.error, _));
+            }));
+
+            it("shows users currently present in the room",
+                mock.initConverseWithPromises(
+                    null, ['rosterGroupsFetched'], {},
+                    function (done, _converse) {
+
+                test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function() {
+                    var name;
+                    var view = _converse.chatboxviews.get('lounge@localhost'),
+                        occupants = view.el.querySelector('.occupant-list');
+                    var presence, role, jid, model;
+                    for (var i=0; i<mock.chatroom_names.length; i++) {
+                        name = mock.chatroom_names[i];
+                        role = mock.chatroom_roles[name].role;
+                        // See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres
+                        jid =
+                        presence = $pres({
+                                to:'dummy@localhost/pda',
+                                from:'lounge@localhost/'+name
+                        }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
+                        .c('item').attrs({
+                            affiliation: 'none',
+                            jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
+                            role: role
+                        }).up()
+                        .c('status').attrs({code:'110'}).nodeTree;
+                        _converse.connection._dataRecv(test_utils.createRequest(presence));
+                        expect(occupants.querySelectorAll('li').length).toBe(2+i);
+                        model = view.occupantsview.model.where({'nick': name})[0];
+                        var index = view.occupantsview.model.indexOf(model);
+                        expect(occupants.querySelectorAll('li .occupant-nick')[index].textContent.trim()).toBe(mock.chatroom_names[i]);
+                    }
+
                     // Test users leaving the room
                     // http://xmpp.org/extensions/xep-0045.html#exit
                     for (i=mock.chatroom_names.length-1; i>-1; i--) {
@@ -1710,7 +1765,11 @@
                         .c('status').attrs({code:'110'}).nodeTree;
 
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($chat_content.find('div.chat-info').length).toBe(2);
+                    // XXX: currently we still have an additional "has entered the room"
+                    // notification for the new nickname. Ideally we'd not have
+                    // that, but that's probably not possible without some
+                    // significant refactoring.
+                    expect($chat_content.find('div.chat-info').length).toBe(3);
                     expect($chat_content.find('div.chat-info').get(1).textContent).toBe(
                         __(_converse.muc.new_nickname_messages["303"], "newnick")
                     );
@@ -1741,6 +1800,8 @@
                         "<query xmlns='http://jabber.org/protocol/disco#info'/>"+
                     "</iq>");
 
+                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
+                spyOn(view.model, 'parseRoomFeatures').and.callThrough();
                 /* <iq from='coven@chat.shakespeare.lit'
                  *      id='ik3vs715'
                  *      to='hag66@shakespeare.lit/pda'
@@ -1780,16 +1841,17 @@
                         .c('feature', {'var': 'muc_unmoderated'}).up()
                         .c('feature', {'var': 'muc_nonanonymous'});
                 _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
-
-                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
-                expect(view.model.get('features_fetched')).toBe(true);
-                expect(view.model.get('passwordprotected')).toBe(true);
-                expect(view.model.get('hidden')).toBe(true);
-                expect(view.model.get('temporary')).toBe(true);
-                expect(view.model.get('open')).toBe(true);
-                expect(view.model.get('unmoderated')).toBe(true);
-                expect(view.model.get('nonanonymous')).toBe(true);
-                done();
+                test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300)
+                .then(() => {
+                    expect(view.model.get('features_fetched')).toBeTruthy();
+                    expect(view.model.get('passwordprotected')).toBe(true);
+                    expect(view.model.get('hidden')).toBe(true);
+                    expect(view.model.get('temporary')).toBe(true);
+                    expect(view.model.get('open')).toBe(true);
+                    expect(view.model.get('unmoderated')).toBe(true);
+                    expect(view.model.get('nonanonymous')).toBe(true);
+                    done();
+                });
             }));
 
             it("updates the shown features when the room configuration has changed",
@@ -2888,6 +2950,7 @@
 
                 var muc_iq;
                 var sent_IQs = [], IQ_ids = [];
+                var invitee_jid, sent_stanza, sent_id;
                 var sendIQ = _converse.connection.sendIQ;
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                     sent_IQs.push(iq);
@@ -2896,6 +2959,9 @@
 
                 _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'dummy'});
 
+                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
+                spyOn(view.model, 'parseRoomFeatures').and.callThrough();
+
                 // State that the chat is members-only via the features IQ
                 var features_stanza = $iq({
                         from: 'coven@chat.shakespeare.lit',
@@ -2915,111 +2981,102 @@
                         .c('feature', {'var': 'muc_membersonly'}).up();
                 _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
 
-                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
-                expect(view.model.get('membersonly')).toBeTruthy();
-
-                test_utils.createContacts(_converse, 'current');
-
-                var sent_stanza, sent_id;
-                spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
-                    if (stanza.nodeTree && stanza.nodeTree.nodeName === 'message') {
-                        sent_id = stanza.nodeTree.getAttribute('id');
-                        sent_stanza = stanza;
-                    }
-                });
-                var name = mock.cur_names[0];
-                var invitee_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
-                var reason = "Please join this chat room";
-                view.model.directInvite(invitee_jid, reason);
-
-                // Check in reverse order that we requested all three lists
-                // (member, owner and admin).
-                var admin_iq_id = IQ_ids.pop();
-                var owner_iq_id = IQ_ids.pop();
-                var member_iq_id = IQ_ids.pop();
-
-                expect(sent_IQs.pop().toLocaleString()).toBe(
-                    "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+admin_iq_id+"'>"+
-                        "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                            "<item affiliation='admin'/>"+
-                        "</query>"+
-                    "</iq>");
-                expect(sent_IQs.pop().toLocaleString()).toBe(
-                    "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+owner_iq_id+"'>"+
-                        "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                            "<item affiliation='owner'/>"+
-                        "</query>"+
-                    "</iq>");
-                expect(sent_IQs.pop().toLocaleString()).toBe(
-                    "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+member_iq_id+"'>"+
-                        "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                            "<item affiliation='member'/>"+
-                        "</query>"+
-                    "</iq>");
-
-                /* Now the service sends the member list to the user
-                 *
-                 *  <iq from='coven@chat.shakespeare.lit'
-                 *      id='member3'
-                 *      to='crone1@shakespeare.lit/desktop'
-                 *      type='result'>
-                 *  <query xmlns='http://jabber.org/protocol/muc#admin'>
-                 *      <item affiliation='member'
-                 *          jid='hag66@shakespeare.lit'
-                 *          nick='thirdwitch'
-                 *          role='participant'/>
-                 *  </query>
-                 *  </iq>
-                 */
-                var member_list_stanza = $iq({
-                        'from': 'coven@chat.shakespeare.lit',
-                        'id': member_iq_id,
-                        'to': 'dummy@localhost/resource',
-                        'type': 'result'
-                    }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
-                        .c('item', {
-                            'affiliation': 'member',
-                            'jid': 'hag66@shakespeare.lit',
-                            'nick': 'thirdwitch',
-                            'role': 'participant'
-                        });
-                _converse.connection._dataRecv(test_utils.createRequest(member_list_stanza));
-
-                var admin_list_stanza = $iq({
-                        'from': 'coven@chat.shakespeare.lit',
-                        'id': admin_iq_id,
-                        'to': 'dummy@localhost/resource',
-                        'type': 'result'
-                    }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
-                        .c('item', {
-                            'affiliation': 'admin',
-                            'jid': 'wiccarocks@shakespeare.lit',
-                            'nick': 'secondwitch'
-                        });
-                _converse.connection._dataRecv(test_utils.createRequest(admin_list_stanza));
-
-                var owner_list_stanza = $iq({
-                        'from': 'coven@chat.shakespeare.lit',
-                        'id': owner_iq_id,
-                        'to': 'dummy@localhost/resource',
-                        'type': 'result'
-                    }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
-                        .c('item', {
-                            'affiliation': 'owner',
-                            'jid': 'crone1@shakespeare.lit',
-                        });
-                _converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
-                test_utils.waitUntil(() => {
-                    return _.filter(
-                        _converse.connection.IQ_stanzas,
-                        (iq) => {
-                            if (iq.nodeTree.getAttribute('to') === 'coven@chat.shakespeare.lit' && iq.nodeTree.getAttribute('type') === 'set') {
-                                muc_iq = iq;
-                                return true;
-                            }
-                            return false;
-                        }).length;
-                }).then(function () {
+                test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300)
+                .then(() => {
+                   expect(view.model.get('membersonly')).toBeTruthy();
+
+                   test_utils.createContacts(_converse, 'current');
+
+                   spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
+                       if (stanza.nodeTree && stanza.nodeTree.nodeName === 'message') {
+                           sent_id = stanza.nodeTree.getAttribute('id');
+                           sent_stanza = stanza;
+                       }
+                   });
+                   var name = mock.cur_names[0];
+                   invitee_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
+                   var reason = "Please join this chat room";
+                   view.model.directInvite(invitee_jid, reason);
+
+                   // Check in reverse order that we requested all three lists
+                   // (member, owner and admin).
+                   var admin_iq_id = IQ_ids.pop();
+                   var owner_iq_id = IQ_ids.pop();
+                   var member_iq_id = IQ_ids.pop();
+
+                   expect(sent_IQs.pop().toLocaleString()).toBe(
+                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+admin_iq_id+"'>"+
+                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
+                               "<item affiliation='admin'/>"+
+                           "</query>"+
+                       "</iq>");
+                   expect(sent_IQs.pop().toLocaleString()).toBe(
+                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+owner_iq_id+"'>"+
+                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
+                               "<item affiliation='owner'/>"+
+                           "</query>"+
+                       "</iq>");
+                   expect(sent_IQs.pop().toLocaleString()).toBe(
+                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+member_iq_id+"'>"+
+                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
+                               "<item affiliation='member'/>"+
+                           "</query>"+
+                       "</iq>");
+
+                   /* Now the service sends the member list to the user
+                    *
+                    *  <iq from='coven@chat.shakespeare.lit'
+                    *      id='member3'
+                    *      to='crone1@shakespeare.lit/desktop'
+                    *      type='result'>
+                    *  <query xmlns='http://jabber.org/protocol/muc#admin'>
+                    *      <item affiliation='member'
+                    *          jid='hag66@shakespeare.lit'
+                    *          nick='thirdwitch'
+                    *          role='participant'/>
+                    *  </query>
+                    *  </iq>
+                    */
+                   var member_list_stanza = $iq({
+                           'from': 'coven@chat.shakespeare.lit',
+                           'id': member_iq_id,
+                           'to': 'dummy@localhost/resource',
+                           'type': 'result'
+                       }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
+                           .c('item', {
+                               'affiliation': 'member',
+                               'jid': 'hag66@shakespeare.lit',
+                               'nick': 'thirdwitch',
+                               'role': 'participant'
+                           });
+                   _converse.connection._dataRecv(test_utils.createRequest(member_list_stanza));
+
+                   var admin_list_stanza = $iq({
+                           'from': 'coven@chat.shakespeare.lit',
+                           'id': admin_iq_id,
+                           'to': 'dummy@localhost/resource',
+                           'type': 'result'
+                       }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
+                           .c('item', {
+                               'affiliation': 'admin',
+                               'jid': 'wiccarocks@shakespeare.lit',
+                               'nick': 'secondwitch'
+                           });
+                   _converse.connection._dataRecv(test_utils.createRequest(admin_list_stanza));
+
+                   var owner_list_stanza = $iq({
+                           'from': 'coven@chat.shakespeare.lit',
+                           'id': owner_iq_id,
+                           'to': 'dummy@localhost/resource',
+                           'type': 'result'
+                       }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
+                           .c('item', {
+                               'affiliation': 'owner',
+                               'jid': 'crone1@shakespeare.lit',
+                           });
+                   _converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
+                    return test_utils.waitUntil(() => IQ_ids.length, 300);
+                }).then(() => {
                     // Check that the member list now gets updated
                     expect(muc_iq.toLocaleString()).toBe("<iq to='coven@chat.shakespeare.lit' type='set' xmlns='jabber:client' id='"+muc_iq.nodeTree.getAttribute('id')+"'>"+
                             "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
@@ -3112,7 +3169,7 @@
 
                 test_utils.openControlBox();
                 var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
-                roomspanel.el.querySelector('.trigger-add-chatrooms-modal').click();
+                roomspanel.el.querySelector('.show-add-muc-modal').click();
                 test_utils.closeControlBox(_converse);
                 const modal = roomspanel.add_room_modal;
                 test_utils.waitUntil(function () {
@@ -3147,7 +3204,7 @@
 
                 test_utils.openControlBox();
                 var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
-                roomspanel.el.querySelector('.trigger-list-chatrooms-modal').click();
+                roomspanel.el.querySelector('.show-list-muc-modal').click();
                 test_utils.closeControlBox(_converse);
                 const modal = roomspanel.list_rooms_modal;
                 test_utils.waitUntil(function () {

+ 2 - 2
spec/controlbox.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $pres = converse.env.$pres;
     var $msg = converse.env.$msg;

+ 1 - 2
spec/converse.js

@@ -2,10 +2,9 @@
     define([
         "jquery",
         "jasmine",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function ($, jasmine, converse, mock, test_utils) {
+} (this, function ($, jasmine, mock, test_utils) {
     var b64_sha1 = converse.env.b64_sha1;
     var _ = converse.env._;
 

+ 6 - 3
spec/disco.js

@@ -2,10 +2,9 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
@@ -15,7 +14,11 @@
 
         describe("Whenever converse.js queries a server for its features", function () {
 
-            it("stores the features it receives", mock.initConverseWithAsync(function (done, _converse) {
+            it("stores the features it receives",
+                mock.initConverseWithPromises(
+                    null, ['discoInitialized'], {},
+                    function (done, _converse) {
+
                 var IQ_stanzas = _converse.connection.IQ_stanzas;
                 var IQ_ids =  _converse.connection.IQ_ids;
                 test_utils.waitUntil(function () {

+ 2 - 2
spec/eventemitter.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
 
     return describe("The _converse Event Emitter", function() {
 

+ 3 - 4
spec/headline.js

@@ -2,15 +2,14 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
-        "utils",
         "mock",
         "test-utils"
         ], factory);
-} (this, function (jasmine, $, converse, utils, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var $msg = converse.env.$msg,
-        _ = converse.env._;
+        _ = converse.env._,
+        utils = converse.env.utils;
 
     describe("A headlines box", function () {
 

+ 3 - 3
spec/http-file-upload.js

@@ -1,11 +1,9 @@
 (function (root, factory) {
     define([
         "jasmine",
-        "jquery",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils) {
+} (this, function (jasmine, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
@@ -367,6 +365,7 @@
                                         }).then(function () {
                                             // Check that the image renders
                                             expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
+                                                '<!-- src/templates/image.html -->\n'+
                                                 '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                                                     '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg">'+
                                                 '</a>');
@@ -474,6 +473,7 @@
                                             }).then(function () {
                                                 // Check that the image renders
                                                 expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
+                                                    '<!-- src/templates/image.html -->\n'+
                                                     '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                                                         '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg"></a>')
                                                 XMLHttpRequest.prototype.send = send_backup;

+ 2 - 2
spec/login.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
 
     describe("The Login Form", function () {
 

+ 2 - 2
spec/mam.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var Backbone = converse.env.Backbone;

+ 62 - 20
spec/messages.js

@@ -2,12 +2,10 @@
     define([
         "jquery",
         "jasmine",
-        "utils",
-        "converse-core",
         "mock",
         "test-utils"
         ], factory);
-} (this, function ($, jasmine, utils, converse, mock, test_utils) {
+} (this, function ($, jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $iq = converse.env.$iq;
@@ -62,7 +60,7 @@
                     expect(msg_obj.get('message')).toEqual(message);
                     expect(msg_obj.get('fullname')).toEqual(mock.cur_names[0]);
                     expect(msg_obj.get('sender')).toEqual('them');
-                    expect(msg_obj.get('delayed')).toEqual(false);
+                    expect(msg_obj.get('is_delayed')).toEqual(false);
                     // Now check that the message appears inside the chatbox in the DOM
                     var chat_content = chatboxview.el.querySelector('.chat-content');
                     expect(chat_content.querySelector('.chat-msg .chat-msg-text').textContent).toEqual(message);
@@ -178,7 +176,7 @@
                     expect(msg_obj.get('message')).toEqual(message);
                     expect(msg_obj.get('fullname')).toEqual(undefined);
                     expect(msg_obj.get('sender')).toEqual('them');
-                    expect(msg_obj.get('delayed')).toEqual(false);
+                    expect(msg_obj.get('is_delayed')).toEqual(false);
                     // Now check that the message appears inside the chatbox in the DOM
                     var chat_content = chatboxview.el.querySelector('.chat-content');
                     expect(chat_content.querySelector('.chat-msg .chat-msg-text').textContent).toEqual(message);
@@ -579,7 +577,7 @@
                 expect($el.hasClass('chat-msg-followup')).toBe(false);
                 expect($el.text()).toEqual('Older message');
 
-                $time = $chat_content.find('time:eq(1)');
+                $time = $chat_content.find('time.separator-text:eq(1)');
                 expect($time.text()).toEqual("Monday Jan 1st 2018");
 
                 $day = $chat_content.find('.date-separator:eq(1)');
@@ -593,7 +591,7 @@
                 expect($el.find('.chat-msg-text').text()).toEqual('another inbetween message');
                 expect($el.hasClass('chat-msg-followup')).toBe(true);
 
-                $time = $chat_content.find('time:nth(2)');
+                $time = $chat_content.find('time.separator-text:nth(2)');
                 expect($time.text()).toEqual("Tuesday Jan 2nd 2018");
 
                 $day = $chat_content.find('.date-separator:nth(2)');
@@ -630,7 +628,7 @@
             */
             sinon.spy(_converse, 'log');
             sinon.spy(_converse.chatboxes, 'getChatBox');
-            sinon.spy(utils, 'isHeadlineMessage');
+            sinon.spy(u, 'isHeadlineMessage');
             var msg = $msg({
                     from: 'localhost',
                     to: _converse.bare_jid,
@@ -642,13 +640,13 @@
                 "onMessage: Ignoring incoming headline message sent with type 'chat' from JID: localhost",
                 Strophe.LogLevel.INFO
             )).toBeTruthy();
-            expect(utils.isHeadlineMessage.called).toBeTruthy();
-            expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
+            expect(u.isHeadlineMessage.called).toBeTruthy();
+            expect(u.isHeadlineMessage.returned(true)).toBeTruthy();
             expect(_converse.chatboxes.getChatBox.called).toBeFalsy();
             // Remove sinon spies
             _converse.log.restore();
             _converse.chatboxes.getChatBox.restore();
-            utils.isHeadlineMessage.restore();
+            u.isHeadlineMessage.restore();
             done();
         }));
 
@@ -692,7 +690,7 @@
             expect(msg_obj.get('message')).toEqual(msgtext);
             expect(msg_obj.get('fullname')).toEqual(mock.cur_names[1]);
             expect(msg_obj.get('sender')).toEqual('them');
-            expect(msg_obj.get('delayed')).toEqual(false);
+            expect(msg_obj.get('is_delayed')).toEqual(false);
             // Now check that the message appears inside the chatbox in the DOM
             var chat_content = chatboxview.el.querySelector('.chat-content');
             expect(chat_content.querySelector('.chat-msg .chat-msg-text').textContent).toEqual(msgtext);
@@ -745,7 +743,7 @@
                 expect(msg_obj.get('message')).toEqual(msgtext);
                 expect(msg_obj.get('fullname')).toEqual(_converse.xmppstatus.get('fullname'));
                 expect(msg_obj.get('sender')).toEqual('me');
-                expect(msg_obj.get('delayed')).toEqual(false);
+                expect(msg_obj.get('is_delayed')).toEqual(false);
                 // Now check that the message appears inside the chatbox in the DOM
                 var $chat_content = $(chatboxview.el).find('.chat-content');
                 var msg_txt = $chat_content.find('.chat-msg').find('.chat-msg-text').text();
@@ -901,7 +899,7 @@
                 expect(msg_obj.get('message')).toEqual(message);
                 expect(msg_obj.get('fullname')).toEqual(contact_name);
                 expect(msg_obj.get('sender')).toEqual('them');
-                expect(msg_obj.get('delayed')).toEqual(true);
+                expect(msg_obj.get('is_delayed')).toEqual(true);
 
                 return test_utils.waitUntil(() => chatbox.vcard.get('fullname') === 'Candice van der Knijff')
                 .then(function () {
@@ -930,7 +928,7 @@
                     expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
                     // Check that there is a <time> element, with the required
                     // props.
-                    expect($chat_content[0].querySelectorAll('time').length).toEqual(2); // There are now two time elements
+                    expect($chat_content[0].querySelectorAll('time.separator-text').length).toEqual(2); // There are now two time elements
 
                     var message_date = new Date();
                     $day = $chat_content.find('.date-separator:last');
@@ -947,7 +945,7 @@
                     expect(msg_obj.get('message')).toEqual(message);
                     expect(msg_obj.get('fullname')).toEqual(contact_name);
                     expect(msg_obj.get('sender')).toEqual('them');
-                    expect(msg_obj.get('delayed')).toEqual(false);
+                    expect(msg_obj.get('is_delayed')).toEqual(false);
                     msg_txt = $chat_content.find('.chat-msg').last().find('.chat-msg-text').text();
                     expect(msg_txt).toEqual(message);
 
@@ -1069,6 +1067,43 @@
             done();
         }));
 
+        it("will render newlines", mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {}, function (done, _converse) {
+            test_utils.createContacts(_converse, 'current');
+            const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+            test_utils.openChatBoxFor(_converse, contact_jid);
+
+            let stanza = Strophe.xmlHtmlNode(
+                "<message from='"+contact_jid+"'"+
+                "         type='chat'"+
+                "         to='dummy@localhost/resource'>"+
+                "    <body>Hey\nHave you heard the news?</body>"+
+                "</message>").firstChild;
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
+
+            const view = _converse.chatboxviews.get(contact_jid);
+            const chat_content = view.el.querySelector('.chat-content');
+            expect(chat_content.querySelector('.chat-msg-text').innerHTML).toBe('Hey<br>Have you heard the news?');
+
+            stanza = Strophe.xmlHtmlNode(
+                "<message from='"+contact_jid+"'"+
+                "         type='chat'"+
+                "         to='dummy@localhost/resource'>"+
+                "    <body>Hey\n\n\nHave you heard the news?</body>"+
+                "</message>").firstChild;
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
+            expect(chat_content.querySelector('.message:last-child .chat-msg-text').innerHTML).toBe('Hey<br><br>Have you heard the news?');
+
+            stanza = Strophe.xmlHtmlNode(
+                "<message from='"+contact_jid+"'"+
+                "         type='chat'"+
+                "         to='dummy@localhost/resource'>"+
+                "    <body>Hey\nHave you heard\nthe news?</body>"+
+                "</message>").firstChild;
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
+            expect(chat_content.querySelector('.message:last-child .chat-msg-text').innerHTML).toBe('Hey<br>Have you heard<br>the news?');
+            done();
+        }));
+
         it("will render images from their URLs",
             mock.initConverseWithPromises(
                 null, ['rosterGroupsFetched'], {},
@@ -1083,12 +1118,12 @@
             spyOn(view.model, 'sendMessage').and.callThrough();
             test_utils.sendMessage(view, message);
 
-            test_utils.waitUntil(function () {
-                return view.el.querySelectorAll('.chat-content .chat-image').length;
-            }, 1000).then(function () {
+            test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length)
+            .then(() => {
                 expect(view.model.sendMessage).toHaveBeenCalled();
                 var msg = $(view.el).find('.chat-content .chat-msg').last().find('.chat-msg-text');
                 expect(msg.html().trim()).toEqual(
+                    '<!-- src/templates/image.html -->\n'+
                     '<a href="'+base_url+'/logo/conversejs-filled.svg" target="_blank" rel="noopener"><img class="chat-image img-thumbnail"'+
                     ' src="' + message + '"></a>');
                 message += "?param1=val1&param2=val2";
@@ -1096,10 +1131,11 @@
                 return test_utils.waitUntil(function () {
                     return view.el.querySelectorAll('.chat-content .chat-image').length === 2;
                 }, 1000);
-            }).then(function () {
+            }).then(() => {
                 expect(view.model.sendMessage).toHaveBeenCalled();
                 var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg-text');
                 expect(msg.html().trim()).toEqual(
+                    '<!-- src/templates/image.html -->\n'+
                     '<a href="'+base_url+'/logo/conversejs-filled.svg?param1=val1&amp;param2=val2" target="_blank" rel="noopener"><img'+
                     ' class="chat-image img-thumbnail" src="'+message.replace(/&/g, '&amp;')+'"></a>')
 
@@ -1342,6 +1378,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you heard this funny audio?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/audio.html -->'+
                         '<audio controls=""><source src="http://localhost/audio.mp3" type="audio/mpeg"></audio>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/audio.mp3">Download audio file</a>');
 
@@ -1359,6 +1396,7 @@
                     expect(msg.innerHTML).toEqual('');
                     media = view.el.querySelector('.chat-msg:last-child .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/audio.html -->'+
                         '<audio controls=""><source src="http://localhost/audio.mp3" type="audio/mpeg"></audio>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/audio.mp3">Download audio file</a>');
                     done();
@@ -1392,6 +1430,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you seen this funny video?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/video.html -->'+
                         '<video controls=""><source src="http://localhost/video.mp4" type="video/mp4"></video>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/video.mp4">Download video file</a>');
 
@@ -1409,6 +1448,7 @@
                     expect(msg.innerHTML).toEqual('');
                     media = view.el.querySelector('.chat-msg:last-child .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/video.html -->'+
                         '<video controls=""><source src="http://localhost/video.mp4" type="video/mp4"></video>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/video.mp4">Download video file</a>');
                     done();
@@ -1442,6 +1482,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you downloaded this funny file?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/file.html -->'+
                         '<a target="_blank" rel="noopener" href="http://localhost/funny.pdf">Download: "funny.pdf</a>');
                     done();
                 });
@@ -1476,6 +1517,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you seen this funny image?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/image.html -->'+
                         '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                             '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg">'+
                         '</a>');

+ 2 - 2
spec/minchats.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $msg = converse.env.$msg;
 

+ 2 - 2
spec/notification.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils", "utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils, utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $msg = converse.env.$msg;

+ 2 - 2
spec/omemo.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var Strophe = converse.env.Strophe;
     var b64_sha1 = converse.env.b64_sha1;
     var $iq = converse.env.$iq;

+ 85 - 49
spec/otr.js

@@ -1,72 +1,108 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var Strophe = converse.env.Strophe;
     var b64_sha1 = converse.env.b64_sha1;
     var $pres = converse.env.$pres;
     var _ = converse.env._;
 
-    describe("A chatbox with an active OTR session", function() {
-
-        it("will not show the spoiler toolbar button",
+    describe("A chatbox", function() {
+    
+        it("contains a button for starting an encrypted chat session",
             mock.initConverseWithPromises(
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
 
+            var timeout = true, $toolbar, view;
             test_utils.createContacts(_converse, 'current');
-            var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
-
-            // XXX: We need to send a presence from the contact, so that we
-            // have a resource, that resource is then queried to see
-            // whether Strophe.NS.SPOILER is supported, in which case
-            // the spoiler button will appear.
-            var presence = $pres({
-                'from': contact_jid+'/phone',
-                'to': 'dummy@localhost'
+            test_utils.openControlBox();
+
+            test_utils.waitUntil(function () {
+                return $(_converse.rosterview.el).find('.roster-group').length;
+            }, 300).then(function () {
+                // TODO: More tests can be added here...
+                var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
+                test_utils.openChatBoxFor(_converse, contact_jid);
+                view = _converse.chatboxviews.get(contact_jid);
+                $toolbar = $(view.el).find('ul.chat-toolbar');
+                expect($toolbar.find('.toggle-otr').length).toBe(1);
+                // Register spies
+                spyOn(view, 'toggleOTRMenu').and.callThrough();
+                view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
+
+                timeout = false;
+                $toolbar[0].querySelector('.toggle-otr').click();
+                return test_utils.waitUntil(function () {
+                    return view.el.querySelector('.otr-menu').offsetHeight;
+                }, 300)
+            }).then(function () {
+                expect(view.toggleOTRMenu).toHaveBeenCalled();
+                done();
             });
-            _converse.connection._dataRecv(test_utils.createRequest(presence));
-            test_utils.openChatBoxFor(_converse, contact_jid);
+        }));
 
-            test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
-                var spoiler_toggle;
-                var view = _converse.chatboxviews.get(contact_jid);
-                spyOn(view, 'addSpoilerButton').and.callThrough();
-                view.model.set('otr_status', 1);
+        describe("with an active OTR session", function() {
 
-                test_utils.waitUntil(function () {
-                    return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).toBe(null);
+            it("will not show the spoiler toolbar button",
+                mock.initConverseWithPromises(
+                    null, ['rosterGroupsFetched'], {},
+                    function (done, _converse) {
 
-                    view.model.set('otr_status', 3);
+                test_utils.createContacts(_converse, 'current');
+                var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+
+                // XXX: We need to send a presence from the contact, so that we
+                // have a resource, that resource is then queried to see
+                // whether Strophe.NS.SPOILER is supported, in which case
+                // the spoiler button will appear.
+                var presence = $pres({
+                    'from': contact_jid+'/phone',
+                    'to': 'dummy@localhost'
+                });
+                _converse.connection._dataRecv(test_utils.createRequest(presence));
+                test_utils.openChatBoxFor(_converse, contact_jid);
 
-                    return test_utils.waitUntil(function () {
-                        return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
-                    });
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).not.toBe(null);
+                test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
+                    var spoiler_toggle;
+                    var view = _converse.chatboxviews.get(contact_jid);
+                    spyOn(view, 'addSpoilerButton').and.callThrough();
+                    view.model.set('otr_status', 1);
 
-                    view.model.set('otr_status', 2);
-                    return test_utils.waitUntil(function () {
+                    test_utils.waitUntil(function () {
                         return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).toBe(null);
+
+                        view.model.set('otr_status', 3);
+
+                        return test_utils.waitUntil(function () {
+                            return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                        });
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).not.toBe(null);
+
+                        view.model.set('otr_status', 2);
+                        return test_utils.waitUntil(function () {
+                            return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                        });
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).toBe(null);
+
+                        view.model.set('otr_status', 4);
+                        return test_utils.waitUntil(function () {
+                            return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                        });
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).not.toBe(null);
+                        done();
                     });
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).toBe(null);
-
-                    view.model.set('otr_status', 4);
-                    return test_utils.waitUntil(function () {
-                        return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
-                    });
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).not.toBe(null);
-                    done();
                 });
-            });
-        }));
+            }));
+        });
     });
 
     describe("The OTR module", function() {

+ 1 - 1
spec/ping.js

@@ -1,5 +1,5 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils", "converse-ping"], factory);
+    define(["jasmine", "mock", "test-utils"], factory);
 } (this, function (jasmine, mock, test_utils) {
     "use strict";
 

+ 3 - 3
spec/presence.js

@@ -4,15 +4,15 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
         "mock",
         "test-utils",
-        "lodash"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils, _) {
+    ], factory);
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
     var $pres = converse.env.$pres;
+    var _ = converse.env._;
     var u = converse.env.utils;
     // See: https://xmpp.org/rfcs/rfc3921.html
 

+ 3 - 2
spec/profiling.js

@@ -1,8 +1,9 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils", "utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils, u) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $iq = converse.env.$iq;
+    var u = converse.env.utils;
 
     describe("Profiling", function() {
         xit("adds hundreds of contacts to the roster",

+ 2 - 3
spec/protocol.js

@@ -2,10 +2,9 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
@@ -210,7 +209,7 @@
                      *  </iq>
                      */
                     spyOn(_converse.roster, "updateContact").and.callThrough();
-                    stanza = $iq({'type': 'set', 'from': 'dummy@localhost'})
+                    stanza = $iq({'type': 'set', 'from': _converse.connection.jid})
                         .c('query', {'xmlns': 'jabber:iq:roster'})
                         .c('item', {
                             'jid': 'contact@example.org',

+ 164 - 0
spec/push.js

@@ -0,0 +1,164 @@
+(function (root, factory) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
+    "use strict";
+    var $iq = converse.env.$iq;
+    var Strophe = converse.env.Strophe;
+    var _ = converse.env._;
+
+    describe("XEP-0357 Push Notifications", function () {
+
+        it("can be enabled",
+            mock.initConverseWithPromises(null,
+                ['rosterGroupsFetched'], {
+                    'push_app_servers': [{
+                        'jid': 'push-5@client.example',
+                        'node': 'yxs32uqsflafdk3iuqo'
+                    }]
+                }, function (done, _converse) {
+
+            const IQ_stanzas = _converse.connection.IQ_stanzas;
+            let stanza;
+
+            expect(_converse.session.get('push_enabled')).toBeFalsy();
+
+            test_utils.waitUntilDiscoConfirmed(
+                _converse, _converse.push_app_servers[0].jid,
+                [{'category': 'pubsub', 'type':'push'}],
+                ['urn:xmpp:push:0'], [], 'info')
+            .then(() => test_utils.waitUntilDiscoConfirmed(
+                    _converse,
+                    _converse.bare_jid,
+                    [{'category': 'account', 'type':'registered'}],
+                    ['urn:xmpp:push:0'], [], 'info'))
+            .then(() => {
+                return test_utils.waitUntil(() => {
+                    const node = _.filter(IQ_stanzas, function (iq) {
+                        return iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]');
+                    }).pop();
+                    if (node) {
+                        stanza = node.nodeTree;
+                        return true;
+                    }
+                })
+            }).then(() => {
+                expect(stanza.outerHTML).toEqual(
+                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                        '<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
+                    '</iq>'
+                )
+                _converse.connection._dataRecv(test_utils.createRequest($iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                })));
+                return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
+            }).then(() => {
+                done();
+            }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+        }));
+
+        it("can be disabled",
+            mock.initConverseWithPromises(null,
+                ['rosterGroupsFetched'], {
+                    'push_app_servers': [{
+                        'jid': 'push-5@client.example',
+                        'node': 'yxs32uqsflafdk3iuqo',
+                        'disable': true
+                    }]
+                }, function (done, _converse) {
+
+            const IQ_stanzas = _converse.connection.IQ_stanzas;
+            let stanza;
+
+            expect(_converse.session.get('push_enabled')).toBeFalsy();
+
+            test_utils.waitUntilDiscoConfirmed(
+                _converse,
+                _converse.bare_jid,
+                [{'category': 'account', 'type':'registered'}],
+                ['urn:xmpp:push:0'], [], 'info')
+            .then(() => {
+                return test_utils.waitUntil(() => {
+                    const node = _.filter(IQ_stanzas, function (iq) {
+                        return iq.nodeTree.querySelector('iq[type="set"] disable[xmlns="urn:xmpp:push:0"]');
+                    }).pop();
+                    if (node) {
+                        stanza = node.nodeTree;
+                        return true;
+                    }
+                })
+            }).then(() => {
+                expect(stanza.outerHTML).toEqual(
+                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                        '<disable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
+                    '</iq>'
+                )
+                _converse.connection._dataRecv(test_utils.createRequest($iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                })));
+                return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
+            }).then(() => {
+                done();
+            }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+        }));
+
+
+        it("can require a secret token to be included",
+            mock.initConverseWithPromises(null,
+                ['rosterGroupsFetched'], {
+                    'push_app_servers': [{
+                        'jid': 'push-5@client.example',
+                        'node': 'yxs32uqsflafdk3iuqo',
+                        'secret': 'eruio234vzxc2kla-91'
+                    }]
+                }, function (done, _converse) {
+
+            const IQ_stanzas = _converse.connection.IQ_stanzas;
+            let stanza;
+            expect(_converse.session.get('push_enabled')).toBeFalsy();
+
+            test_utils.waitUntilDiscoConfirmed(
+                _converse, _converse.push_app_servers[0].jid,
+                [{'category': 'pubsub', 'type':'push'}],
+                ['urn:xmpp:push:0'], [], 'info')
+            .then(() => test_utils.waitUntilDiscoConfirmed(
+                    _converse,
+                    _converse.bare_jid,
+                    [{'category': 'account', 'type':'registered'}],
+                    ['urn:xmpp:push:0'], [], 'info'))
+            .then(() => {
+                return test_utils.waitUntil(() => {
+                    const node = _.filter(IQ_stanzas, function (iq) {
+                        return iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]');
+                    }).pop();
+                    if (node) {
+                        stanza = node.nodeTree;
+                        return true;
+                    }
+                })
+            }).then(() => {
+                expect(stanza.outerHTML).toEqual(
+                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                        '<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo">'+
+                            '<x xmlns="jabber:x:data" type="submit">'+
+                                '<field var="FORM_TYPE"><value>http://jabber.org/protocol/pubsub#publish-options</value></field>'+
+                                '<field var="secret"><value>eruio234vzxc2kla-91</value></field>'+
+                            '</x>'+
+                        '</enable>'+
+                    '</iq>'
+                )
+                _converse.connection._dataRecv(test_utils.createRequest($iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                })));
+                return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
+            }).then(() => {
+                done();
+            }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+        }));
+    });
+}));

+ 20 - 6
spec/register.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
     var _ = converse.env._;
@@ -264,10 +264,24 @@
                 registerview.el.querySelector('input[type=submit]').click();
 
                 expect(_converse.connection.send).toHaveBeenCalled();
-                var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree());
-                expect($stanza.children('query').children().length).toBe(1);
-                expect($stanza.children('query').children().children().length).toBe(3);
-                expect($stanza.children('query').children().children()[0].tagName).toBe('field');
+                stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
+                expect(stanza.outerHTML.trim().replace(/(\n|\s{2,})/g, '')).toEqual(
+                    '<iq type="set" id="'+stanza.getAttribute('id')+'" xmlns="jabber:client">'+
+                        '<query xmlns="jabber:iq:register">'+
+                            '<x xmlns="jabber:x:data" type="submit">'+
+                                '<field xmlns="http://www.w3.org/1999/xhtml" var="username">'+
+                                    '<value>testusername</value>'+
+                                '</field>'+
+                                '<field xmlns="http://www.w3.org/1999/xhtml" var="password">'+
+                                    '<value>testpassword</value>'+
+                                '</field>'+
+                                '<field xmlns="http://www.w3.org/1999/xhtml" var="email">'+
+                                    '<value>test@email.local</value>'+
+                                '</field>'+
+                            '</x>'+
+                        '</query>'+
+                    '</iq>'
+                );
                 done();
             });
         }));

+ 106 - 5
spec/roomslist.js

@@ -1,13 +1,17 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "converse-roomslist", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, roomslist, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $msg = converse.env.$msg;
+    var $iq = converse.env.$iq;
+    var $pres = converse.env.$pres;
     var Promise = converse.env.Promise;
+    var Strophe = converse.env.Strophe;
+    var u = converse.env.utils;
 
-    describe("The converse-roomslist plugin", function () {
+    describe("A list of open rooms", function () {
 
-        it("is shown under a list of open rooms in the \"Rooms\" panel", mock.initConverseWithPromises(
+        it("is shown in the \"Rooms\" panel", mock.initConverseWithPromises(
             null, ['rosterGroupsFetched'],
             { allow_bookmarks: false // Makes testing easier, otherwise we
                                      // have to mock stanza traffic.
@@ -50,7 +54,104 @@
         ));
     });
 
-    describe("An room shown in the rooms list", function () {
+    describe("A room shown in the rooms list", function () {
+
+        it("has an info icon which opens a details modal when clicked", mock.initConverseWithPromises(
+            null, ['rosterGroupsFetched'],
+            { whitelisted_plugins: ['converse-roomslist'],
+              allow_bookmarks: false // Makes testing easier, otherwise we
+                                     // have to mock stanza traffic.
+            }, function (done, _converse) {
+
+            test_utils.openControlBox();
+            _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
+            const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
+            const last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree;
+            const IQ_id = last_stanza.getAttribute('id');
+            const features_stanza = $iq({
+                    'from': 'coven@chat.shakespeare.lit',
+                    'id': IQ_id,
+                    'to': 'dummy@localhost/desktop',
+                    'type': 'result'
+                })
+                .c('query', { 'xmlns': 'http://jabber.org/protocol/disco#info'})
+                    .c('identity', {
+                        'category': 'conference',
+                        'name': 'A Dark Cave',
+                        'type': 'text'
+                    }).up()
+                    .c('feature', {'var': 'http://jabber.org/protocol/muc'}).up()
+                    .c('feature', {'var': 'muc_passwordprotected'}).up()
+                    .c('feature', {'var': 'muc_hidden'}).up()
+                    .c('feature', {'var': 'muc_temporary'}).up()
+                    .c('feature', {'var': 'muc_open'}).up()
+                    .c('feature', {'var': 'muc_unmoderated'}).up()
+                    .c('feature', {'var': 'muc_nonanonymous'}).up()
+                    .c('feature', {'var': 'urn:xmpp:mam:0'}).up()
+                    .c('x', { 'xmlns':'jabber:x:data', 'type':'result'})
+                        .c('field', {'var':'FORM_TYPE', 'type':'hidden'})
+                            .c('value').t('http://jabber.org/protocol/muc#roominfo').up().up()
+                        .c('field', {'type':'text-single', 'var':'muc#roominfo_description', 'label':'Description'})
+                            .c('value').t('This is the description').up().up()
+                        .c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
+                            .c('value').t(0);
+            _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
+
+            test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING)
+            .then(function () {
+                var presence = $pres({
+                        to: _converse.connection.jid,
+                        from: 'coven@chat.shakespeare.lit/some1',
+                        id: 'DC352437-C019-40EC-B590-AF29E879AF97'
+                }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
+                    .c('item').attrs({
+                        affiliation: 'member',
+                        jid: _converse.bare_jid,
+                        role: 'participant'
+                    }).up()
+                    .c('status').attrs({code:'110'});
+                _converse.connection._dataRecv(test_utils.createRequest(presence));
+
+                const room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
+                expect(room_els.length).toBe(1);
+                var info_el = _converse.rooms_list_view.el.querySelector(".room-info");
+                info_el.click();
+
+                const modal = view.model.room_details_modal;
+                return test_utils.waitUntil(() => u.isVisible(modal.el), 2000);
+            }).then(() => {
+                const modal = view.model.room_details_modal;
+                let els = modal.el.querySelectorAll('p.room-info');
+                expect(els[0].textContent).toBe("Room address (JID): coven@chat.shakespeare.lit")
+                expect(els[1].textContent).toBe("Name: A Dark Cave")
+                expect(els[2].textContent).toBe("Description: This is the description")
+                expect(els[3].textContent).toBe("Online users: 1")
+                const features_list = modal.el.querySelector('.features-list');
+                expect(features_list.textContent.replace(/(\n|\s{2,})/g, '')).toBe(
+                    'Password protected - This room requires a password before entry'+
+                    'Hidden - This room is not publicly searchable'+
+                    'Open - Anyone can join this room'+
+                    'Temporary - This room will disappear once the last person leaves'+
+                    'Not anonymous - All other room occupants can see your XMPP username'+
+                    'Not moderated - This room is not being moderated'
+                );
+                const presence = $pres({
+                        to: 'dummy@localhost/_converse.js-29092160',
+                        from: 'coven@chat.shakespeare.lit/newguy'
+                    })
+                    .c('x', {xmlns: Strophe.NS.MUC_USER})
+                    .c('item', {
+                        'affiliation': 'none',
+                        'jid': 'newguy@localhost/_converse.js-290929789',
+                        'role': 'participant'
+                    });
+                _converse.connection._dataRecv(test_utils.createRequest(presence));
+
+                els = modal.el.querySelectorAll('p.room-info');
+                expect(els[3].textContent).toBe("Online users: 2")
+                done();
+            });
+        }));
 
         it("can be closed", mock.initConverseWithPromises(
             null, ['rosterGroupsFetched'],

+ 64 - 2
spec/roster.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var Strophe = converse.env.Strophe;
     var $pres = converse.env.$pres;
@@ -35,6 +35,68 @@
 
     describe("The Contacts Roster", function () {
 
+        it("supports roster versioning",
+            mock.initConverseWithPromises(
+                null, ['rosterGroupsFetched'], {},
+                function (done, _converse) {
+
+            var IQ_stanzas = _converse.connection.IQ_stanzas;
+            var stanza;
+
+            test_utils.waitUntil(() => {
+                const node = _.filter(IQ_stanzas, function (iq) {
+                    return iq.nodeTree.querySelector('iq query[xmlns="jabber:iq:roster"]');
+                }).pop();
+                if (node) {
+                    stanza = node.nodeTree;
+                    return true;
+                }
+            }).then(() => {
+                expect(_converse.roster.data.get('version')).toBeUndefined();
+                expect(stanza.outerHTML).toBe(
+                    `<iq type="get" id="${stanza.getAttribute('id')}" xmlns="jabber:client">`+
+                        `<query xmlns="jabber:iq:roster"/>`+
+                    `</iq>`);
+                let result = $iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                }).c('query', {
+                    'xmlns': 'jabber:iq:roster',
+                    'ver': 'ver7'
+                }).c('item', {'jid': 'nurse@example.com'}).up()
+                  .c('item', {'jid': 'romeo@example.com'})
+                _converse.connection._dataRecv(test_utils.createRequest(result));
+                expect(_converse.roster.data.get('version')).toBe('ver7');
+                expect(_converse.roster.models.length).toBe(2);
+
+                _converse.roster.fetchFromServer();
+                stanza = _converse.connection.IQ_stanzas.pop().nodeTree;
+                expect(stanza.outerHTML).toBe(
+                    `<iq type="get" id="${stanza.getAttribute('id')}" xmlns="jabber:client">`+
+                        `<query xmlns="jabber:iq:roster" ver="ver7"/>`+
+                    `</iq>`);
+
+                result = $iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                });
+                _converse.connection._dataRecv(test_utils.createRequest(result));
+
+                const roster_push = $iq({
+                    'to': _converse.connection.jid,
+                    'type': 'set',
+                }).c('query', {'xmlns': 'jabber:iq:roster', 'ver': 'ver34'})
+                    .c('item', {'jid': 'romeo@example.com', 'subscription': 'remove'});
+                _converse.connection._dataRecv(test_utils.createRequest(roster_push));
+                expect(_converse.roster.data.get('version')).toBe('ver34');
+                expect(_converse.roster.models.length).toBe(1);
+                expect(_converse.roster.at(0).get('jid')).toBe('nurse@example.com');
+                done();
+            });
+        }));
+
         describe("The live filter", function () {
 
             it("will only appear when roster contacts flow over the visible area",

+ 2 - 9
spec/spoilers.js

@@ -1,13 +1,6 @@
 (function (root, factory) {
-    define([
-        "jasmine",
-        "utils",
-        "mock",
-        "converse-core",
-        "test-utils"
-        ], factory);
-} (this, function (jasmine, utils, mock, converse, test_utils) {
-
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var _ = converse.env._;
     var Strophe = converse.env.Strophe;
     var $msg = converse.env.$msg;

+ 1 - 3
spec/user-details-modal.js

@@ -1,12 +1,10 @@
 (function (root, factory) {
     define([
         "jasmine",
-        "utils",
-        "converse-core",
         "mock",
         "test-utils"
         ], factory);
-} (this, function (jasmine, utils, converse, mock, test_utils) {
+} (this, function (jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $iq = converse.env.$iq;

+ 2 - 2
spec/utils.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "converse-core"], factory);
-} (this, function (jasmine, converse) {
+    define(["jasmine"], factory);
+} (this, function (jasmine) {
     var utils = converse.env.utils,
         _ = converse.env._;
 

+ 2 - 2
spec/xmppstatus.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
 
     return describe("The XMPPStatus model", function() {
 

+ 0 - 9
src/build-esnext.js

@@ -1,9 +0,0 @@
-({
-    baseUrl: "../",
-    name: "almond",
-    mainConfigFile: 'config.js',
-    wrap: {
-        startFile: "start.frag",
-        endFile: "end.frag"
-    }
-});

+ 0 - 54
src/build-no-dependencies.js

@@ -1,54 +0,0 @@
-({
-    baseUrl: "../",
-    name: "almond",
-    out: "../dist/converse-no-dependencies.min.js",
-    include: ["converse"],
-    exclude: [
-        "awesomplete",
-        "backbone.browserStorage",
-        "backbone.overview",
-        "moment",
-        "strophe",
-        "strophe.rsm",
-        "strophe.ping",
-        "otr",
-        "lodash",
-        "lodash.converter",
-        "lodash.noconflict",
-        "es6-promise"
-    ],
-    paths: {
-        "backbone.vdomview":        "builds/backbone.vdomview",
-        "converse-bookmarks":       "builds/converse-bookmarks",
-        "converse-chatboxes":       "builds/converse-chatboxes",
-        "converse-chatview":        "builds/converse-chatview",
-        "converse-controlbox":      "builds/converse-controlbox",
-        "converse-core":            "builds/converse-core",
-        "converse-disco":           "builds/converse-disco",
-        "converse-dragresize":      "builds/converse-dragresize",
-        "converse-embedded":        "builds/converse-embedded",
-        "converse-fullscreen":      "builds/converse-fullscreen",
-        "converse-headline":        "builds/converse-headline",
-        "converse-mam":             "builds/converse-mam",
-        "converse-minimize":        "builds/converse-minimize",
-        "converse-muc":             "builds/converse-muc",
-        "converse-notification":    "builds/converse-notification",
-        "converse-otr":             "builds/converse-otr",
-        "converse-ping":            "builds/converse-ping",
-        "converse-profile":         "builds/converse-profile",
-        "converse-register":        "builds/converse-register",
-        "converse-roomslist":       "builds/converse-roomslist",
-        "converse-rosterview":      "builds/converse-rosterview",
-        "converse-singleton":       "builds/converse-singleton",
-        "converse-vcard":           "builds/converse-vcard",
-        "form-utils":               "builds/utils/form",
-        "i18n":                     "builds/i18n",
-        "utils":                    "builds/utils/core",
-        "muc-utils":                "builds/utils/muc"
-    },
-    wrap: {
-        startFile: "start.frag",
-        endFile: "end-no-dependencies.frag"
-    },
-    mainConfigFile: "config.js"
-});

+ 0 - 43
src/build.js

@@ -1,43 +0,0 @@
-({
-    baseUrl: "../",
-    name: "almond",
-    mainConfigFile: 'config.js',
-    paths: {
-        "backbone.vdomview":        "builds/backbone.vdomview",
-        "converse-bookmarks":       "builds/converse-bookmarks",
-        "converse-caps":            "builds/converse-caps",
-        "converse-chatboxes":       "builds/converse-chatboxes",
-        "converse-chatview":        "builds/converse-chatview",
-        "converse-controlbox":      "builds/converse-controlbox",
-        "converse-core":            "builds/converse-core",
-        "converse-disco":           "builds/converse-disco",
-        "converse-dragresize":      "builds/converse-dragresize",
-        "converse-embedded":        "builds/converse-embedded",
-        "converse-fullscreen":      "builds/converse-fullscreen",
-        "converse-headline":        "builds/converse-headline",
-        "converse-mam":             "builds/converse-mam",
-        "converse-message-view":    "builds/converse-message-view",
-        "converse-minimize":        "builds/converse-minimize",
-        "converse-modal":           "builds/converse-modal",
-        "converse-muc":             "builds/converse-muc",
-        "converse-muc-views":       "builds/converse-muc-views",
-        "converse-notification":    "builds/converse-notification",
-        "converse-otr":             "builds/converse-otr",
-        "converse-ping":            "builds/converse-ping",
-        "converse-profile":         "builds/converse-profile",
-        "converse-register":        "builds/converse-register",
-        "converse-roomslist":       "builds/converse-roomslist",
-        "converse-roster":          "builds/converse-roster",
-        "converse-rosterview":      "builds/converse-rosterview",
-        "converse-singleton":       "builds/converse-singleton",
-        "converse-vcard":           "builds/converse-vcard",
-        "form-utils":               "builds/utils/form",
-        "i18n":                     "builds/i18n",
-        "muc-utils":                "builds/utils/muc",
-        "utils":                    "builds/utils/core"
-    },
-    wrap: {
-        startFile: "start.frag",
-        endFile: "end.frag"
-    }
-});

+ 0 - 168
src/config.js

@@ -1,168 +0,0 @@
-var config;
-if (typeof(require) === 'undefined') {
-    /* XXX: Hack to work around r.js's stupid parsing.
-     * We want to save the configuration in a variable so that we can reuse it in
-     * tests/main.js.
-     */
-    // eslint-disable-next-line
-    require = { // jshint ignore:line
-        config: function (c) {
-            config = c;
-        }
-    };
-}
-
-require.config({
-    baseUrl: '.',
-    paths: {
-        "IPv6":                     "node_modules/urijs/src/IPv6",
-        "SecondLevelDomains":       "node_modules/urijs/src/SecondLevelDomains",
-        "almond":                   "node_modules/almond/almond",
-        "awesomplete":              "node_modules/awesomplete-avoid-xss/awesomplete",
-        "babel":                    "node_modules/requirejs-babel/babel-5.8.34.min",
-        "backbone":                 "node_modules/backbone/backbone",
-        "backbone.browserStorage":  "node_modules/backbone.browserStorage/backbone.browserStorage",
-        "backbone.nativeview":      "node_modules/backbone.nativeview/backbone.nativeview",
-        "backbone.noconflict":      "src/backbone.noconflict",
-        "backbone.orderedlistview": "node_modules/backbone.overview/dist/backbone.orderedlistview",
-        "backbone.overview":        "node_modules/backbone.overview/dist/backbone.overview",
-        "backbone.vdomview":        "node_modules/backbone.vdomview/dist/backbone.vdomview",
-        "bootstrap":                "node_modules/bootstrap.native/dist/bootstrap-native-v4",
-        "emojione":                 "node_modules/emojione/lib/js/emojione",
-        "es6-promise":              "node_modules/es6-promise/dist/es6-promise.auto",
-        "eventemitter":             "node_modules/otr/build/dep/eventemitter",
-        "filesize":                 "node_modules/filesize/lib/filesize",
-        "form-utils":               "src/utils/form",
-        "i18n":                     "src/i18n",
-        "jed":                      "node_modules/jed/jed",
-        "jquery":                   "src/jquery-stub",
-        "lodash":                   "node_modules/lodash/lodash",
-        "lodash.converter":         "3rdparty/lodash.fp",
-        "lodash.fp":                "src/lodash.fp",
-        "lodash.noconflict":        "src/lodash.noconflict",
-        "message-utils":            "src/utils/message",
-        "muc-utils":                "src/utils/muc",
-        "pluggable":                "node_modules/pluggable.js/dist/pluggable",
-        "polyfill":                 "src/polyfill",
-        "punycode":                 "node_modules/urijs/src/punycode",
-        "sizzle":                   "node_modules/sizzle/dist/sizzle",
-        "snabbdom":                 "node_modules/snabbdom/dist/snabbdom",
-        "snabbdom-attributes":      "node_modules/snabbdom/dist/snabbdom-attributes",
-        "snabbdom-class":           "node_modules/snabbdom/dist/snabbdom-class",
-        "snabbdom-dataset":         "node_modules/snabbdom/dist/snabbdom-dataset",
-        "snabbdom-eventlisteners":  "node_modules/snabbdom/dist/snabbdom-eventlisteners",
-        "snabbdom-props":           "node_modules/snabbdom/dist/snabbdom-props",
-        "snabbdom-style":           "node_modules/snabbdom/dist/snabbdom-style",
-        "strophe":                  "node_modules/strophe.js/strophe",
-        "strophe.ping":             "node_modules/strophejs-plugin-ping/strophe.ping",
-        "strophe.rsm":              "node_modules/strophejs-plugin-rsm/strophe.rsm",
-        "text":                     "node_modules/text/text",
-        "tovnode":                  "node_modules/snabbdom/dist/tovnode",
-        "tpl":                      "node_modules/lodash-template-loader/loader",
-        "underscore":               "src/underscore-shim",
-        "uri":                      "node_modules/urijs/src/URI",
-        "utils":                    "src/utils/core",
-        "vdom-parser":              "node_modules/vdom-parser/dist",
-        "xss":                      "node_modules/xss/dist/xss",
-        "xss.noconflict":           "src/xss.noconflict",
-
-        // OMEMO/libsignal requirements
-        "Long":                     "3rdparty/long",
-        "protobuf":                 "3rdparty/protobuf",
-        "bytebuffer":               "3rdparty/bytebuffer",
-        "libsignal":                "3rdparty/libsignal-protocol-javascript/dist/libsignal-protocol",
-
-        // Converse
-        "converse":                 "src/converse",
-
-        "converse-bookmarks":       "src/converse-bookmarks",
-        "converse-caps":            "src/converse-caps",
-        "converse-chatboxes":       "src/converse-chatboxes",
-        "converse-chatview":        "src/converse-chatview",
-        "converse-controlbox":      "src/converse-controlbox",
-        "converse-core":            "src/converse-core",
-        "converse-disco":           "src/converse-disco",
-        "converse-dragresize":      "src/converse-dragresize",
-        "converse-embedded":        "src/converse-embedded",
-        "converse-fullscreen":      "src/converse-fullscreen",
-        "converse-headline":        "src/converse-headline",
-        "converse-mam":             "src/converse-mam",
-        "converse-message-view":    "src/converse-message-view",
-        "converse-minimize":        "src/converse-minimize",
-        "converse-modal":           "src/converse-modal",
-        "converse-muc":             "src/converse-muc",
-        "converse-muc-views":       "src/converse-muc-views",
-        "converse-notification":    "src/converse-notification",
-        "converse-omemo":           "src/converse-omemo",
-        "converse-otr":             "src/converse-otr",
-        "converse-ping":            "src/converse-ping",
-        "converse-profile":         "src/converse-profile",
-        "converse-register":        "src/converse-register",
-        "converse-roomslist":       "src/converse-roomslist",
-        "converse-roster":          "src/converse-roster",
-        "converse-rosterview":      "src/converse-rosterview",
-        "converse-singleton":       "src/converse-singleton",
-        "converse-vcard":           "src/converse-vcard",
-
-        // Off-the-record-encryption
-        // "bigint":               "node_modules/otr/build/dep/bigint",
-        "bigint":               "3rdparty/bigint",
-        "crypto":               "node_modules/otr/build/dep/crypto",
-        "salsa20":              "node_modules/otr/build/dep/salsa20",
-        "otr":                  "node_modules/otr/build/otr",
-    },
-
-    packages: [{
-        'name': 'moment',
-        'location': 'node_modules/moment',
-        'main': 'moment'
-    }],
-
-    map: {
-        // '*' means all modules will get the '*.noconflict' version
-        // as their dependency.
-        '*': {
-            'backbone': 'backbone.noconflict',
-            'lodash': 'lodash.noconflict'
-         },
-        // '*.noconflict' wants the real module
-        // If this line was not here, there would
-        // be an unresolvable cyclic dependency.
-        'backbone.noconflict': { 'backbone': 'backbone' },
-        'lodash.noconflict': { 'lodash': 'lodash' }
-    },
-
-    lodashLoader: {
-        // Configuration for requirejs-tpl
-        // Use Mustache style syntax for variable interpolation
-        root: "src/templates/",
-        templateSettings: {
-            "escape": /\{\{\{([\s\S]+?)\}\}\}/g,
-            "evaluate": /\{\[([\s\S]+?)\]\}/g,
-            "interpolate": /\{\{([\s\S]+?)\}\}/g,
-            // By default, template places the values from your data in the
-            // local scope via the with statement. However, you can specify
-            // a single variable name with the variable setting. This can
-            // significantly improve the speed at which a template is able
-            // to render.
-            "variable": 'o'
-        }
-    },
-
-    // define module dependencies for modules not using define
-    shim: {
-        'backbone.orderedlistview': { deps: ['backbone.nativeview'] },
-        'backbone.overview':        { deps: ['backbone.nativeview'] },
-        'backbone.vdomview':        { deps: ['backbone.nativeview'] },
-        'awesomplete':              { exports: 'Awesomplete'},
-        'emojione':                 { exports: 'emojione'},
-        'xss':  {
-            'init': function (xss_noconflict) {
-                return {
-                    filterXSS: window.filterXSS,
-                    filterCSS: window.filterCSS
-                }
-            }
-        }
-    }
-});

+ 7 - 8
src/converse-bookmarks.js

@@ -12,10 +12,10 @@
 (function (root, factory) {
     define(["converse-core",
             "converse-muc",
-            "tpl!chatroom_bookmark_form",
-            "tpl!chatroom_bookmark_toggle",
-            "tpl!bookmark",
-            "tpl!bookmarks_list"
+            "templates/chatroom_bookmark_form.html",
+            "templates/chatroom_bookmark_toggle.html",
+            "templates/bookmark.html",
+            "templates/bookmarks_list.html"
         ],
         factory);
 }(this, function (
@@ -337,10 +337,9 @@
                         'type': 'get',
                     }).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
                         .c('items', {'node': 'storage:bookmarks'});
-                    _converse.connection.sendIQ(
-                        stanza,
-                        _.bind(this.onBookmarksReceived, this, deferred),
-                        _.bind(this.onBookmarksReceivedError, this, deferred)
+                    _converse.api.sendIQ(stanza)
+                        .then((iq) => this.onBookmarksReceived(deferred, iq))
+                        .catch((iq) => this.onBookmarksReceivedError(deferred, iq)
                     );
                 },
 

+ 83 - 73
src/converse-chatboxes.js

@@ -9,9 +9,9 @@
         "converse-core",
         "emojione",
         "filesize",
-        "tpl!chatboxes",
+        "templates/chatboxes.html",
         "backbone.overview",
-        "form-utils"
+        "utils/form"
     ], factory);
 }(this, function (converse, emojione, filesize, tpl_chatboxes) {
     "use strict";
@@ -29,18 +29,6 @@
             // plugin architecture they will replace existing methods on the
             // relevant objects or classes.
 
-            disconnect: function () {
-                const { _converse } = this.__super__;
-                _converse.chatboxviews.closeAllChatBoxes();
-                return this.__super__.disconnect.apply(this, arguments);
-            },
-
-            logOut: function () {
-                const { _converse } = this.__super__;
-                _converse.chatboxviews.closeAllChatBoxes();
-                return this.__super__.logOut.apply(this, arguments);
-            },
-
             initStatus: function (reconnecting) {
                 const { _converse } = this.__super__;
                 if (!reconnecting) {
@@ -62,7 +50,9 @@
             // Refer to docs/source/configuration.rst for explanations of these
             // configuration settings.
             _converse.api.settings.update({
-                auto_join_private_chats: [],
+                'filter_by_resource': false,
+                'auto_join_private_chats': [],
+                'forward_messages': false,
             });
             _converse.api.promises.add([
                 'chatBoxesFetched',
@@ -110,17 +100,35 @@
                     }
                 },
 
-                setVCard () {
-                    if (this.get('type') === 'groupchat') {
-                        const chatbox = this.collection.chatbox,
-                              nick = Strophe.getResourceFromJid(this.get('from'));
-                        if (chatbox.get('nick') === nick) {
-                            this.vcard = _converse.xmppstatus.vcard;
-                        } else {
+                getVCardForChatroomOccupant () {
+                    const chatbox = this.collection.chatbox,
+                          nick = Strophe.getResourceFromJid(this.get('from'));
+
+                    if (chatbox.get('nick') === nick) {
+                        return _converse.xmppstatus.vcard;
+                    } else {
+                        let vcard;
+                        if (this.get('vcard_jid')) {
+                            vcard = _converse.vcards.findWhere({'jid': this.get('vcard_jid')});
+                        }
+                        if (!vcard) {
+                            let jid;
                             const occupant = chatbox.occupants.findWhere({'nick': nick});
-                            const jid = (occupant && occupant.get('jid')) ? occupant.get('jid') : this.get('from');
-                            this.vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
+                            if (occupant && occupant.get('jid')) {
+                                jid = occupant.get('jid');
+                                this.save({'vcard_jid': jid}, {'silent': true});
+                            } else {
+                                jid = this.get('from');
+                            }
+                            vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
                         }
+                        return vcard;
+                    }
+                },
+
+                setVCard () {
+                    if (this.get('type') === 'groupchat') {
+                        this.vcard = this.getVCardForChatroomOccupant();
                     } else {
                         const jid = this.get('from');
                         this.vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
@@ -231,13 +239,16 @@
 
 
             _converse.ChatBox = _converse.ModelWithVCardAndPresence.extend({
-                defaults: {
-                    'bookmarked': false,
-                    'chat_state': undefined,
-                    'num_unread': 0,
-                    'type': 'chatbox',
-                    'message_type': 'chat',
-                    'url': ''
+                defaults () {
+                    return {
+                        'bookmarked': false,
+                        'chat_state': undefined,
+                        'num_unread': 0,
+                        'type': 'chatbox',
+                        'message_type': 'chat',
+                        'url': '',
+                        'hidden': _.includes(['mobile', 'fullscreen'], _converse.view_mode)
+                    }
                 },
 
                 initialize () {
@@ -401,12 +412,17 @@
 
                 getMessageBody (message) {
                     const type = message.getAttribute('type');
-                    return (type === 'error') ?
-                        _.propertyOf(message.querySelector('error text'))('textContent') :
-                            _.propertyOf(message.querySelector('body'))('textContent');
+                    if (type === 'error') {
+                        const error = message.querySelector('error');
+                        return _.propertyOf(error.querySelector('text'))('textContent') ||
+                            __('Sorry, an error occured:') + ' ' + error.innerHTML;
+                    } else {
+                        return _.propertyOf(message.querySelector('body'))('textContent');
+                    }
+
                 },
 
-                getMessageAttributesFromStanza (message, delay, original_stanza) {
+                getMessageAttributesFromStanza (message, original_stanza) {
                     /* Parses a passed in message stanza and returns an object
                      * of attributes.
                      *
@@ -418,11 +434,11 @@
                      *      that contains the message stanza, if it was
                      *      contained, otherwise it's the message stanza itself.
                      */
-                    delay = delay || message.querySelector('delay');
-
                     const { _converse } = this.__super__,
                           { __ } = _converse,
-                          spoiler = message.querySelector(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`),
+                          archive = sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop(),
+                          spoiler = sizzle(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`, original_stanza).pop(),
+                          delay = sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, original_stanza).pop(),
                           chat_state = message.getElementsByTagName(_converse.COMPOSING).length && _converse.COMPOSING ||
                                 message.getElementsByTagName(_converse.PAUSED).length && _converse.PAUSED ||
                                 message.getElementsByTagName(_converse.INACTIVE).length && _converse.INACTIVE ||
@@ -430,13 +446,14 @@
                                 message.getElementsByTagName(_converse.GONE).length && _converse.GONE;
 
                     const attrs = {
-                        'type': message.getAttribute('type'),
                         'chat_state': chat_state,
-                        'delayed': !_.isNull(delay),
+                        'is_archived': !_.isNil(archive),
+                        'is_delayed': !_.isNil(delay),
+                        'is_spoiler': !_.isNil(spoiler),
                         'message': this.getMessageBody(message) || undefined,
                         'msgid': message.getAttribute('id'),
                         'time': delay ? delay.getAttribute('stamp') : moment().format(),
-                        'is_spoiler': !_.isNull(spoiler)
+                        'type': message.getAttribute('type')
                     };
                     if (attrs.type === 'groupchat') {
                         attrs.from = message.getAttribute('from');
@@ -466,14 +483,15 @@
                     return attrs;
                 },
 
-                createMessage (message, delay, original_stanza) {
+                createMessage (message, original_stanza) {
                     /* Create a Backbone.Message object inside this chat box
                      * based on the identified message stanza.
                      */
-                    const attrs = this.getMessageAttributesFromStanza.apply(this, arguments)
+                    const attrs = this.getMessageAttributesFromStanza(message, original_stanza);
                     const is_csn = u.isOnlyChatStateNotification(attrs);
-                    if (is_csn && attrs.delayed) {
-                        // No need showing old CSNs
+                    if (is_csn && (attrs.is_delayed || (attrs.type === 'groupchat' && Strophe.getResourceFromJid(attrs.from) == this.get('nick')))) {
+                        // XXX: MUC leakage
+                        // No need showing delayed or our own CSN messages
                         return;
                     } else if (!is_csn && !attrs.file && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
                         // TODO: handle <subject> messages (currently being done by ChatRoom)
@@ -483,7 +501,7 @@
                     }
                 },
 
-                newMessageWillBeHidden () {
+                isHidden () {
                     /* Returns a boolean to indicate whether a newly received
                      * message will be visible to the user or not.
                      */
@@ -500,7 +518,7 @@
                     if (_.isNull(stanza.querySelector('body'))) {
                         return; // The message has no text
                     }
-                    if (utils.isNewMessage(stanza) && this.newMessageWillBeHidden()) {
+                    if (utils.isNewMessage(stanza) && this.isHidden()) {
                         this.save({'num_unread': this.get('num_unread') + 1});
                         _converse.incrementMsgCounter();
                     }
@@ -524,12 +542,14 @@
                 },
 
                 registerMessageHandler () {
-                    _converse.connection.addHandler(
-                        this.onMessage.bind(this), null, 'message', 'chat'
-                    );
-                    _converse.connection.addHandler(
-                        this.onErrorMessage.bind(this), null, 'message', 'error'
-                    );
+                    _converse.connection.addHandler((stanza) => {
+                        this.onMessage(stanza);
+                        return true;
+                    }, null, 'message', 'chat');
+                    _converse.connection.addHandler((stanza) => {
+                        this.onErrorMessage(stanza);
+                        return true;
+                    }, null, 'message', 'error');
                 },
 
                 chatBoxMayBeShown (chatbox) {
@@ -547,29 +567,27 @@
                 },
 
                 onConnected () {
-                    this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.chatboxes-${_converse.bare_jid}`));
                     this.registerMessageHandler();
                     this.fetch({
-                        add: true,
-                        success: this.onChatBoxesFetched.bind(this)
+                        'add': true,
+                        'success': this.onChatBoxesFetched.bind(this)
                     });
                 },
 
                 onErrorMessage (message) {
                     /* Handler method for all incoming error message stanzas
                     */
-                    // TODO: we can likely just reuse "onMessage" below
                     const from_jid =  Strophe.getBareJidFromJid(message.getAttribute('from'));
                     if (utils.isSameBareJID(from_jid, _converse.bare_jid)) {
                         return true;
                     }
-                    // Get chat box, but only create a new one when the message has a body.
                     const chatbox = this.getChatBox(from_jid);
                     if (!chatbox) {
                         return true;
                     }
-                    chatbox.createMessage(message, null, message);
+                    chatbox.createMessage(message, message);
                     return true;
                 },
 
@@ -580,8 +598,7 @@
                      * Parameters:
                      *    (XMLElement) message - The incoming message stanza
                      */
-                    let contact_jid, delay, resource,
-                        from_jid = message.getAttribute('from'),
+                    let from_jid = message.getAttribute('from'),
                         to_jid = message.getAttribute('to');
 
                     const original_stanza = message,
@@ -610,12 +627,10 @@
                         const forwarded_from = forwarded_message.getAttribute('from');
                         if (is_carbon && Strophe.getBareJidFromJid(forwarded_from) !== from_jid) {
                             // Prevent message forging via carbons
-                            //
                             // https://xmpp.org/extensions/xep-0280.html#security
                             return true;
                         }
                         message = forwarded_message;
-                        delay = forwarded.querySelector('delay');
                         from_jid = message.getAttribute('from');
                         to_jid = message.getAttribute('to');
                     }
@@ -624,13 +639,12 @@
                         from_resource = Strophe.getResourceFromJid(from_jid),
                         is_me = from_bare_jid === _converse.bare_jid;
 
+                    let contact_jid;
                     if (is_me) {
                         // I am the sender, so this must be a forwarded message...
                         contact_jid = Strophe.getBareJidFromJid(to_jid);
-                        resource = Strophe.getResourceFromJid(to_jid);
                     } else {
                         contact_jid = from_bare_jid;
-                        resource = from_resource;
                     }
                     // Get chat box, but only create a new one when the message has a body.
                     const attrs = {
@@ -645,7 +659,7 @@
                             // Only create the message when we're sure it's not a
                             // duplicate
                             chatbox.incrementUnreadMsgCounter(original_stanza);
-                            chatbox.createMessage(message, delay, original_stanza);
+                            chatbox.createMessage(message, original_stanza);
                         }
                     }
                     _converse.emit('message', {'stanza': original_stanza, 'chatbox': chatbox});
@@ -700,9 +714,6 @@
                                 _converse.root.appendChild(el);
                             }
                         }
-                        if (_.includes(['mobile', 'fullscreen'], _converse.view_mode)) {
-                            el.classList.add('fullscreen');
-                        }
                         el.innerHTML = '';
                         this.setElement(el, false);
                     } else {
@@ -814,12 +825,11 @@
                 _converse.emit('chatBoxesInitialized');
             });
 
-            _converse.api.listen.on('beforeTearDown', () => {
-                _converse.chatboxes.remove(); // Don't call off(), events won't get re-registered upon reconnect.
-                delete _converse.chatboxes.browserStorage;
+            _converse.api.listen.on('clearSession', () => {
+                _converse.chatboxviews.closeAllChatBoxes();
             });
 
-            _converse.api.listen.on('statusInitialized', () => _converse.chatboxes.onConnected());
+            _converse.api.listen.on('presencesInitialized', () => _converse.chatboxes.onConnected());
             /************************ END Event Handlers ************************/
 
 

+ 33 - 26
src/converse-chatview.js

@@ -5,26 +5,25 @@
 // Licensed under the Mozilla Public License (MPLv2)
 
 (function (root, factory) {
-    define([
-            "converse-core",
+    define(["converse-core",
             "bootstrap",
             "emojione",
             "xss",
-            "tpl!action",
-            "tpl!chatbox",
-            "tpl!chatbox_head",
-            "tpl!chatbox_message_form",
-            "tpl!emojis",
-            "tpl!error_message",
-            "tpl!help_message",
-            "tpl!info",
-            "tpl!new_day",
-            "tpl!user_details_modal",
-            "tpl!toolbar_fileupload",
-            "tpl!spinner",
-            "tpl!spoiler_button",
-            "tpl!status_message",
-            "tpl!toolbar",
+            "templates/action.html",
+            "templates/chatbox.html",
+            "templates/chatbox_head.html",
+            "templates/chatbox_message_form.html",
+            "templates/emojis.html",
+            "templates/error_message.html",
+            "templates/help_message.html",
+            "templates/info.html",
+            "templates/new_day.html",
+            "templates/user_details_modal.html",
+            "templates/toolbar_fileupload.html",
+            "templates/spinner.html",
+            "templates/spoiler_button.html",
+            "templates/status_message.html",
+            "templates/toolbar.html",
             "converse-modal",
             "converse-chatboxes",
             "converse-message-view"
@@ -101,10 +100,11 @@
                 { __ } = _converse;
 
             _converse.api.settings.update({
-                'use_emojione': false,
                 'emojione_image_path': emojione.imagePathPNG,
+                'show_send_button': false,
                 'show_toolbar': true,
                 'time_format': 'HH:mm',
+                'use_emojione': false,
                 'visible_toolbar_buttons': {
                     'call': false,
                     'clear': true,
@@ -151,6 +151,7 @@
                     return tpl_emojis(
                         _.extend(
                             this.model.toJSON(), {
+                                '_': _,
                                 'transform': _converse.use_emojione ? emojione.shortnameToImage : emojione.shortnameToUnicode,
                                 'emojis_by_category': u.getEmojisByCategory(_converse, emojione),
                                 'toned_emojis': u.getTonedEmojis(_converse),
@@ -320,16 +321,17 @@
 
                 events: {
                     'change input.fileupload': 'onFileSelection',
+                    'click .chatbox-navback': 'showControlBox',
                     'click .close-chatbox-button': 'close',
-                    'click .show-user-details-modal': 'showUserDetailsModal',
                     'click .new-msgs-indicator': 'viewUnreadMessages',
                     'click .send-button': 'onFormSubmitted',
+                    'click .show-user-details-modal': 'showUserDetailsModal',
+                    'click .spoiler-toggle': 'toggleSpoilerMessage',
                     'click .toggle-call': 'toggleCall',
                     'click .toggle-clear': 'clearMessages',
                     'click .toggle-compose-spoiler': 'toggleComposeSpoilerMessage',
                     'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
                     'click .toggle-smiley': 'toggleEmojiMenu',
-                    'click .spoiler-toggle': 'toggleSpoilerMessage',
                     'click .upload-file': 'toggleFileUpload',
                     'keypress .chat-textarea': 'keyPressed',
                     'input .chat-textarea': 'inputChanged'
@@ -413,7 +415,15 @@
                     this.renderToolbar();
                 },
 
+                showControlBox () {
+                    // Used in mobile view, to navigate back to the controlbox
+                    const view = _converse.chatboxviews.get('controlbox');
+                    view.show();
+                    this.hide();
+                },
+
                 showUserDetailsModal (ev) {
+                    ev.preventDefault();
                     if (_.isUndefined(this.user_details_modal)) {
                         this.user_details_modal = new _converse.UserDetailsModal({model: this.model});
                     }
@@ -901,7 +911,7 @@
                 keyPressed (ev) {
                     /* Event handler for when a key is pressed in a chat box textarea.
                      */
-                    if (ev.keyCode === KEY.ENTER) {
+                    if (ev.keyCode === KEY.ENTER && !ev.shiftKey) {
                         this.onFormSubmitted(ev);
                     } else if (ev.keyCode !== KEY.FORWARD_SLASH && this.model.get('chat_state') !== _converse.COMPOSING) {
                         // Set chat state to composing if keyCode is not a forward-slash
@@ -1075,10 +1085,7 @@
                 },
 
                 afterShown () {
-                    if (u.isPersistableModel(this.model)) {
-                        this.model.clearUnreadMsgCounter();
-                        this.model.save();
-                    }
+                    this.model.clearUnreadMsgCounter();
                     this.setChatState(_converse.ACTIVE);
                     this.renderEmojiPicker();
                     this.scrollDown();
@@ -1155,7 +1162,7 @@
                 },
 
                 onWindowStateChanged (state) {
-                    if (this.model.get('num_unread', 0) && !this.model.newMessageWillBeHidden()) {
+                    if (this.model.get('num_unread', 0) && !this.model.isHidden()) {
                         this.model.clearUnreadMsgCounter();
                     }
                 }

+ 6 - 6
src/converse-controlbox.js

@@ -10,10 +10,10 @@
     define(["converse-core",
             "bootstrap",
             "lodash.fp",
-            "tpl!converse_brand_heading",
-            "tpl!controlbox",
-            "tpl!controlbox_toggle",
-            "tpl!login_panel",
+            "templates/converse_brand_heading.html",
+            "templates/controlbox.html",
+            "templates/controlbox_toggle.html",
+            "templates/login_panel.html",
             "converse-chatview",
             "converse-rosterview",
             "converse-profile"
@@ -91,8 +91,8 @@
             //
             // New functions which don't exist yet can also be added.
 
-            _tearDown () {
-                this.__super__._tearDown.apply(this, arguments);
+            tearDown () {
+                this.__super__.tearDown.apply(this, arguments);
                 if (this.rosterview) {
                     // Removes roster groups
                     this.rosterview.model.off().reset();

File diff suppressed because it is too large
+ 6 - 8
src/converse-core.js


+ 53 - 13
src/converse-disco.js

@@ -36,24 +36,24 @@
                     this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
 
                     this.dataforms = new Backbone.Collection();
-                    this.dataforms.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.dataforms.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.dataforms-{this.get('jid')}`)
                     );
 
                     this.features = new Backbone.Collection();
-                    this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.features.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.features-${this.get('jid')}`)
                     );
                     this.features.on('add', this.onFeatureAdded, this);
 
                     this.identities = new Backbone.Collection();
-                    this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.identities.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.identities-${this.get('jid')}`)
                     );
                     this.fetchFeatures();
 
                     this.items = new _converse.DiscoEntities();
-                    this.items.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.items.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.disco-items-${this.get('jid')}`)
                     );
                     this.items.fetch();
@@ -125,7 +125,12 @@
                 },
 
                 queryInfo () {
-                    _converse.api.disco.info(this.get('jid'), null, this.onInfo.bind(this));
+                    _converse.api.disco.info(this.get('jid'), null)
+                        .then((stanza) => this.onInfo(stanza))
+                        .catch((iq) => {
+                            this.waitUntilFeaturesDiscovered.resolve();
+                            _converse.log(iq, Strophe.LogLevel.ERROR);
+                        });
                 },
 
                 onDiscoItems (stanza) {
@@ -137,7 +142,12 @@
                         }
                         const jid = item.getAttribute('jid');
                         if (_.isUndefined(this.items.get(jid))) {
-                            this.items.create({'jid': jid});
+                            const entity = _converse.disco_entities.get(jid);
+                            if (entity) {
+                                this.items.add(entity);
+                            } else {
+                                this.items.create({'jid': jid});
+                            }
                         }
                     });
                 },
@@ -216,12 +226,34 @@
                 return this;
             }
 
+            function initStreamFeatures () {
+                _converse.stream_features = new Backbone.Collection();
+                _converse.stream_features.browserStorage = new Backbone.BrowserStorage.session(
+                    b64_sha1(`converse.stream-features-${_converse.bare_jid}`)
+                );
+                _converse.stream_features.fetch({
+                    success (collection) {
+                        if (collection.length === 0 && _converse.connection.features) {
+                            _.forEach(
+                                _converse.connection.features.childNodes,
+                                (feature) => {
+                                    _converse.stream_features.create({
+                                        'name': feature.nodeName,
+                                        'xmlns': feature.getAttribute('xmlns')
+                                    });
+                                });
+                        }
+                    }
+                });
+                _converse.emit('streamFeaturesAdded');
+            }
+
             function initializeDisco () {
                 addClientFeatures();
                 _converse.connection.addHandler(onDiscoInfoRequest, Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);
 
                 _converse.disco_entities = new _converse.DiscoEntities();
-                _converse.disco_entities.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                _converse.disco_entities.browserStorage = new Backbone.BrowserStorage.session(
                     b64_sha1(`converse.disco-entities-${_converse.bare_jid}`)
                 );
 
@@ -235,6 +267,7 @@
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
             }
 
+            _converse.api.listen.on('sessionInitialized', initStreamFeatures);
             _converse.api.listen.on('reconnected', initializeDisco);
             _converse.api.listen.on('connected', initializeDisco);
 
@@ -290,6 +323,15 @@
                  * @namespace
                  */
                 'disco': {
+                    'stream': {
+                        'getFeature': function (name, xmlns) {
+                            if (_.isNil(name) || _.isNil(xmlns)) {
+                                throw new Error("name and xmlns need to be provided when calling disco.stream.getFeature");
+                            }
+                            return _converse.stream_features.findWhere({'name': name, 'xmlns': xmlns});
+                        }
+                    },
+
                     /**
                      * The "own" grouping
                      * @namespace
@@ -389,7 +431,7 @@
                         }
                     },
 
-                    'info' (jid, node, callback, errback, timeout) {
+                    'info' (jid, node) {
                         const attrs = {xmlns: Strophe.NS.DISCO_INFO};
                         if (node) {
                             attrs.node = node;
@@ -399,7 +441,7 @@
                             'to':jid,
                             'type':'get'
                         }).c('query', attrs);
-                        _converse.connection.sendIQ(info, callback, errback, timeout);
+                        return _converse.api.sendIQ(info);
                     },
 
                     'items' (jid, node, callback, errback, timeout) {
@@ -481,10 +523,8 @@
                          *    (String) entity_jid - The JID of the entity which might have the identity
                          */
                         return new Promise((resolve, reject) => {
-                            _converse.api.waitUntil('discoInitialized').then(() => {
-                                _converse.api.disco.entities.get(entity_jid, true)
-                                    .then((entity) => resolve(entity.getIdentity(category, type)));
-                            })
+                            _converse.api.disco.entities.get(entity_jid, true)
+                                .then((entity) => resolve(entity.getIdentity(category, type)));
                         }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
                     }
                 }

+ 1 - 1
src/converse-dragresize.js

@@ -8,7 +8,7 @@
 
 (function (root, factory) {
     define(["converse-core",
-            "tpl!dragresize",
+            "templates/dragresize.html",
             "converse-chatview",
             "converse-controlbox"
     ], factory);

+ 1 - 1
src/converse-fullscreen.js

@@ -8,7 +8,7 @@
 
 (function (root, factory) {
     define(["converse-core",
-            "tpl!inverse_brand_heading",
+            "templates/inverse_brand_heading.html",
             "converse-chatview",
             "converse-controlbox",
             "converse-muc",

+ 2 - 2
src/converse-headline.js

@@ -9,7 +9,7 @@
 (function (root, factory) {
     define([
             "converse-core",
-            "tpl!chatbox",
+            "templates/chatbox.html",
             "converse-chatview",
     ], factory);
 }(this, function (converse, tpl_chatbox) {
@@ -138,7 +138,7 @@
                         'type': 'headline',
                         'from': from_jid
                     });
-                    chatbox.createMessage(message, undefined, message);
+                    chatbox.createMessage(message, message);
                     _converse.emit('message', {'chatbox': chatbox, 'stanza': message});
                 }
                 return true;

+ 4 - 4
src/converse-mam.js

@@ -11,14 +11,14 @@
 (function (root, factory) {
     define(["sizzle",
             "converse-core",
-            "utils",
             "converse-disco",
             "strophe.rsm"
     ], factory);
-}(this, function (sizzle, converse, utils) {
+}(this, function (sizzle, converse) {
     "use strict";
     const CHATROOMS_TYPE = 'chatroom';
     const { Promise, Strophe, $iq, _, moment } = converse.env;
+    const u = converse.env.utils;
 
     const RSM_ATTRIBUTES = ['max', 'first', 'last', 'after', 'before', 'index', 'count'];
     // XEP-0313 Message Archive Management
@@ -128,7 +128,7 @@
             //
             // New functions which don't exist yet can also be added.
             ChatBox: {
-                getMessageAttributesFromStanza (message, delay, original_stanza) {
+                getMessageAttributesFromStanza (message, original_stanza) {
                     const attrs = this.__super__.getMessageAttributesFromStanza.apply(this, arguments);
                     const archive_id = getMessageArchiveID(original_stanza);
                     if (archive_id) {
@@ -153,7 +153,7 @@
                      */
                     if (this.disable_mam) { return; }
                     const { _converse } = this.__super__,
-                          most_recent_msg = utils.getMostRecentMessage(this.model);
+                          most_recent_msg = u.getMostRecentMessage(this.model);
 
                     if (_.isNil(most_recent_msg)) {
                         this.fetchArchivedMessages();

+ 9 - 8
src/converse-message-view.js

@@ -1,7 +1,7 @@
 // Converse.js
 // https://conversejs.org
 //
-// Copyright (c) 2012-2018, the Converse.js developers
+// Copyright (c) 2013-2018, the Converse.js developers
 // Licensed under the Mozilla Public License (MPLv2)
 
 (function (root, factory) {
@@ -10,12 +10,12 @@
         "xss",
         "emojione",
         "filesize",
-        "tpl!action",
-        "tpl!csn",
-        "tpl!file_progress",
-        "tpl!info",
-        "tpl!message",
-        "tpl!spoiler_message"
+        "templates/action.html",
+        "templates/csn.html",
+        "templates/file_progress.html",
+        "templates/info.html",
+        "templates/message.html",
+        "templates/spoiler_message.html"
     ], factory);
 }(this, function (
         converse,
@@ -145,6 +145,7 @@
                         msg_content.innerHTML = _.flow(
                             _.partial(u.geoUriToHttp, _, _converse.geouri_replacement),
                             u.addHyperlinks,
+                            u.renderNewLines,
                             _.partial(u.addEmoji, _converse, emojione, _)
                         )(text);
                     }
@@ -225,7 +226,7 @@
                 },
 
                 getExtraMessageClasses () {
-                    let extra_classes = this.model.get('delayed') && 'delayed' || '';
+                    let extra_classes = this.model.get('is_delayed') && 'delayed' || '';
                     if (this.model.get('type') === 'groupchat' && this.model.get('sender') === 'them') {
                         if (this.model.collection.chatbox.isUserMentioned(this.model.get('message'))) {
                             // Add special class to mark groupchat messages

+ 13 - 14
src/converse-minimize.js

@@ -8,10 +8,10 @@
 
 (function (root, factory) {
     define(["converse-core",
-            "tpl!chatbox_minimize",
-            "tpl!toggle_chats",
-            "tpl!trimmed_chat",
-            "tpl!chats_panel",
+            "templates/chatbox_minimize.html",
+            "templates/toggle_chats.html",
+            "templates/trimmed_chat.html",
+            "templates/chats_panel.html",
             "converse-chatview"
     ], factory);
 }(this, function (
@@ -52,16 +52,6 @@
             //
             // New functions which don't exist yet can also be added.
 
-            registerGlobalEventHandlers () {
-                const { _converse } = this.__super__;
-                window.addEventListener("resize", _.debounce(function (ev) {
-                    if (_converse.connection.connected) {
-                        _converse.chatboxviews.trimChats();
-                    }
-                }, 200));
-                return this.__super__.registerGlobalEventHandlers.apply(this, arguments);
-            },
-
             ChatBox: {
                 initialize () {
                     this.__super__.initialize.apply(this, arguments);
@@ -541,6 +531,15 @@
                 _converse.emit('minimizedChatsInitialized');
             }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
 
+
+            _converse.on('registeredGlobalEventHandlers', function () {
+                window.addEventListener("resize", _.debounce(function (ev) {
+                    if (_converse.connection.connected) {
+                        _converse.chatboxviews.trimChats();
+                    }
+                }, 200));
+            });
+
             _converse.on('controlBoxOpened', function (chatbox) {
                 // Wrapped in anon method because at scan time, chatboxviews
                 // attr not set yet.

Some files were not shown because too many files changed in this diff