Commit d2ffdcef authored by JC Brand's avatar JC Brand

Merge branch 'master' into weblate-translations

parents 172f6302 4331f920
{
"presets": [
["@babel/preset-env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 10", "IE >= 11"]
}
}]
]
}
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
"plugins": ["lodash"], "plugins": ["lodash"],
"extends": ["eslint:recommended", "plugin:lodash/canonical"], "extends": ["eslint:recommended", "plugin:lodash/canonical"],
"globals": { "globals": {
"Promise": true,
"converse": true,
"window": true, "window": true,
"sinon": true, "sinon": true,
"define": true, "define": true,
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
.idea .idea
.su? .su?
builds/* builds/*
*.map
dist/converse-no-dependencies-es2015.js
analytics.js analytics.js
inverse-analytics.js inverse-analytics.js
......
...@@ -7,12 +7,21 @@ ...@@ -7,12 +7,21 @@
- #161 XEP-0363: HTTP File Upload - #161 XEP-0363: HTTP File Upload
- #194 Include entity capabilities in outgoing presence stanzas - #194 Include entity capabilities in outgoing presence stanzas
- #337 API call to update a VCard - #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 - #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 - It's now also possible to edit your VCard via the UI
- Automatically grow/shrink input as text is entered/removed - 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 - MP4 and MP3 files when sent as XEP-0066 Out of Band Data, are now playable directly in chat
- Support for rendering URLs sent according to XEP-0066 Out of Band Data. - Support for rendering URLs sent according to XEP-0066 Out of Band Data.
- Geo-URIs (e.g. from Conversations) are now replaced by links to openstreetmap (works in reverse also) - Geo-URIs (e.g. from Conversations) are now replaced by links to openstreetmap (works in reverse also)
- Add a checkbox to indicate whether a trusted device is being used or not.
If the device is not trusted, sessionStorage is used and all user data is deleted from the browser cache upon logout.
If the device is trusted, localStorage is used and user data is cached indefinitely.
- Initial support for XEP-0357 Push Notifications, 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 ### Bugfixes
...@@ -22,10 +31,13 @@ ...@@ -22,10 +31,13 @@
- #1039 Multi-option data form elements not shown and saved correctly - #1039 Multi-option data form elements not shown and saved correctly
### API changes ### API changes
- `_converse.api.vcard.get` now also accepts a `Backbone.Model` instance and - `_converse.api.vcard.get` now also accepts a `Backbone.Model` instance and
has an additional `force` parameter to force fetching the vcard even if it has an additional `force` parameter to force fetching the vcard even if it
has already been fetched. has already been fetched.
- New API method `_converse.api.vcard.update`. - New API method `_converse.api.vcard.update`.
- The `contactStatusChanged` event has been renamed to `contactPresenceChanged`
and a event `presenceChanged` is now also triggered on the contact.
## UI changes ## UI changes
...@@ -41,6 +53,8 @@ ...@@ -41,6 +53,8 @@
[statusMessageChanged](https://conversejs.org/docs/html/events.html#contactstatusmessagechanged) [statusMessageChanged](https://conversejs.org/docs/html/events.html#contactstatusmessagechanged)
event and make the XMLHttpRequest yourself. event and make the XMLHttpRequest yourself.
- Removed `xhr_user_search` in favor of only accepting `xhr_user_search_url` as configuration option. - Removed `xhr_user_search` in favor of only accepting `xhr_user_search_url` as configuration option.
- `xhr_user_search_url` has to include the `?` character now in favor of more
flexibility. See example in the documentation.
- The data returned from the `xhr_user_search_url` must now include the user's - The data returned from the `xhr_user_search_url` must now include the user's
`jid` instead of just an `id`. `jid` instead of just an `id`.
- New configuration settings [nickname](https://conversejs.org/docs/html/configurations.html#nickname) - New configuration settings [nickname](https://conversejs.org/docs/html/configurations.html#nickname)
......
...@@ -15,6 +15,7 @@ OXIPNG ?= oxipng ...@@ -15,6 +15,7 @@ OXIPNG ?= oxipng
PAPER = PAPER =
PO2JSON ?= ./node_modules/.bin/po2json 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 SASS ?= ./.bundle/bin/sass
SED ?= sed SED ?= sed
SPHINXBUILD ?= ./bin/sphinx-build SPHINXBUILD ?= ./bin/sphinx-build
...@@ -73,7 +74,7 @@ serve_bg: dev ...@@ -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 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 .PHONY: pot
pot: dist/converse-no-dependencies.js pot: dist/converse-no-dependencies-es2015.js
$(GETTEXT) 2>&1 > /dev/null; exit $$?; $(GETTEXT) 2>&1 > /dev/null; exit $$?;
.PHONY: po .PHONY: po
...@@ -121,7 +122,7 @@ stamp-bundler: Gemfile ...@@ -121,7 +122,7 @@ stamp-bundler: Gemfile
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf node_modules .bundle stamp-npm rm -rf node_modules .bundle stamp-npm stamp-bundler
rm dist/*.min.js rm dist/*.min.js
rm css/website.min.css rm css/website.min.css
rm css/converse.min.css rm css/converse.min.css
...@@ -134,10 +135,7 @@ dev: stamp-bundler stamp-npm ...@@ -134,10 +135,7 @@ dev: stamp-bundler stamp-npm
## Builds ## Builds
.PHONY: css .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: dev sass/*.scss css/converse.css css/converse.min.css css/website.css css/website.min.css css/fonts.css
css/inverse.css:: dev sass sass
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/inverse.scss css/inverse.css
css/converse.css:: dev sass css/converse.css:: dev sass
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/converse.scss css/converse.css $(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/converse.scss css/converse.css
...@@ -158,12 +156,7 @@ watch: dev ...@@ -158,12 +156,7 @@ watch: dev
.PHONY: watchjs .PHONY: watchjs
watchjs: dev watchjs: dev
$(BABEL) --source-maps --watch=./src --out-dir=./builds ./node_modules/.bin/npx webpack --mode=development --watch
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
.PHONY: logo .PHONY: logo
logo: logo/conversejs-transparent16.png \ logo: logo/conversejs-transparent16.png \
...@@ -190,33 +183,30 @@ BUILDS = dist/converse.js \ ...@@ -190,33 +183,30 @@ BUILDS = dist/converse.js \
dist/converse-headless.js \ dist/converse-headless.js \
dist/converse-headless.min.js \ dist/converse-headless.min.js \
dist/converse-no-dependencies.min.js \ dist/converse-no-dependencies.min.js \
dist/converse-no-dependencies.js dist/converse-no-dependencies.js \
dist/converse-no-dependencies-es2015.js
# dist/converse-esnext.js \
# dist/converse-esnext.min.js \ dist/converse.js: src webpack.config.js stamp-npm
./node_modules/.bin/npx webpack --mode=development
dist/converse.js: transpile src stamp-npm dist/converse.min.js: src webpack.config.js stamp-npm
$(RJS) -o src/build.js include=converse out=dist/converse.js optimize=none ./node_modules/.bin/npx webpack --mode=production
dist/converse.min.js: transpile src stamp-npm dist/converse-headless.js: src webpack.config.js stamp-npm
$(RJS) -o src/build.js include=converse out=dist/converse.min.js ./node_modules/.bin/npx webpack --mode=development --type=headless
dist/converse-headless.js: transpile src stamp-npm dist/converse-headless.min.js: src webpack.config.js stamp-npm
$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.js optimize=none ./node_modules/.bin/npx webpack --mode=production --type=headless
dist/converse-headless.min.js: transpile src stamp-npm dist/converse-no-dependencies.js: src webpack.config.js stamp-npm
$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.min.js ./node_modules/.bin/npx webpack --mode=development --type=nodeps
dist/converse-esnext.js: src stamp-npm dist/converse-no-dependencies.min.js: src webpack.config.js stamp-npm
$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.js optimize=none ./node_modules/.bin/npx webpack --mode=production --type=nodeps
dist/converse-esnext.min.js: src stamp-npm dist/converse-no-dependencies-es2015.js: src webpack.config.js stamp-npm
$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.min.js ./node_modules/.bin/npx webpack --mode=development --type=nodeps --lang=es2015
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
.PHONY: dist .PHONY: dist
dist:: build dist:: build
.PHONY: build .PHONY: build
build:: dev css transpile $(BUILDS) build:: dev css $(BUILDS)
######################################################################## ########################################################################
## Tests ## Tests
......
##############################################################################
#
# 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)
...@@ -11,12 +11,4 @@ eggs = ...@@ -11,12 +11,4 @@ eggs =
sphinx-bootstrap-theme sphinx-bootstrap-theme
[versions] [versions]
docutils = 0.13.1 Sphinx = 1.7.5
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
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.
This diff is collapsed.
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%;
}
This diff is collapsed.
...@@ -117,6 +117,14 @@ a:hover, a:focus { ...@@ -117,6 +117,14 @@ a:hover, a:focus {
.outro { .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; }
section h3 {
color: #89B7CD; }
section h4 {
color: #5CBC86;
font-size: 1.5em; }
.brand-heading { .brand-heading {
font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif; font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif;
font-weight: normal; font-weight: normal;
...@@ -181,7 +189,17 @@ a:hover, a:focus { ...@@ -181,7 +189,17 @@ a:hover, a:focus {
-moz-animation-timing-function: linear; } -moz-animation-timing-function: linear; }
.content-section { .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 { .donate-section {
width: 100%; width: 100%;
...@@ -194,7 +212,6 @@ a:hover, a:focus { ...@@ -194,7 +212,6 @@ a:hover, a:focus {
@media (min-width: 767px) { @media (min-width: 767px) {
.content-section { .content-section {
padding-top: 150px;
padding-bottom: 50px; } padding-bottom: 50px; }
.donate-section { .donate-section {
...@@ -304,6 +321,8 @@ ul.features { ...@@ -304,6 +321,8 @@ ul.features {
clear: both; clear: both;
font-size: 1.4em; font-size: 1.4em;
padding: 2em 0 6em 0; } padding: 2em 0 6em 0; }
.sponsors ul {
padding: 0; }
.sponsors h2 { .sponsors h2 {
text-align: center; } text-align: center; }
......
...@@ -9,15 +9,14 @@ ...@@ -9,15 +9,14 @@
<meta name="author" content="JC Brand" /> <meta name="author" content="JC Brand" />
<meta name="keywords" content="xmpp chat webchat converse.js" /> <meta name="keywords" content="xmpp chat webchat converse.js" />
<link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/> <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
<link type="text/css" rel="stylesheet" media="screen" href="css/inverse.css" /> <link type="text/css" rel="stylesheet" media="screen" href="css/fullpage.css" />
<script src="node_modules/requirejs/require.js"></script> <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
<script src="src/config.js"></script> <script src="dist/converse.js"></script>
</head> </head>
<body class="reset"> <body class="reset">
<script> <script>
require(['converse'], function (converse) {
converse.initialize({ converse.initialize({
auto_away: 300, auto_away: 300,
i18n: 'en', i18n: 'en',
...@@ -26,6 +25,7 @@ ...@@ -26,6 +25,7 @@
// 'prosody@conference.prosody.im', // 'prosody@conference.prosody.im',
// 'jdev@conference.jabber.org' // 'jdev@conference.jabber.org'
// ], // ],
// websocket_url: 'ws://chat.example.org:5280/xmpp-websocket',
view_mode: 'fullscreen', view_mode: 'fullscreen',
archived_messages_page_size: '500', archived_messages_page_size: '500',
allow_public_bookmarks: true, allow_public_bookmarks: true,
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
message_archiving: 'always', message_archiving: 'always',
debug: true debug: true
}); });
});
</script> </script>
</body> </body>
</html> </html>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
Events and promises 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`. :ref:`listen-grouping`.
Some of these events are also available as `ES2015 Promises <http://es6-features.org/#PromiseUsage>`_, Some of these events are also available as `ES2015 Promises <http://es6-features.org/#PromiseUsage>`_,
...@@ -149,6 +149,11 @@ When a chatbox has been minimized or maximized. Relevant to converse-chatview.js ...@@ -149,6 +149,11 @@ When a chatbox has been minimized or maximized. Relevant to converse-chatview.js
``_converse.api.listen.on('chatBoxToggled', function (chatbox) { ... });`` ``_converse.api.listen.on('chatBoxToggled', function (chatbox) { ... });``
clearSession
~~~~~~~~~~~~
Called when the user is logging out and provides the opportunity to remove session data.
connected connected
~~~~~~~~~ ~~~~~~~~~
...@@ -174,12 +179,13 @@ The user has removed a contact. ...@@ -174,12 +179,13 @@ The user has removed a contact.
``_converse.api.listen.on('contactRemoved', function (data) { ... });`` ``_converse.api.listen.on('contactRemoved', function (data) { ... });``
contactStatusChanged contactPresenceChanged
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
When a chat buddy's chat status has changed. When a chat buddy's presence status has changed.
The presence status is either `online`, `offline`, `dnd`, `away` or `xa`.
``_converse.api.listen.on('contactStatusChanged', function (buddy) { ... });`` ``_converse.api.listen.on('contactPresenceChanged', function (presence) { ... });``
contactStatusMessageChanged contactStatusMessageChanged
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -288,6 +294,25 @@ Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_: ...@@ -288,6 +294,25 @@ Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
// Your code here... // 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 reconnecting
~~~~~~~~~~~~ ~~~~~~~~~~~~
...@@ -305,24 +330,14 @@ have to be registered anew. ...@@ -305,24 +330,14 @@ have to be registered anew.
_converse.api.listen.on('reconnected', function () { ... }); _converse.api.listen.on('reconnected', function () { ... });
registeredGlobalEventHandlers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
privateChatsAutoJoined Called once Converse has registered its global event handlers (for events such
~~~~~~~~~~~~~~~~~~~~~~ as window resize or unload).
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 () { Plugins can listen to this event as cue to register their own global event
// Your code here... handlers.
});
roomsAutoJoined roomsAutoJoined
--------------- ---------------
...@@ -460,6 +475,14 @@ Similar to `rosterInitialized`, but instead pertaining to reconnection. This ...@@ -460,6 +475,14 @@ Similar to `rosterInitialized`, but instead pertaining to reconnection. This
event indicates that the Backbone collections representing the roster and its event indicates that the Backbone collections representing the roster and its
groups are now again available after converse.js has reconnected. 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`:
statusInitialized statusInitialized
...@@ -491,12 +514,12 @@ When own custom status message has changed. ...@@ -491,12 +514,12 @@ When own custom status message has changed.
``_converse.api.listen.on('statusMessageChanged', function (message) { ... });`` ``_converse.api.listen.on('statusMessageChanged', function (message) { ... });``
serviceDiscovered streamFeaturesAdded
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
``_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 windowStateChanged
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
......
...@@ -19,7 +19,7 @@ and a private chat with a URL fragment such as ...@@ -19,7 +19,7 @@ and a private chat with a URL fragment such as
Off-the-record encryption 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. encrypted messaging.
The OTR protocol not only **encrypts your messages**, it provides ways to The OTR protocol not only **encrypts your messages**, it provides ways to
...@@ -38,17 +38,17 @@ secure crypto. ...@@ -38,17 +38,17 @@ secure crypto.
For harsh but fairly valid criticism of JavaScript cryptography, read: For harsh but fairly valid criticism of JavaScript cryptography, read:
`JavaScript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_. `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>`_. `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 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. communications privacy, then you're much better off using native software.
Notifications 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. message.
For more info, refer to the :ref:`play-sounds` configuration setting. 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 ...@@ -61,13 +61,10 @@ For more info, refer to the :ref:`show-desktop-notifications` configuration sett
Multilingual Support Multilingual Support
==================== ====================
Converse.js is translated into multiple languages. The default build, Converse is translated into multiple languages. Translations are supplied in
``converse.min.js``, includes all languages. 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
Languages increase the size of the Converse.js significantly. :ref:`locales-url` configuration setting.
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.
Moderating chatrooms Moderating chatrooms
==================== ====================
...@@ -103,7 +100,7 @@ Here are the different commands that may be used to moderate a chatroom: ...@@ -103,7 +100,7 @@ Here are the different commands that may be used to moderate a chatroom:
Passwordless login with client certificates 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 used together with x509 client certificates to enable passwordless login or
even 2-factor authentication. even 2-factor authentication.
......
...@@ -34,8 +34,6 @@ via the *script* and *link* tags: ...@@ -34,8 +34,6 @@ via the *script* and *link* tags:
<script src="https://cdn.conversejs.org/dist/converse.min.js" charset="utf-8"></script> <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 .. 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 CDN, it's generally better to load a specific version (preferably the
latest one), to avoid breakage when new backwards-incompatible versions are 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. ...@@ -111,19 +109,13 @@ split up into two parts, with the UI part dropped for this build.
Fullscreen version 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>`_. A hosted version is available online at `inverse.chat <https://inverse.chat>`_.
Originally this version was available as a separate build file, but 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 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 "fullscreen" versions of converse.js is simply a matter of configuring the
:ref:`view_mode` and including the right CSS file. :ref:`view_mode`.
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.
To generate the headless build, run ``make dist/converse-headless.js`` and/or To generate the headless build, run ``make dist/converse-headless.js`` and/or
``make dist/converse-headless.min.js``. ``make dist/converse-headless.min.js``.
......
...@@ -3,11 +3,12 @@ ...@@ -3,11 +3,12 @@
<head> <head>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <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"/> <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
<script type="text/javascript" src="inverse-analytics.js"></script> <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> <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> <script src="dist/converse.js"></script>
</head> </head>
<body class="reset"> <body class="reset">
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Converse.js Mockups</title> <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="../../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> </head>
<body class="reset"> <body class="reset">
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chatroom Fullscreen</title> <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="../../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> </head>
<body class="reset"> <body class="reset">
...@@ -23,12 +23,11 @@ ...@@ -23,12 +23,11 @@
<div class="chatbox chatroom" id="chatroom"> <div class="chatbox chatroom" id="chatroom">
<div class="flyout box-flyout"> <div class="flyout box-flyout">
<div class="chat-head chat-head-chatroom row no-gutters"> <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> <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> <p class="chatroom-description">Two households, both alike in dignity, In fair Verona, where we lay our scene.</p>
</div> </div>
<div class="chatbox-buttons row no-gutters"> <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-close"></a>
<a class="chatbox-btn fa fa-wrench"></a> <a class="chatbox-btn fa fa-wrench"></a>
</div> </div>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<title>Login Fullscreen</title> <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/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="../../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> </head>
<body> <body>
......
...@@ -9,22 +9,27 @@ ...@@ -9,22 +9,27 @@
<link type="text/css" rel="stylesheet" media="screen" href="css/mockup.css" /> <link type="text/css" rel="stylesheet" media="screen" href="css/mockup.css" />
</head> </head>
<body style="background-color: #578EA9"> <body class="reset">
<div class="converse-bg container"> <div class="converse-bg container">
<h1 class="brand-heading">Converse</h1> <h1 class="brand-heading">Converse</h1>
</div> </div>
<div id="conversejs" class="converse-overlayed"> <div id="conversejs" class="converse-overlayed">
<div class="converse-chatboxes row no-gutters"> <div class="converse-chatboxes row no-gutters">
<div id="controlbox" class="chatbox"> <div id="controlbox" class="chatbox logged-out">
<div class="flyout box-flyout"> <div class="flyout box-flyout">
<div class="chat-head controlbox-head"> <div class="chat-head controlbox-head">
<div class="brand-heading"><i class="icon-conversejs"></i><span class="brand-name">converse</span></div>
<a class="chatbox-btn close-chatbox-button fa fa-close"></a> <a class="chatbox-btn close-chatbox-button fa fa-close"></a>
<span class="brand-heading-container">
<div class="brand-heading">
<a href="https://conversejs.org" target="_blank" rel="noopener">
<i class="icon-conversejs"></i><span class="brand-name">converse</span>
</a>
</div>
</span>
</div> </div>
<div class="controlbox-panes"> <div class="controlbox-panes">
<div id="login-dialog" class="controlbox-pane row"> <div id="converse-login-panel" class="controlbox-pane fade-in row no-gutters">
<form id="converse-login" class="pure-form converse-form"> <form id="converse-login" class="converse-form">
<div class="form-group"> <div class="form-group">
<label for="jid">XMPP Username:</label> <label for="jid">XMPP Username:</label>
<input type="text" name="jid" class="form-control" placeholder="user@server" autocomplete="off"> <input type="text" name="jid" class="form-control" placeholder="user@server" autocomplete="off">
...@@ -33,9 +38,14 @@ ...@@ -33,9 +38,14 @@
<label for="password">Password:</label> <label for="password">Password:</label>
<input type="password" name="password" class="form-control" placeholder="password" autocomplete="off"> <input type="password" name="password" class="form-control" placeholder="password" autocomplete="off">
</div> </div>
<p></p> <div class="form-group form-check">
<p><input class="btn btn-primary" type="submit" value="Log In"></p> <input id="converse-login-trusted" class="form-check-input" type="checkbox" name="trusted" checked="">
<label class="form-check-label" for="converse-login-trusted">This is a trusted device</label>
</div>
<fieldset class="buttons">
<input class="btn btn-primary" type="submit" value="Log in">
<p>Click <a href="#" data-toggle="modal" data-target="#registerModal">here</a> to register.</p> <p>Click <a href="#" data-toggle="modal" data-target="#registerModal">here</a> to register.</p>
</fieldset>
</form> </form>
</div> </div>
</div> </div>
......
This diff is collapsed.
This diff is collapsed.
{ {
"name": "converse.js", "name": "converse.js",
"version": "3.3.4", "version": "3.3.4",
"description": "Browser based XMPP instant messaging client", "description": "Browser based XMPP chat client",
"main": "main.js", "main": "dist/converse.js",
"directories": { "directories": {
"doc": "docs", "doc": "docs",
"locale": "locale", "locale": "locale",
...@@ -20,20 +20,24 @@ ...@@ -20,20 +20,24 @@
"chatrooms", "chatrooms",
"webchat" "webchat"
], ],
"author": "JC Brand", "author": {
"name": "JC Brand",
"email": "jc@opkode.com"
},
"license": "MPL-2.0", "license": "MPL-2.0",
"bugs": { "bugs": {
"url": "https://github.com/jcbrand/converse.js/issues" "url": "https://github.com/conversejs/converse.js/issues"
}, },
"engines": { "engines": {
"browser": "*" "browser": "*"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.0.0-beta.35", "@babel/cli": "^7.0.0-beta.48",
"@babel/core": "^7.0.0-beta.35", "@babel/core": "^7.0.0-beta.48",
"@babel/preset-env": "^7.0.0-beta.35", "@babel/preset-env": "^7.0.0-beta.48",
"almond": "~0.3.3", "@babel/preset-es2015": "^7.0.0-beta.49",
"awesomplete-avoid-xss": "^1.1.2", "awesomplete-avoid-xss": "^1.1.2",
"babel-loader": "^8.0.0-beta.3",
"backbone": "1.3.3", "backbone": "1.3.3",
"backbone.browserStorage": "0.0.3", "backbone.browserStorage": "0.0.3",
"backbone.nativeview": "^0.3.3", "backbone.nativeview": "^0.3.3",
...@@ -47,9 +51,12 @@ ...@@ -47,9 +51,12 @@
"es6-promise": "^4.1.0", "es6-promise": "^4.1.0",
"eslint": "4.19.1", "eslint": "4.19.1",
"eslint-plugin-lodash": "^2.3.3", "eslint-plugin-lodash": "^2.3.3",
"exports-loader": "^0.7.0",
"filesize": "^3.6.1", "filesize": "^3.6.1",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"hellojs": "^1.16.1",
"http-server": "^0.10.0", "http-server": "^0.10.0",
"imports-loader": "^0.8.0",
"install": "^0.9.5", "install": "^0.9.5",
"jasmine-core": "2.6.4", "jasmine-core": "2.6.4",
"jed": "1.1.1", "jed": "1.1.1",
...@@ -58,7 +65,10 @@ ...@@ -58,7 +65,10 @@
"jshint": "^2.9.4", "jshint": "^2.9.4",
"lodash": "4.17.4", "lodash": "4.17.4",
"lodash-template-loader": "^2.0.0", "lodash-template-loader": "^2.0.0",
"lodash-template-webpack-loader": "jcbrand/lodash-template-webpack-loader",
"minimist": "^1.2.0",
"moment": "~> 2.19.3 ", "moment": "~> 2.19.3 ",
"npm": "^5.7.1",
"otr": "0.2.16", "otr": "0.2.16",
"pluggable.js": "2.0.0", "pluggable.js": "2.0.0",
"po2json": "^0.4.4", "po2json": "^0.4.4",
...@@ -67,18 +77,15 @@ ...@@ -67,18 +77,15 @@
"sinon": "^2.1.0", "sinon": "^2.1.0",
"sizzle": "^2.3.3", "sizzle": "^2.3.3",
"snabbdom": "0.7.1", "snabbdom": "0.7.1",
"snyk": "^1.21.2", "strophe.js": "1.2.15",
"strophe.js": "1.2.14",
"strophejs-plugin-ping": "0.0.1", "strophejs-plugin-ping": "0.0.1",
"strophejs-plugin-register": "0.0.1", "strophejs-plugin-register": "0.0.1",
"strophejs-plugin-rsm": "0.0.1", "strophejs-plugin-rsm": "0.0.1",
"text": "requirejs/text#2.0.15",
"uglify-es": "^3.0.24", "uglify-es": "^3.0.24",
"urijs": "^1.19.1", "urijs": "^1.19.1",
"wait-until-promise": "^1.0.0", "wait-until-promise": "^1.0.0",
"webpack": "^4.0.1",
"webpack-cli": "^2.1.4",
"xss": "^0.3.3" "xss": "^0.3.3"
},
"dependencies": {
"npm": "^5.7.1"
} }
} }
<!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>
#converse-embedded-chat,
#conversejs { #conversejs {
[hidden] { display: none; } [hidden] { display: none; }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
@import "bourbon"; @import "bourbon";
@import "converse/variables";
#conversejs.converse-embedded { #conversejs.converse-embedded {
@include box-sizing(border-box); @include box-sizing(border-box);
......
This diff is collapsed.
...@@ -18,3 +18,20 @@ ...@@ -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;
}
}
}
#conversejs:not(.fullscreen) { #conversejs.converse-overlayed {
#minimized-chats { #minimized-chats {
order: 100; order: 100;
......
...@@ -32,6 +32,10 @@ ...@@ -32,6 +32,10 @@
.open-chatroom { .open-chatroom {
&:hover { &:hover {
background-color: lighten($controlbox-head-color, 45%); background-color: lighten($controlbox-head-color, 45%);
a.add-bookmark,
a.room-info {
display: block !important;
}
} }
&.unread-msgs { &.unread-msgs {
.msgs-indicator { .msgs-indicator {
...@@ -48,7 +52,9 @@ ...@@ -48,7 +52,9 @@
&:hover { &:hover {
color: $dark-link-color; color: $dark-link-color;
} }
&.add-bookmark,
&.room-info { &.room-info {
display: none;
&:before { &:before {
font-size: 15px; font-size: 15px;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#conversejs {
> .row {
flex-direction: row-reverse;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment