diff --git a/README.md b/README.md index 73e742b..9fe101e 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ The benefit of using converse.js as opposed to relying on a SaaS (software-as-a- -**Shipped version:** 7.0.6~ynh2 +**Shipped version:** 9.0.0~ynh1 **Demo:** https://inverse.chat/ diff --git a/README_fr.md b/README_fr.md index 4e4d914..f56a883 100644 --- a/README_fr.md +++ b/README_fr.md @@ -27,7 +27,7 @@ The benefit of using converse.js as opposed to relying on a SaaS (software-as-a- -**Version incluse :** 7.0.6~ynh2 +**Version incluse :** 9.0.0~ynh1 **Démo :** https://inverse.chat/ diff --git a/conf/nginx.conf b/conf/nginx.conf index 4ff7bc7..26fac60 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -6,11 +6,6 @@ location __PATH__/ { index index.html; - # Force usage of https - if ($scheme = http) { - rewrite ^ https://$server_name$request_uri? permanent; - } - # BOSH location = __PATH__/http-bind { proxy_pass "http://localhost:5290/http-bind"; diff --git a/manifest.json b/manifest.json index 8df0172..e7c33ad 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "en": "Web-based XMPP/Jabber chat client", "fr": "Client de chat XMPP/Jabber basé sur le Web" }, - "version": "7.0.6~ynh2", + "version": "9.0.0~ynh1", "url": "http://conversejs.org/", "upstream": { "license": "MPL-2.0", @@ -21,7 +21,7 @@ "email": "" }, "requirements": { - "yunohost": ">= 4.2.4" + "yunohost": ">= 4.3.0" }, "multi_instance": true, "services": [ @@ -31,8 +31,7 @@ "install" : [ { "name": "domain", - "type": "domain", - "example": "domain.org" + "type": "domain" }, { "name": "path", diff --git a/scripts/restore b/scripts/restore index e1d772a..258843e 100644 --- a/scripts/restore +++ b/scripts/restore @@ -30,8 +30,7 @@ final_path=$(ynh_app_setting_get --app=$app --key=final_path) #================================================= ynh_script_progression --message="Validating restoration parameters..." --weight=1 -test ! -d $final_path \ - || ynh_die --message="There is already a directory: $final_path " +test ! -d $final_path || ynh_die --message="There is already a directory: $final_path " #================================================= # STANDARD RESTORATION STEPS diff --git a/sources/dist/converse.js b/sources/dist/converse.js deleted file mode 100644 index aa27b88..0000000 --- a/sources/dist/converse.js +++ /dev/null @@ -1,83469 +0,0 @@ -/******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ({ - -/***/ 7706: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -const atob = __webpack_require__(171); - -const btoa = __webpack_require__(8713); - -module.exports = { - atob, - btoa -}; - -/***/ }), - -/***/ 171: -/***/ ((module) => { - -"use strict"; - -/** - * Implementation of atob() according to the HTML and Infra specs, except that - * instead of throwing INVALID_CHARACTER_ERR we return null. - */ - -function atob(data) { - // Web IDL requires DOMStrings to just be converted using ECMAScript - // ToString, which in our case amounts to using a template literal. - data = `${data}`; // "Remove all ASCII whitespace from data." - - data = data.replace(/[ \t\n\f\r]/g, ""); // "If data's length divides by 4 leaving no remainder, then: if data ends - // with one or two U+003D (=) code points, then remove them from data." - - if (data.length % 4 === 0) { - data = data.replace(/==?$/, ""); - } // "If data's length divides by 4 leaving a remainder of 1, then return - // failure." - // - // "If data contains a code point that is not one of - // - // U+002B (+) - // U+002F (/) - // ASCII alphanumeric - // - // then return failure." - - - if (data.length % 4 === 1 || /[^+/0-9A-Za-z]/.test(data)) { - return null; - } // "Let output be an empty byte sequence." - - - let output = ""; // "Let buffer be an empty buffer that can have bits appended to it." - // - // We append bits via left-shift and or. accumulatedBits is used to track - // when we've gotten to 24 bits. - - let buffer = 0; - let accumulatedBits = 0; // "Let position be a position variable for data, initially pointing at the - // start of data." - // - // "While position does not point past the end of data:" - - for (let i = 0; i < data.length; i++) { - // "Find the code point pointed to by position in the second column of - // Table 1: The Base 64 Alphabet of RFC 4648. Let n be the number given in - // the first cell of the same row. - // - // "Append to buffer the six bits corresponding to n, most significant bit - // first." - // - // atobLookup() implements the table from RFC 4648. - buffer <<= 6; - buffer |= atobLookup(data[i]); - accumulatedBits += 6; // "If buffer has accumulated 24 bits, interpret them as three 8-bit - // big-endian numbers. Append three bytes with values equal to those - // numbers to output, in the same order, and then empty buffer." - - if (accumulatedBits === 24) { - output += String.fromCharCode((buffer & 0xff0000) >> 16); - output += String.fromCharCode((buffer & 0xff00) >> 8); - output += String.fromCharCode(buffer & 0xff); - buffer = accumulatedBits = 0; - } // "Advance position by 1." - - } // "If buffer is not empty, it contains either 12 or 18 bits. If it contains - // 12 bits, then discard the last four and interpret the remaining eight as - // an 8-bit big-endian number. If it contains 18 bits, then discard the last - // two and interpret the remaining 16 as two 8-bit big-endian numbers. Append - // the one or two bytes with values equal to those one or two numbers to - // output, in the same order." - - - if (accumulatedBits === 12) { - buffer >>= 4; - output += String.fromCharCode(buffer); - } else if (accumulatedBits === 18) { - buffer >>= 2; - output += String.fromCharCode((buffer & 0xff00) >> 8); - output += String.fromCharCode(buffer & 0xff); - } // "Return output." - - - return output; -} -/** - * A lookup table for atob(), which converts an ASCII character to the - * corresponding six-bit number. - */ - - -const keystr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -function atobLookup(chr) { - const index = keystr.indexOf(chr); // Throw exception if character is not in the lookup string; should not be hit in tests - - return index < 0 ? undefined : index; -} - -module.exports = atob; - -/***/ }), - -/***/ 8713: -/***/ ((module) => { - -"use strict"; - -/** - * btoa() as defined by the HTML and Infra specs, which mostly just references - * RFC 4648. - */ - -function btoa(s) { - let i; // String conversion as required by Web IDL. - - s = `${s}`; // "The btoa() method must throw an "InvalidCharacterError" DOMException if - // data contains any character whose code point is greater than U+00FF." - - for (i = 0; i < s.length; i++) { - if (s.charCodeAt(i) > 255) { - return null; - } - } - - let out = ""; - - for (i = 0; i < s.length; i += 3) { - const groupsOfSix = [undefined, undefined, undefined, undefined]; - groupsOfSix[0] = s.charCodeAt(i) >> 2; - groupsOfSix[1] = (s.charCodeAt(i) & 0x03) << 4; - - if (s.length > i + 1) { - groupsOfSix[1] |= s.charCodeAt(i + 1) >> 4; - groupsOfSix[2] = (s.charCodeAt(i + 1) & 0x0f) << 2; - } - - if (s.length > i + 2) { - groupsOfSix[2] |= s.charCodeAt(i + 2) >> 6; - groupsOfSix[3] = s.charCodeAt(i + 2) & 0x3f; - } - - for (let j = 0; j < groupsOfSix.length; j++) { - if (typeof groupsOfSix[j] === "undefined") { - out += "="; - } else { - out += btoaLookup(groupsOfSix[j]); - } - } - } - - return out; -} -/** - * Lookup table for btoa(), which converts a six-bit number into the - * corresponding ASCII character. - */ - - -const keystr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -function btoaLookup(index) { - if (index >= 0 && index < 64) { - return keystr[index]; - } // Throw INVALID_CHARACTER_ERR exception here -- won't be hit in the tests. - - - return undefined; -} - -module.exports = btoa; - -/***/ }), - -/***/ 8826: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = { - "default": __webpack_require__(5820), - __esModule: true -}; - -/***/ }), - -/***/ 1060: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = { - "default": __webpack_require__(3248), - __esModule: true -}; - -/***/ }), - -/***/ 3415: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = { - "default": __webpack_require__(9830), - __esModule: true -}; - -/***/ }), - -/***/ 8681: -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -exports.__esModule = true; - -var _promise = __webpack_require__(3415); - -var _promise2 = _interopRequireDefault(_promise); - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; -} - -exports.default = function (fn) { - return function () { - var gen = fn.apply(this, arguments); - return new _promise2.default(function (resolve, reject) { - function step(key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } - - if (info.done) { - resolve(value); - } else { - return _promise2.default.resolve(value).then(function (value) { - step("next", value); - }, function (err) { - step("throw", err); - }); - } - } - - return step("next"); - }); - }; -}; - -/***/ }), - -/***/ 8584: -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -"use strict"; - - -exports.__esModule = true; - -var _defineProperty = __webpack_require__(8826); - -var _defineProperty2 = _interopRequireDefault(_defineProperty); - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; -} - -exports.default = function (obj, key, value) { - if (key in obj) { - (0, _defineProperty2.default)(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - - return obj; -}; - -/***/ }), - -/***/ 7034: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ -// This method of obtaining a reference to the global object needs to be -// kept identical to the way it is obtained in runtime.js -var g = function () { - return this; -}() || Function("return this")(); // Use `getOwnPropertyNames` because not all browsers support calling -// `hasOwnProperty` on the global `self` object in a worker. See #183. - - -var hadRuntime = g.regeneratorRuntime && Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0; // Save the old regeneratorRuntime in case it needs to be restored later. - -var oldRuntime = hadRuntime && g.regeneratorRuntime; // Force reevalutation of runtime.js. - -g.regeneratorRuntime = undefined; -module.exports = __webpack_require__(4267); - -if (hadRuntime) { - // Restore the original runtime. - g.regeneratorRuntime = oldRuntime; -} else { - // Remove the global property added by runtime.js. - try { - delete g.regeneratorRuntime; - } catch (e) { - g.regeneratorRuntime = undefined; - } -} - -/***/ }), - -/***/ 4267: -/***/ ((module) => { - -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ -!function (global) { - "use strict"; - - var Op = Object.prototype; - var hasOwn = Op.hasOwnProperty; - var undefined; // More compressible than void 0. - - var $Symbol = typeof Symbol === "function" ? Symbol : {}; - var iteratorSymbol = $Symbol.iterator || "@@iterator"; - var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; - var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; - var inModule = "object" === "object"; - var runtime = global.regeneratorRuntime; - - if (runtime) { - if (inModule) { - // If regeneratorRuntime is defined globally and we're in a module, - // make the exports object identical to regeneratorRuntime. - module.exports = runtime; - } // Don't bother evaluating the rest of this file if the runtime was - // already defined globally. - - - return; - } // Define the runtime globally (as expected by generated code) as either - // module.exports (if we're in a module) or a new, empty object. - - - runtime = global.regeneratorRuntime = inModule ? module.exports : {}; - - function wrap(innerFn, outerFn, self, tryLocsList) { - // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. - var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; - var generator = Object.create(protoGenerator.prototype); - var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next, - // .throw, and .return methods. - - generator._invoke = makeInvokeMethod(innerFn, self, context); - return generator; - } - - runtime.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion - // record like context.tryEntries[i].completion. This interface could - // have been (and was previously) designed to take a closure to be - // invoked without arguments, but in all the cases we care about we - // already have an existing method we want to call, so there's no need - // to create a new function object. We can even get away with assuming - // the method takes exactly one argument, since that happens to be true - // in every case, so we don't have to touch the arguments object. The - // only additional allocation required is the completion record, which - // has a stable shape and so hopefully should be cheap to allocate. - - function tryCatch(fn, obj, arg) { - try { - return { - type: "normal", - arg: fn.call(obj, arg) - }; - } catch (err) { - return { - type: "throw", - arg: err - }; - } - } - - var GenStateSuspendedStart = "suspendedStart"; - var GenStateSuspendedYield = "suspendedYield"; - var GenStateExecuting = "executing"; - var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as - // breaking out of the dispatch switch statement. - - var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and - // .constructor.prototype properties for functions that return Generator - // objects. For full spec compliance, you may wish to configure your - // minifier not to mangle the names of these two functions. - - function Generator() {} - - function GeneratorFunction() {} - - function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that - // don't natively support it. - - - var IteratorPrototype = {}; - - IteratorPrototype[iteratorSymbol] = function () { - return this; - }; - - var getProto = Object.getPrototypeOf; - var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); - - if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { - // This environment has a native %IteratorPrototype%; use it instead - // of the polyfill. - IteratorPrototype = NativeIteratorPrototype; - } - - var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); - GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; - GeneratorFunctionPrototype.constructor = GeneratorFunction; - GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; // Helper for defining the .next, .throw, and .return methods of the - // Iterator interface in terms of a single ._invoke method. - - function defineIteratorMethods(prototype) { - ["next", "throw", "return"].forEach(function (method) { - prototype[method] = function (arg) { - return this._invoke(method, arg); - }; - }); - } - - runtime.isGeneratorFunction = function (genFun) { - var ctor = typeof genFun === "function" && genFun.constructor; - return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can - // do is to check its .name property. - (ctor.displayName || ctor.name) === "GeneratorFunction" : false; - }; - - runtime.mark = function (genFun) { - if (Object.setPrototypeOf) { - Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); - } else { - genFun.__proto__ = GeneratorFunctionPrototype; - - if (!(toStringTagSymbol in genFun)) { - genFun[toStringTagSymbol] = "GeneratorFunction"; - } - } - - genFun.prototype = Object.create(Gp); - return genFun; - }; // Within the body of any async function, `await x` is transformed to - // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test - // `hasOwn.call(value, "__await")` to determine if the yielded value is - // meant to be awaited. - - - runtime.awrap = function (arg) { - return { - __await: arg - }; - }; - - function AsyncIterator(generator) { - function invoke(method, arg, resolve, reject) { - var record = tryCatch(generator[method], generator, arg); - - if (record.type === "throw") { - reject(record.arg); - } else { - var result = record.arg; - var value = result.value; - - if (value && typeof value === "object" && hasOwn.call(value, "__await")) { - return Promise.resolve(value.__await).then(function (value) { - invoke("next", value, resolve, reject); - }, function (err) { - invoke("throw", err, resolve, reject); - }); - } - - return Promise.resolve(value).then(function (unwrapped) { - // When a yielded Promise is resolved, its final value becomes - // the .value of the Promise<{value,done}> result for the - // current iteration. If the Promise is rejected, however, the - // result for this iteration will be rejected with the same - // reason. Note that rejections of yielded Promises are not - // thrown back into the generator function, as is the case - // when an awaited Promise is rejected. This difference in - // behavior between yield and await is important, because it - // allows the consumer to decide what to do with the yielded - // rejection (swallow it and continue, manually .throw it back - // into the generator, abandon iteration, whatever). With - // await, by contrast, there is no opportunity to examine the - // rejection reason outside the generator function, so the - // only option is to throw it from the await expression, and - // let the generator function handle the exception. - result.value = unwrapped; - resolve(result); - }, reject); - } - } - - var previousPromise; - - function enqueue(method, arg) { - function callInvokeWithMethodAndArg() { - return new Promise(function (resolve, reject) { - invoke(method, arg, resolve, reject); - }); - } - - return previousPromise = // If enqueue has been called before, then we want to wait until - // all previous Promises have been resolved before calling invoke, - // so that results are always delivered in the correct order. If - // enqueue has not been called before, then it is important to - // call invoke immediately, without waiting on a callback to fire, - // so that the async generator function has the opportunity to do - // any necessary setup in a predictable way. This predictability - // is why the Promise constructor synchronously invokes its - // executor callback, and why async functions synchronously - // execute code before the first await. Since we implement simple - // async functions in terms of async generators, it is especially - // important to get this right, even though it requires care. - previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later - // invocations of the iterator. - callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); - } // Define the unified helper method that is used to implement .next, - // .throw, and .return (see defineIteratorMethods). - - - this._invoke = enqueue; - } - - defineIteratorMethods(AsyncIterator.prototype); - - AsyncIterator.prototype[asyncIteratorSymbol] = function () { - return this; - }; - - runtime.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of - // AsyncIterator objects; they just return a Promise for the value of - // the final result produced by the iterator. - - runtime.async = function (innerFn, outerFn, self, tryLocsList) { - var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); - return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. - : iter.next().then(function (result) { - return result.done ? result.value : iter.next(); - }); - }; - - function makeInvokeMethod(innerFn, self, context) { - var state = GenStateSuspendedStart; - return function invoke(method, arg) { - if (state === GenStateExecuting) { - throw new Error("Generator is already running"); - } - - if (state === GenStateCompleted) { - if (method === "throw") { - throw arg; - } // Be forgiving, per 25.3.3.3.3 of the spec: - // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - - - return doneResult(); - } - - context.method = method; - context.arg = arg; - - while (true) { - var delegate = context.delegate; - - if (delegate) { - var delegateResult = maybeInvokeDelegate(delegate, context); - - if (delegateResult) { - if (delegateResult === ContinueSentinel) continue; - return delegateResult; - } - } - - if (context.method === "next") { - // Setting context._sent for legacy support of Babel's - // function.sent implementation. - context.sent = context._sent = context.arg; - } else if (context.method === "throw") { - if (state === GenStateSuspendedStart) { - state = GenStateCompleted; - throw context.arg; - } - - context.dispatchException(context.arg); - } else if (context.method === "return") { - context.abrupt("return", context.arg); - } - - state = GenStateExecuting; - var record = tryCatch(innerFn, self, context); - - if (record.type === "normal") { - // If an exception is thrown from innerFn, we leave state === - // GenStateExecuting and loop back for another invocation. - state = context.done ? GenStateCompleted : GenStateSuspendedYield; - - if (record.arg === ContinueSentinel) { - continue; - } - - return { - value: record.arg, - done: context.done - }; - } else if (record.type === "throw") { - state = GenStateCompleted; // Dispatch the exception by looping back around to the - // context.dispatchException(context.arg) call above. - - context.method = "throw"; - context.arg = record.arg; - } - } - }; - } // Call delegate.iterator[context.method](context.arg) and handle the - // result, either by returning a { value, done } result from the - // delegate iterator, or by modifying context.method and context.arg, - // setting context.delegate to null, and returning the ContinueSentinel. - - - function maybeInvokeDelegate(delegate, context) { - var method = delegate.iterator[context.method]; - - if (method === undefined) { - // A .throw or .return when the delegate iterator has no .throw - // method always terminates the yield* loop. - context.delegate = null; - - if (context.method === "throw") { - if (delegate.iterator.return) { - // If the delegate iterator has a return method, give it a - // chance to clean up. - context.method = "return"; - context.arg = undefined; - maybeInvokeDelegate(delegate, context); - - if (context.method === "throw") { - // If maybeInvokeDelegate(context) changed context.method from - // "return" to "throw", let that override the TypeError below. - return ContinueSentinel; - } - } - - context.method = "throw"; - context.arg = new TypeError("The iterator does not provide a 'throw' method"); - } - - return ContinueSentinel; - } - - var record = tryCatch(method, delegate.iterator, context.arg); - - if (record.type === "throw") { - context.method = "throw"; - context.arg = record.arg; - context.delegate = null; - return ContinueSentinel; - } - - var info = record.arg; - - if (!info) { - context.method = "throw"; - context.arg = new TypeError("iterator result is not an object"); - context.delegate = null; - return ContinueSentinel; - } - - if (info.done) { - // Assign the result of the finished delegate to the temporary - // variable specified by delegate.resultName (see delegateYield). - context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield). - - context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the - // exception, let the outer generator proceed normally. If - // context.method was "next", forget context.arg since it has been - // "consumed" by the delegate iterator. If context.method was - // "return", allow the original .return call to continue in the - // outer generator. - - if (context.method !== "return") { - context.method = "next"; - context.arg = undefined; - } - } else { - // Re-yield the result returned by the delegate method. - return info; - } // The delegate iterator is finished, so forget it and continue with - // the outer generator. - - - context.delegate = null; - return ContinueSentinel; - } // Define Generator.prototype.{next,throw,return} in terms of the - // unified ._invoke helper method. - - - defineIteratorMethods(Gp); - Gp[toStringTagSymbol] = "Generator"; // A Generator should always return itself as the iterator object when the - // @@iterator function is called on it. Some browsers' implementations of the - // iterator prototype chain incorrectly implement this, causing the Generator - // object to not be returned from this call. This ensures that doesn't happen. - // See https://github.com/facebook/regenerator/issues/274 for more details. - - Gp[iteratorSymbol] = function () { - return this; - }; - - Gp.toString = function () { - return "[object Generator]"; - }; - - function pushTryEntry(locs) { - var entry = { - tryLoc: locs[0] - }; - - if (1 in locs) { - entry.catchLoc = locs[1]; - } - - if (2 in locs) { - entry.finallyLoc = locs[2]; - entry.afterLoc = locs[3]; - } - - this.tryEntries.push(entry); - } - - function resetTryEntry(entry) { - var record = entry.completion || {}; - record.type = "normal"; - delete record.arg; - entry.completion = record; - } - - function Context(tryLocsList) { - // The root entry object (effectively a try statement without a catch - // or a finally block) gives us a place to store values thrown from - // locations where there is no enclosing try statement. - this.tryEntries = [{ - tryLoc: "root" - }]; - tryLocsList.forEach(pushTryEntry, this); - this.reset(true); - } - - runtime.keys = function (object) { - var keys = []; - - for (var key in object) { - keys.push(key); - } - - keys.reverse(); // Rather than returning an object with a next method, we keep - // things simple and return the next function itself. - - return function next() { - while (keys.length) { - var key = keys.pop(); - - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } // To avoid creating an additional object, we just hang the .value - // and .done properties off the next function object itself. This - // also ensures that the minifier will not anonymize the function. - - - next.done = true; - return next; - }; - }; - - function values(iterable) { - if (iterable) { - var iteratorMethod = iterable[iteratorSymbol]; - - if (iteratorMethod) { - return iteratorMethod.call(iterable); - } - - if (typeof iterable.next === "function") { - return iterable; - } - - if (!isNaN(iterable.length)) { - var i = -1, - next = function next() { - while (++i < iterable.length) { - if (hasOwn.call(iterable, i)) { - next.value = iterable[i]; - next.done = false; - return next; - } - } - - next.value = undefined; - next.done = true; - return next; - }; - - return next.next = next; - } - } // Return an iterator with no values. - - - return { - next: doneResult - }; - } - - runtime.values = values; - - function doneResult() { - return { - value: undefined, - done: true - }; - } - - Context.prototype = { - constructor: Context, - reset: function (skipTempReset) { - this.prev = 0; - this.next = 0; // Resetting context._sent for legacy support of Babel's - // function.sent implementation. - - this.sent = this._sent = undefined; - this.done = false; - this.delegate = null; - this.method = "next"; - this.arg = undefined; - this.tryEntries.forEach(resetTryEntry); - - if (!skipTempReset) { - for (var name in this) { - // Not sure about the optimal order of these conditions: - if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { - this[name] = undefined; - } - } - } - }, - stop: function () { - this.done = true; - var rootEntry = this.tryEntries[0]; - var rootRecord = rootEntry.completion; - - if (rootRecord.type === "throw") { - throw rootRecord.arg; - } - - return this.rval; - }, - dispatchException: function (exception) { - if (this.done) { - throw exception; - } - - var context = this; - - function handle(loc, caught) { - record.type = "throw"; - record.arg = exception; - context.next = loc; - - if (caught) { - // If the dispatched exception was caught by a catch block, - // then let that catch block handle the exception normally. - context.method = "next"; - context.arg = undefined; - } - - return !!caught; - } - - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - var record = entry.completion; - - if (entry.tryLoc === "root") { - // Exception thrown outside of any try block that could handle - // it, so set the completion value of the entire function to - // throw the exception. - return handle("end"); - } - - if (entry.tryLoc <= this.prev) { - var hasCatch = hasOwn.call(entry, "catchLoc"); - var hasFinally = hasOwn.call(entry, "finallyLoc"); - - if (hasCatch && hasFinally) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } else if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } - } else if (hasCatch) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } - } else if (hasFinally) { - if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } - } else { - throw new Error("try statement without catch or finally"); - } - } - } - }, - abrupt: function (type, arg) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - - if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { - var finallyEntry = entry; - break; - } - } - - if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { - // Ignore the finally entry if control is not jumping to a - // location outside the try/catch block. - finallyEntry = null; - } - - var record = finallyEntry ? finallyEntry.completion : {}; - record.type = type; - record.arg = arg; - - if (finallyEntry) { - this.method = "next"; - this.next = finallyEntry.finallyLoc; - return ContinueSentinel; - } - - return this.complete(record); - }, - complete: function (record, afterLoc) { - if (record.type === "throw") { - throw record.arg; - } - - if (record.type === "break" || record.type === "continue") { - this.next = record.arg; - } else if (record.type === "return") { - this.rval = this.arg = record.arg; - this.method = "return"; - this.next = "end"; - } else if (record.type === "normal" && afterLoc) { - this.next = afterLoc; - } - - return ContinueSentinel; - }, - finish: function (finallyLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - - if (entry.finallyLoc === finallyLoc) { - this.complete(entry.completion, entry.afterLoc); - resetTryEntry(entry); - return ContinueSentinel; - } - } - }, - "catch": function (tryLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - - if (entry.tryLoc === tryLoc) { - var record = entry.completion; - - if (record.type === "throw") { - var thrown = record.arg; - resetTryEntry(entry); - } - - return thrown; - } - } // The context.catch method must only be called with a location - // argument that corresponds to a known catch block. - - - throw new Error("illegal catch attempt"); - }, - delegateYield: function (iterable, resultName, nextLoc) { - this.delegate = { - iterator: values(iterable), - resultName: resultName, - nextLoc: nextLoc - }; - - if (this.method === "next") { - // Deliberately forget the last sent value so that we don't - // accidentally pass it on to the delegate. - this.arg = undefined; - } - - return ContinueSentinel; - } - }; -}( // In sloppy mode, unbound `this` refers to the global object, fallback to -// Function constructor if we're in global strict mode. That is sadly a form -// of indirect eval which violates Content Security Policy. -function () { - return this; -}() || Function("return this")()); - -/***/ }), - -/***/ 1161: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = __webpack_require__(7034); - -/***/ }), - -/***/ 6434: -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Native Javascript for Bootstrap 4 v2.0.27 | © dnp_theme | MIT-License -(function (root, factory) { - if (true) { - // AMD support: - !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else { var bsn; } -})(this, function () { - /* Native Javascript for Bootstrap 4 | Internal Utility Functions - ----------------------------------------------------------------*/ - "use strict"; // globals - - var globalObject = typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : this || window, - DOC = document, - HTML = DOC.documentElement, - body = 'body', - // allow the library to be used in - // Native Javascript for Bootstrap Global Object - BSN = globalObject.BSN = {}, - supports = BSN.supports = [], - // function toggle attributes - dataToggle = 'data-toggle', - dataDismiss = 'data-dismiss', - dataSpy = 'data-spy', - dataRide = 'data-ride', - // components - stringAlert = 'Alert', - stringButton = 'Button', - stringCarousel = 'Carousel', - stringCollapse = 'Collapse', - stringDropdown = 'Dropdown', - stringModal = 'Modal', - stringPopover = 'Popover', - stringScrollSpy = 'ScrollSpy', - stringTab = 'Tab', - stringTooltip = 'Tooltip', - stringToast = 'Toast', - // options DATA API - dataAutohide = 'data-autohide', - databackdrop = 'data-backdrop', - dataKeyboard = 'data-keyboard', - dataTarget = 'data-target', - dataInterval = 'data-interval', - dataHeight = 'data-height', - dataPause = 'data-pause', - dataTitle = 'data-title', - dataOriginalTitle = 'data-original-title', - dataDismissible = 'data-dismissible', - dataTrigger = 'data-trigger', - dataAnimation = 'data-animation', - dataContainer = 'data-container', - dataPlacement = 'data-placement', - dataDelay = 'data-delay', - // option keys - backdrop = 'backdrop', - keyboard = 'keyboard', - delay = 'delay', - content = 'content', - target = 'target', - currentTarget = 'currentTarget', - interval = 'interval', - pause = 'pause', - animation = 'animation', - placement = 'placement', - container = 'container', - // box model - offsetTop = 'offsetTop', - offsetBottom = 'offsetBottom', - offsetLeft = 'offsetLeft', - scrollTop = 'scrollTop', - scrollLeft = 'scrollLeft', - clientWidth = 'clientWidth', - clientHeight = 'clientHeight', - offsetWidth = 'offsetWidth', - offsetHeight = 'offsetHeight', - innerWidth = 'innerWidth', - innerHeight = 'innerHeight', - scrollHeight = 'scrollHeight', - scrollWidth = 'scrollWidth', - height = 'height', - // aria - ariaExpanded = 'aria-expanded', - ariaHidden = 'aria-hidden', - ariaSelected = 'aria-selected', - // event names - clickEvent = 'click', - focusEvent = 'focus', - hoverEvent = 'hover', - keydownEvent = 'keydown', - keyupEvent = 'keyup', - resizeEvent = 'resize', - // passive - scrollEvent = 'scroll', - // passive - mouseHover = 'onmouseleave' in DOC ? ['mouseenter', 'mouseleave'] : ['mouseover', 'mouseout'], - // touch since 2.0.26 - touchEvents = { - start: 'touchstart', - end: 'touchend', - move: 'touchmove' - }, - // passive - // originalEvents - showEvent = 'show', - shownEvent = 'shown', - hideEvent = 'hide', - hiddenEvent = 'hidden', - closeEvent = 'close', - closedEvent = 'closed', - slidEvent = 'slid', - slideEvent = 'slide', - changeEvent = 'change', - // other - getAttribute = 'getAttribute', - setAttribute = 'setAttribute', - hasAttribute = 'hasAttribute', - createElement = 'createElement', - appendChild = 'appendChild', - innerHTML = 'innerHTML', - getElementsByTagName = 'getElementsByTagName', - preventDefault = 'preventDefault', - getBoundingClientRect = 'getBoundingClientRect', - querySelectorAll = 'querySelectorAll', - getElementsByCLASSNAME = 'getElementsByClassName', - getComputedStyle = 'getComputedStyle', - indexOf = 'indexOf', - parentNode = 'parentNode', - length = 'length', - toLowerCase = 'toLowerCase', - Transition = 'Transition', - Duration = 'Duration', - Webkit = 'Webkit', - style = 'style', - push = 'push', - tabindex = 'tabindex', - contains = 'contains', - active = 'active', - showClass = 'show', - collapsing = 'collapsing', - disabled = 'disabled', - loading = 'loading', - left = 'left', - right = 'right', - top = 'top', - bottom = 'bottom', - // tooltip / popover - tipPositions = /\b(top|bottom|left|right)+/, - // modal - modalOverlay = 0, - fixedTop = 'fixed-top', - fixedBottom = 'fixed-bottom', - // transitionEnd since 2.0.4 - supportTransitions = Webkit + Transition in HTML[style] || Transition[toLowerCase]() in HTML[style], - transitionEndEvent = Webkit + Transition in HTML[style] ? Webkit[toLowerCase]() + Transition + 'End' : Transition[toLowerCase]() + 'end', - transitionDuration = Webkit + Duration in HTML[style] ? Webkit[toLowerCase]() + Transition + Duration : Transition[toLowerCase]() + Duration, - // set new focus element since 2.0.3 - setFocus = function (element) { - element.focus ? element.focus() : element.setActive(); - }, - // class manipulation, since 2.0.0 requires polyfill.js - addClass = function (element, classNAME) { - element.classList.add(classNAME); - }, - removeClass = function (element, classNAME) { - element.classList.remove(classNAME); - }, - hasClass = function (element, classNAME) { - // since 2.0.0 - return element.classList[contains](classNAME); - }, - // selection methods - getElementsByClassName = function (element, classNAME) { - // returns Array - return [].slice.call(element[getElementsByCLASSNAME](classNAME)); - }, - queryElement = function (selector, parent) { - var lookUp = parent ? parent : DOC; - return typeof selector === 'object' ? selector : lookUp.querySelector(selector); - }, - getClosest = function (element, selector) { - //element is the element and selector is for the closest parent element to find - // source http://gomakethings.com/climbing-up-and-down-the-dom-tree-with-vanilla-javascript/ - var firstChar = selector.charAt(0), - selectorSubstring = selector.substr(1); - - if (firstChar === '.') { - // If selector is a class - for (; element && element !== DOC; element = element[parentNode]) { - // Get closest match - if (queryElement(selector, element[parentNode]) !== null && hasClass(element, selectorSubstring)) { - return element; - } - } - } else if (firstChar === '#') { - // If selector is an ID - for (; element && element !== DOC; element = element[parentNode]) { - // Get closest match - if (element.id === selectorSubstring) { - return element; - } - } - } - - return false; - }, - // event attach jQuery style / trigger since 1.2.0 - on = function (element, event, handler, options) { - options = options || false; - element.addEventListener(event, handler, options); - }, - off = function (element, event, handler, options) { - options = options || false; - element.removeEventListener(event, handler, options); - }, - one = function (element, event, handler, options) { - // one since 2.0.4 - on(element, event, function handlerWrapper(e) { - handler(e); - off(element, event, handlerWrapper, options); - }, options); - }, - // determine support for passive events - supportPassive = function () { - // Test via a getter in the options object to see if the passive property is accessed - var result = false; - - try { - var opts = Object.defineProperty({}, 'passive', { - get: function () { - result = true; - } - }); - one(globalObject, 'testPassive', null, opts); - } catch (e) {} - - return result; - }(), - // event options - // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection - passiveHandler = supportPassive ? { - passive: true - } : false, - // transitions - getTransitionDurationFromElement = function (element) { - var duration = supportTransitions ? globalObject[getComputedStyle](element)[transitionDuration] : 0; - duration = parseFloat(duration); - duration = typeof duration === 'number' && !isNaN(duration) ? duration * 1000 : 0; - return duration; // we take a short offset to make sure we fire on the next frame after animation - }, - emulateTransitionEnd = function (element, handler) { - // emulateTransitionEnd since 2.0.4 - var called = 0, - duration = getTransitionDurationFromElement(element); - duration ? one(element, transitionEndEvent, function (e) { - !called && handler(e), called = 1; - }) : setTimeout(function () { - !called && handler(), called = 1; - }, 17); - }, - bootstrapCustomEvent = function (eventName, componentName, related) { - var OriginalCustomEvent = new CustomEvent(eventName + '.bs.' + componentName); - OriginalCustomEvent.relatedTarget = related; - this.dispatchEvent(OriginalCustomEvent); - }, - // tooltip / popover stuff - getScroll = function () { - // also Affix and ScrollSpy uses it - return { - y: globalObject.pageYOffset || HTML[scrollTop], - x: globalObject.pageXOffset || HTML[scrollLeft] - }; - }, - styleTip = function (link, element, position, parent) { - // both popovers and tooltips (target,tooltip,placement,elementToAppendTo) - var elementDimensions = { - w: element[offsetWidth], - h: element[offsetHeight] - }, - windowWidth = HTML[clientWidth] || DOC[body][clientWidth], - windowHeight = HTML[clientHeight] || DOC[body][clientHeight], - rect = link[getBoundingClientRect](), - scroll = parent === DOC[body] ? getScroll() : { - x: parent[offsetLeft] + parent[scrollLeft], - y: parent[offsetTop] + parent[scrollTop] - }, - linkDimensions = { - w: rect[right] - rect[left], - h: rect[bottom] - rect[top] - }, - isPopover = hasClass(element, 'popover'), - topPosition, - leftPosition, - arrow = queryElement('.arrow', element), - arrowTop, - arrowLeft, - arrowWidth, - arrowHeight, - halfTopExceed = rect[top] + linkDimensions.h / 2 - elementDimensions.h / 2 < 0, - halfLeftExceed = rect[left] + linkDimensions.w / 2 - elementDimensions.w / 2 < 0, - halfRightExceed = rect[left] + elementDimensions.w / 2 + linkDimensions.w / 2 >= windowWidth, - halfBottomExceed = rect[top] + elementDimensions.h / 2 + linkDimensions.h / 2 >= windowHeight, - topExceed = rect[top] - elementDimensions.h < 0, - leftExceed = rect[left] - elementDimensions.w < 0, - bottomExceed = rect[top] + elementDimensions.h + linkDimensions.h >= windowHeight, - rightExceed = rect[left] + elementDimensions.w + linkDimensions.w >= windowWidth; // recompute position - - position = (position === left || position === right) && leftExceed && rightExceed ? top : position; // first, when both left and right limits are exceeded, we fall back to top|bottom - - position = position === top && topExceed ? bottom : position; - position = position === bottom && bottomExceed ? top : position; - position = position === left && leftExceed ? right : position; - position = position === right && rightExceed ? left : position; // update tooltip/popover class - - element.className[indexOf](position) === -1 && (element.className = element.className.replace(tipPositions, position)); // we check the computed width & height and update here - - arrowWidth = arrow[offsetWidth]; - arrowHeight = arrow[offsetHeight]; // apply styling to tooltip or popover - - if (position === left || position === right) { - // secondary|side positions - if (position === left) { - // LEFT - leftPosition = rect[left] + scroll.x - elementDimensions.w - (isPopover ? arrowWidth : 0); - } else { - // RIGHT - leftPosition = rect[left] + scroll.x + linkDimensions.w; - } // adjust top and arrow - - - if (halfTopExceed) { - topPosition = rect[top] + scroll.y; - arrowTop = linkDimensions.h / 2 - arrowWidth; - } else if (halfBottomExceed) { - topPosition = rect[top] + scroll.y - elementDimensions.h + linkDimensions.h; - arrowTop = elementDimensions.h - linkDimensions.h / 2 - arrowWidth; - } else { - topPosition = rect[top] + scroll.y - elementDimensions.h / 2 + linkDimensions.h / 2; - arrowTop = elementDimensions.h / 2 - (isPopover ? arrowHeight * 0.9 : arrowHeight / 2); - } - } else if (position === top || position === bottom) { - // primary|vertical positions - if (position === top) { - // TOP - topPosition = rect[top] + scroll.y - elementDimensions.h - (isPopover ? arrowHeight : 0); - } else { - // BOTTOM - topPosition = rect[top] + scroll.y + linkDimensions.h; - } // adjust left | right and also the arrow - - - if (halfLeftExceed) { - leftPosition = 0; - arrowLeft = rect[left] + linkDimensions.w / 2 - arrowWidth; - } else if (halfRightExceed) { - leftPosition = windowWidth - elementDimensions.w * 1.01; - arrowLeft = elementDimensions.w - (windowWidth - rect[left]) + linkDimensions.w / 2 - arrowWidth / 2; - } else { - leftPosition = rect[left] + scroll.x - elementDimensions.w / 2 + linkDimensions.w / 2; - arrowLeft = elementDimensions.w / 2 - (isPopover ? arrowWidth : arrowWidth / 2); - } - } // apply style to tooltip/popover and its arrow - - - element[style][top] = topPosition + 'px'; - element[style][left] = leftPosition + 'px'; - arrowTop && (arrow[style][top] = arrowTop + 'px'); - arrowLeft && (arrow[style][left] = arrowLeft + 'px'); - }; - - BSN.version = '2.0.27'; - /* Native Javascript for Bootstrap 4 | Alert - -------------------------------------------*/ - // ALERT DEFINITION - // ================ - - var Alert = function (element) { - // initialization element - element = queryElement(element); // bind, target alert, duration and stuff - - var self = this, - component = 'alert', - alert = getClosest(element, '.' + component), - triggerHandler = function () { - hasClass(alert, 'fade') ? emulateTransitionEnd(alert, transitionEndHandler) : transitionEndHandler(); - }, - // handlers - clickHandler = function (e) { - alert = getClosest(e[target], '.' + component); - element = queryElement('[' + dataDismiss + '="' + component + '"]', alert); - element && alert && (element === e[target] || element[contains](e[target])) && self.close(); - }, - transitionEndHandler = function () { - bootstrapCustomEvent.call(alert, closedEvent, component); - off(element, clickEvent, clickHandler); // detach it's listener - - alert[parentNode].removeChild(alert); - }; // public method - - - this.close = function () { - if (alert && element && hasClass(alert, showClass)) { - bootstrapCustomEvent.call(alert, closeEvent, component); - removeClass(alert, showClass); - alert && triggerHandler(); - } - }; // init - - - if (!(stringAlert in element)) { - // prevent adding event handlers twice - on(element, clickEvent, clickHandler); - } - - element[stringAlert] = self; - }; // ALERT DATA API - // ============== - - - supports[push]([stringAlert, Alert, '[' + dataDismiss + '="alert"]']); - /* Native Javascript for Bootstrap 4 | Button - ---------------------------------------------*/ - // BUTTON DEFINITION - // =================== - - var Button = function (element) { - // initialization element - element = queryElement(element); // constant - - var toggled = false, - // toggled makes sure to prevent triggering twice the change.bs.button events - // strings - component = 'button', - checked = 'checked', - LABEL = 'LABEL', - INPUT = 'INPUT', - // private methods - keyHandler = function (e) { - var key = e.which || e.keyCode; - key === 32 && e[target] === DOC.activeElement && toggle(e); - }, - preventScroll = function (e) { - var key = e.which || e.keyCode; - key === 32 && e[preventDefault](); - }, - toggle = function (e) { - var label = e[target].tagName === LABEL ? e[target] : e[target][parentNode].tagName === LABEL ? e[target][parentNode] : null; // the .btn label - - if (!label) return; //react if a label or its immediate child is clicked - - var labels = getElementsByClassName(label[parentNode], 'btn'), - // all the button group buttons - input = label[getElementsByTagName](INPUT)[0]; - if (!input) return; // return if no input found - // manage the dom manipulation - - if (input.type === 'checkbox') { - //checkboxes - if (!input[checked]) { - addClass(label, active); - input[getAttribute](checked); - input[setAttribute](checked, checked); - input[checked] = true; - } else { - removeClass(label, active); - input[getAttribute](checked); - input.removeAttribute(checked); - input[checked] = false; - } - - if (!toggled) { - // prevent triggering the event twice - toggled = true; - bootstrapCustomEvent.call(input, changeEvent, component); //trigger the change for the input - - bootstrapCustomEvent.call(element, changeEvent, component); //trigger the change for the btn-group - } - } - - if (input.type === 'radio' && !toggled) { - // radio buttons - // don't trigger if already active (the OR condition is a hack to check if the buttons were selected with key press and NOT mouse click) - if (!input[checked] || e.screenX === 0 && e.screenY == 0) { - addClass(label, active); - addClass(label, focusEvent); - input[setAttribute](checked, checked); - input[checked] = true; - bootstrapCustomEvent.call(input, changeEvent, component); //trigger the change for the input - - bootstrapCustomEvent.call(element, changeEvent, component); //trigger the change for the btn-group - - toggled = true; - - for (var i = 0, ll = labels[length]; i < ll; i++) { - var otherLabel = labels[i], - otherInput = otherLabel[getElementsByTagName](INPUT)[0]; - - if (otherLabel !== label && hasClass(otherLabel, active)) { - removeClass(otherLabel, active); - otherInput.removeAttribute(checked); - otherInput[checked] = false; - bootstrapCustomEvent.call(otherInput, changeEvent, component); // trigger the change - } - } - } - } - - setTimeout(function () { - toggled = false; - }, 50); - }, - focusHandler = function (e) { - addClass(e[target][parentNode], focusEvent); - }, - blurHandler = function (e) { - removeClass(e[target][parentNode], focusEvent); - }; // init - - - if (!(stringButton in element)) { - // prevent adding event handlers twice - on(element, clickEvent, toggle); - on(element, keyupEvent, keyHandler), on(element, keydownEvent, preventScroll); - var allBtns = getElementsByClassName(element, 'btn'); - - for (var i = 0; i < allBtns.length; i++) { - var input = allBtns[i][getElementsByTagName](INPUT)[0]; - on(input, focusEvent, focusHandler), on(input, 'blur', blurHandler); - } - } // activate items on load - - - var labelsToACtivate = getElementsByClassName(element, 'btn'), - lbll = labelsToACtivate[length]; - - for (var i = 0; i < lbll; i++) { - !hasClass(labelsToACtivate[i], active) && queryElement('input:checked', labelsToACtivate[i]) && addClass(labelsToACtivate[i], active); - } - - element[stringButton] = this; - }; // BUTTON DATA API - // ================= - - - supports[push]([stringButton, Button, '[' + dataToggle + '="buttons"]']); - /* Native Javascript for Bootstrap 4 | Collapse - -----------------------------------------------*/ - // COLLAPSE DEFINITION - // =================== - - var Collapse = function (element, options) { - // initialization element - element = queryElement(element); // set options - - options = options || {}; // event targets and constants - - var accordion = null, - collapse = null, - self = this, - accordionData = element[getAttribute]('data-parent'), - activeCollapse, - activeElement, - // component strings - component = 'collapse', - collapsed = 'collapsed', - isAnimating = 'isAnimating', - // private methods - openAction = function (collapseElement, toggle) { - bootstrapCustomEvent.call(collapseElement, showEvent, component); - collapseElement[isAnimating] = true; - addClass(collapseElement, collapsing); - removeClass(collapseElement, component); - collapseElement[style][height] = collapseElement[scrollHeight] + 'px'; - emulateTransitionEnd(collapseElement, function () { - collapseElement[isAnimating] = false; - collapseElement[setAttribute](ariaExpanded, 'true'); - toggle[setAttribute](ariaExpanded, 'true'); - removeClass(collapseElement, collapsing); - addClass(collapseElement, component); - addClass(collapseElement, showClass); - collapseElement[style][height] = ''; - bootstrapCustomEvent.call(collapseElement, shownEvent, component); - }); - }, - closeAction = function (collapseElement, toggle) { - bootstrapCustomEvent.call(collapseElement, hideEvent, component); - collapseElement[isAnimating] = true; - collapseElement[style][height] = collapseElement[scrollHeight] + 'px'; // set height first - - removeClass(collapseElement, component); - removeClass(collapseElement, showClass); - addClass(collapseElement, collapsing); - collapseElement[offsetWidth]; // force reflow to enable transition - - collapseElement[style][height] = '0px'; - emulateTransitionEnd(collapseElement, function () { - collapseElement[isAnimating] = false; - collapseElement[setAttribute](ariaExpanded, 'false'); - toggle[setAttribute](ariaExpanded, 'false'); - removeClass(collapseElement, collapsing); - addClass(collapseElement, component); - collapseElement[style][height] = ''; - bootstrapCustomEvent.call(collapseElement, hiddenEvent, component); - }); - }, - getTarget = function () { - var href = element.href && element[getAttribute]('href'), - parent = element[getAttribute](dataTarget), - id = href || parent && parent.charAt(0) === '#' && parent; - return id && queryElement(id); - }; // public methods - - - this.toggle = function (e) { - e[preventDefault](); - - if (!hasClass(collapse, showClass)) { - self.show(); - } else { - self.hide(); - } - }; - - this.hide = function () { - if (collapse[isAnimating]) return; - closeAction(collapse, element); - addClass(element, collapsed); - }; - - this.show = function () { - if (accordion) { - activeCollapse = queryElement('.' + component + '.' + showClass, accordion); - activeElement = activeCollapse && (queryElement('[' + dataTarget + '="#' + activeCollapse.id + '"]', accordion) || queryElement('[href="#' + activeCollapse.id + '"]', accordion)); - } - - if (!collapse[isAnimating] || activeCollapse && !activeCollapse[isAnimating]) { - if (activeElement && activeCollapse !== collapse) { - closeAction(activeCollapse, activeElement); - addClass(activeElement, collapsed); - } - - openAction(collapse, element); - removeClass(element, collapsed); - } - }; // init - - - if (!(stringCollapse in element)) { - // prevent adding event handlers twice - on(element, clickEvent, self.toggle); - } - - collapse = getTarget(); - collapse[isAnimating] = false; // when true it will prevent click handlers - - accordion = queryElement(options.parent) || accordionData && getClosest(element, accordionData); - element[stringCollapse] = self; - }; // COLLAPSE DATA API - // ================= - - - supports[push]([stringCollapse, Collapse, '[' + dataToggle + '="collapse"]']); - /* Native Javascript for Bootstrap 4 | Dropdown - ----------------------------------------------*/ - // DROPDOWN DEFINITION - // =================== - - var Dropdown = function (element, option) { - // initialization element - element = queryElement(element); // set option - - this.persist = option === true || element[getAttribute]('data-persist') === 'true' || false; // constants, event targets, strings - - var self = this, - children = 'children', - parent = element[parentNode], - component = 'dropdown', - open = 'open', - relatedTarget = null, - menu = queryElement('.dropdown-menu', parent), - menuItems = function () { - var set = menu[children], - newSet = []; - - for (var i = 0; i < set[length]; i++) { - set[i][children][length] && set[i][children][0].tagName === 'A' && newSet[push](set[i][children][0]); - set[i].tagName === 'A' && newSet[push](set[i]); - } - - return newSet; - }(), - // preventDefault on empty anchor links - preventEmptyAnchor = function (anchor) { - (anchor.href && anchor.href.slice(-1) === '#' || anchor[parentNode] && anchor[parentNode].href && anchor[parentNode].href.slice(-1) === '#') && this[preventDefault](); - }, - // toggle dismissible events - toggleDismiss = function () { - var type = element[open] ? on : off; - type(DOC, clickEvent, dismissHandler); - type(DOC, keydownEvent, preventScroll); - type(DOC, keyupEvent, keyHandler); - type(DOC, focusEvent, dismissHandler, true); - }, - // handlers - dismissHandler = function (e) { - var eventTarget = e[target], - hasData = eventTarget && (eventTarget[getAttribute](dataToggle) || eventTarget[parentNode] && getAttribute in eventTarget[parentNode] && eventTarget[parentNode][getAttribute](dataToggle)); - - if (e.type === focusEvent && (eventTarget === element || eventTarget === menu || menu[contains](eventTarget))) { - return; - } - - if ((eventTarget === menu || menu[contains](eventTarget)) && (self.persist || hasData)) { - return; - } else { - relatedTarget = eventTarget === element || element[contains](eventTarget) ? element : null; - hide(); - } - - preventEmptyAnchor.call(e, eventTarget); - }, - clickHandler = function (e) { - relatedTarget = element; - show(); - preventEmptyAnchor.call(e, e[target]); - }, - preventScroll = function (e) { - var key = e.which || e.keyCode; - - if (key === 38 || key === 40) { - e[preventDefault](); - } - }, - keyHandler = function (e) { - var key = e.which || e.keyCode, - activeItem = DOC.activeElement, - idx = menuItems[indexOf](activeItem), - isSameElement = activeItem === element, - isInsideMenu = menu[contains](activeItem), - isMenuItem = activeItem[parentNode] === menu || activeItem[parentNode][parentNode] === menu; - - if (isMenuItem) { - // navigate up | down - idx = isSameElement ? 0 : key === 38 ? idx > 1 ? idx - 1 : 0 : key === 40 ? idx < menuItems[length] - 1 ? idx + 1 : idx : idx; - menuItems[idx] && setFocus(menuItems[idx]); - } - - if ((menuItems[length] && isMenuItem // menu has items - || !menuItems[length] && (isInsideMenu || isSameElement) // menu might be a form - || !isInsideMenu) && // or the focused element is not in the menu at all - element[open] && key === 27 // menu must be open - ) { - self.toggle(); - relatedTarget = null; - } - }, - // private methods - show = function () { - bootstrapCustomEvent.call(parent, showEvent, component, relatedTarget); - addClass(menu, showClass); - addClass(parent, showClass); - element[setAttribute](ariaExpanded, true); - bootstrapCustomEvent.call(parent, shownEvent, component, relatedTarget); - element[open] = true; - off(element, clickEvent, clickHandler); - setTimeout(function () { - setFocus(menu[getElementsByTagName]('INPUT')[0] || element); // focus the first input item | element - - toggleDismiss(); - }, 1); - }, - hide = function () { - bootstrapCustomEvent.call(parent, hideEvent, component, relatedTarget); - removeClass(menu, showClass); - removeClass(parent, showClass); - element[setAttribute](ariaExpanded, false); - bootstrapCustomEvent.call(parent, hiddenEvent, component, relatedTarget); - element[open] = false; - toggleDismiss(); - setFocus(element); - setTimeout(function () { - on(element, clickEvent, clickHandler); - }, 1); - }; // set initial state to closed - - - element[open] = false; // public methods - - this.toggle = function () { - if (hasClass(parent, showClass) && element[open]) { - hide(); - } else { - show(); - } - }; // init - - - if (!(stringDropdown in element)) { - // prevent adding event handlers twice - !tabindex in menu && menu[setAttribute](tabindex, '0'); // Fix onblur on Chrome | Safari - - on(element, clickEvent, clickHandler); - } - - element[stringDropdown] = self; - }; // DROPDOWN DATA API - // ================= - - - supports[push]([stringDropdown, Dropdown, '[' + dataToggle + '="dropdown"]']); - /* Native Javascript for Bootstrap 4 | Modal - -------------------------------------------*/ - // MODAL DEFINITION - // =============== - - var Modal = function (element, options) { - // element can be the modal/triggering button - // the modal (both JavaScript / DATA API init) / triggering button element (DATA API) - element = queryElement(element); // strings - - var component = 'modal', - staticString = 'static', - modalTrigger = 'modalTrigger', - paddingRight = 'paddingRight', - modalBackdropString = 'modal-backdrop', - isAnimating = 'isAnimating', - // determine modal, triggering element - btnCheck = element[getAttribute](dataTarget) || element[getAttribute]('href'), - checkModal = queryElement(btnCheck), - modal = hasClass(element, component) ? element : checkModal; - - if (hasClass(element, component)) { - element = null; - } // modal is now independent of it's triggering element - - - if (!modal) { - return; - } // invalidate - // set options - - - options = options || {}; - this[keyboard] = options[keyboard] === false || modal[getAttribute](dataKeyboard) === 'false' ? false : true; - this[backdrop] = options[backdrop] === staticString || modal[getAttribute](databackdrop) === staticString ? staticString : true; - this[backdrop] = options[backdrop] === false || modal[getAttribute](databackdrop) === 'false' ? false : this[backdrop]; - this[animation] = hasClass(modal, 'fade') ? true : false; - this[content] = options[content]; // JavaScript only - // set an initial state of the modal - - modal[isAnimating] = false; // bind, constants, event targets and other vars - - var self = this, - relatedTarget = null, - bodyIsOverflowing, - scrollBarWidth, - overlay, - overlayDelay, - modalTimer, - // also find fixed-top / fixed-bottom items - fixedItems = getElementsByClassName(HTML, fixedTop).concat(getElementsByClassName(HTML, fixedBottom)), - // private methods - getWindowWidth = function () { - var htmlRect = HTML[getBoundingClientRect](); - return globalObject[innerWidth] || htmlRect[right] - Math.abs(htmlRect[left]); - }, - setScrollbar = function () { - var bodyStyle = globalObject[getComputedStyle](DOC[body]), - bodyPad = parseInt(bodyStyle[paddingRight], 10), - itemPad; - - if (bodyIsOverflowing) { - DOC[body][style][paddingRight] = bodyPad + scrollBarWidth + 'px'; - modal[style][paddingRight] = scrollBarWidth + 'px'; - - if (fixedItems[length]) { - for (var i = 0; i < fixedItems[length]; i++) { - itemPad = globalObject[getComputedStyle](fixedItems[i])[paddingRight]; - fixedItems[i][style][paddingRight] = parseInt(itemPad) + scrollBarWidth + 'px'; - } - } - } - }, - resetScrollbar = function () { - DOC[body][style][paddingRight] = ''; - modal[style][paddingRight] = ''; - - if (fixedItems[length]) { - for (var i = 0; i < fixedItems[length]; i++) { - fixedItems[i][style][paddingRight] = ''; - } - } - }, - measureScrollbar = function () { - // thx walsh - var scrollDiv = DOC[createElement]('div'), - widthValue; - scrollDiv.className = component + '-scrollbar-measure'; // this is here to stay - - DOC[body][appendChild](scrollDiv); - widthValue = scrollDiv[offsetWidth] - scrollDiv[clientWidth]; - DOC[body].removeChild(scrollDiv); - return widthValue; - }, - checkScrollbar = function () { - bodyIsOverflowing = DOC[body][clientWidth] < getWindowWidth(); - scrollBarWidth = measureScrollbar(); - }, - createOverlay = function () { - var newOverlay = DOC[createElement]('div'); - overlay = queryElement('.' + modalBackdropString); - - if (overlay === null) { - newOverlay[setAttribute]('class', modalBackdropString + (self[animation] ? ' fade' : '')); - overlay = newOverlay; - DOC[body][appendChild](overlay); - } - - modalOverlay = 1; - }, - removeOverlay = function () { - overlay = queryElement('.' + modalBackdropString); - - if (overlay && overlay !== null && typeof overlay === 'object') { - modalOverlay = 0; - DOC[body].removeChild(overlay); - overlay = null; - } - }, - // triggers - triggerShow = function () { - setFocus(modal); - modal[isAnimating] = false; - bootstrapCustomEvent.call(modal, shownEvent, component, relatedTarget); - on(globalObject, resizeEvent, self.update, passiveHandler); - on(modal, clickEvent, dismissHandler); - on(DOC, keydownEvent, keyHandler); - }, - triggerHide = function () { - modal[style].display = ''; - element && setFocus(element); - bootstrapCustomEvent.call(modal, hiddenEvent, component); - - (function () { - if (!getElementsByClassName(DOC, component + ' ' + showClass)[0]) { - resetScrollbar(); - removeClass(DOC[body], component + '-open'); - overlay && hasClass(overlay, 'fade') ? (removeClass(overlay, showClass), emulateTransitionEnd(overlay, removeOverlay)) : removeOverlay(); - off(globalObject, resizeEvent, self.update, passiveHandler); - off(modal, clickEvent, dismissHandler); - off(DOC, keydownEvent, keyHandler); - } - })(); - - modal[isAnimating] = false; - }, - // handlers - clickHandler = function (e) { - if (modal[isAnimating]) return; - var clickTarget = e[target]; - clickTarget = clickTarget[hasAttribute](dataTarget) || clickTarget[hasAttribute]('href') ? clickTarget : clickTarget[parentNode]; - - if (clickTarget === element && !hasClass(modal, showClass)) { - modal[modalTrigger] = element; - relatedTarget = element; - self.show(); - e[preventDefault](); - } - }, - keyHandler = function (e) { - if (modal[isAnimating]) return; - - if (self[keyboard] && e.which == 27 && hasClass(modal, showClass)) { - self.hide(); - } - }, - dismissHandler = function (e) { - if (modal[isAnimating]) return; - var clickTarget = e[target]; - - if (hasClass(modal, showClass) && (clickTarget[parentNode][getAttribute](dataDismiss) === component || clickTarget[getAttribute](dataDismiss) === component || clickTarget === modal && self[backdrop] !== staticString)) { - self.hide(); - relatedTarget = null; - e[preventDefault](); - } - }; // public methods - - - this.toggle = function () { - if (hasClass(modal, showClass)) { - this.hide(); - } else { - this.show(); - } - }; - - this.show = function () { - if (hasClass(modal, showClass) || modal[isAnimating]) { - return; - } - - clearTimeout(modalTimer); - modalTimer = setTimeout(function () { - modal[isAnimating] = true; - bootstrapCustomEvent.call(modal, showEvent, component, relatedTarget); // we elegantly hide any opened modal - - var currentOpen = getElementsByClassName(DOC, component + ' ' + showClass)[0]; - - if (currentOpen && currentOpen !== modal) { - modalTrigger in currentOpen && currentOpen[modalTrigger][stringModal].hide(); - stringModal in currentOpen && currentOpen[stringModal].hide(); - } - - if (self[backdrop]) { - !modalOverlay && !overlay && createOverlay(); - } - - if (overlay && !hasClass(overlay, showClass)) { - overlay[offsetWidth]; // force reflow to enable trasition - - overlayDelay = getTransitionDurationFromElement(overlay); - addClass(overlay, showClass); - } - - setTimeout(function () { - modal[style].display = 'block'; - checkScrollbar(); - setScrollbar(); - addClass(DOC[body], component + '-open'); - addClass(modal, showClass); - modal[setAttribute](ariaHidden, false); - hasClass(modal, 'fade') ? emulateTransitionEnd(modal, triggerShow) : triggerShow(); - }, supportTransitions && overlay && overlayDelay ? overlayDelay : 1); - }, 1); - }; - - this.hide = function () { - if (modal[isAnimating] || !hasClass(modal, showClass)) { - return; - } - - clearTimeout(modalTimer); - modalTimer = setTimeout(function () { - modal[isAnimating] = true; - bootstrapCustomEvent.call(modal, hideEvent, component); - overlay = queryElement('.' + modalBackdropString); - overlayDelay = overlay && getTransitionDurationFromElement(overlay); - removeClass(modal, showClass); - modal[setAttribute](ariaHidden, true); - setTimeout(function () { - hasClass(modal, 'fade') ? emulateTransitionEnd(modal, triggerHide) : triggerHide(); - }, supportTransitions && overlay && overlayDelay ? overlayDelay : 2); - }, 2); - }; - - this.setContent = function (content) { - queryElement('.' + component + '-content', modal)[innerHTML] = content; - }; - - this.update = function () { - if (hasClass(modal, showClass)) { - checkScrollbar(); - setScrollbar(); - } - }; // init - // prevent adding event handlers over and over - // modal is independent of a triggering element - - - if (!!element && !(stringModal in element)) { - on(element, clickEvent, clickHandler); - } - - if (!!self[content]) { - self.setContent(self[content]); - } - - if (element) { - element[stringModal] = self; - modal[modalTrigger] = element; - } else { - modal[stringModal] = self; - } - }; // DATA API - - - supports[push]([stringModal, Modal, '[' + dataToggle + '="modal"]']); - /* Native Javascript for Bootstrap 4 | Popover - ----------------------------------------------*/ - // POPOVER DEFINITION - // ================== - - var Popover = function (element, options) { - // initialization element - element = queryElement(element); // set options - - options = options || {}; // DATA API - - var triggerData = element[getAttribute](dataTrigger), - // click / hover / focus - animationData = element[getAttribute](dataAnimation), - // true / false - placementData = element[getAttribute](dataPlacement), - dismissibleData = element[getAttribute](dataDismissible), - delayData = element[getAttribute](dataDelay), - containerData = element[getAttribute](dataContainer), - // internal strings - component = 'popover', - template = 'template', - trigger = 'trigger', - classString = 'class', - div = 'div', - fade = 'fade', - dataContent = 'data-content', - dismissible = 'dismissible', - closeBtn = '', - // check container - containerElement = queryElement(options[container]), - containerDataElement = queryElement(containerData), - // maybe the element is inside a modal - modal = getClosest(element, '.modal'), - // maybe the element is inside a fixed navbar - navbarFixedTop = getClosest(element, '.' + fixedTop), - navbarFixedBottom = getClosest(element, '.' + fixedBottom); // set instance options - - this[template] = options[template] ? options[template] : null; // JavaScript only - - this[trigger] = options[trigger] ? options[trigger] : triggerData || hoverEvent; - this[animation] = options[animation] && options[animation] !== fade ? options[animation] : animationData || fade; - this[placement] = options[placement] ? options[placement] : placementData || top; - this[delay] = parseInt(options[delay] || delayData) || 200; - this[dismissible] = options[dismissible] || dismissibleData === 'true' ? true : false; - this[container] = containerElement ? containerElement : containerDataElement ? containerDataElement : navbarFixedTop ? navbarFixedTop : navbarFixedBottom ? navbarFixedBottom : modal ? modal : DOC[body]; // bind, content - - var self = this, - titleString = options.title || element[getAttribute](dataTitle) || null, - contentString = options.content || element[getAttribute](dataContent) || null; - if (!contentString && !this[template]) return; // invalidate - // constants, vars - - var popover = null, - timer = 0, - placementSetting = this[placement], - // handlers - dismissibleHandler = function (e) { - if (popover !== null && e[target] === queryElement('.close', popover)) { - self.hide(); - } - }, - // private methods - removePopover = function () { - self[container].removeChild(popover); - timer = null; - popover = null; - }, - createPopover = function () { - titleString = options.title || element[getAttribute](dataTitle); - contentString = options.content || element[getAttribute](dataContent); // fixing https://github.com/thednp/bootstrap.native/issues/233 - - contentString = !!contentString ? contentString.trim() : null; - popover = DOC[createElement](div); // popover arrow - - var popoverArrow = DOC[createElement](div); - popoverArrow[setAttribute](classString, 'arrow'); - popover[appendChild](popoverArrow); - - if (contentString !== null && self[template] === null) { - //create the popover from data attributes - popover[setAttribute]('role', 'tooltip'); - - if (titleString !== null) { - var popoverTitle = DOC[createElement]('h3'); - popoverTitle[setAttribute](classString, component + '-header'); - popoverTitle[innerHTML] = self[dismissible] ? titleString + closeBtn : titleString; - popover[appendChild](popoverTitle); - } //set popover content - - - var popoverContent = DOC[createElement](div); - popoverContent[setAttribute](classString, component + '-body'); - popoverContent[innerHTML] = self[dismissible] && titleString === null ? contentString + closeBtn : contentString; - popover[appendChild](popoverContent); - } else { - // or create the popover from template - var popoverTemplate = DOC[createElement](div); - self[template] = self[template].trim(); - popoverTemplate[innerHTML] = self[template]; - popover[innerHTML] = popoverTemplate.firstChild[innerHTML]; - } //append to the container - - - self[container][appendChild](popover); - popover[style].display = 'block'; - popover[setAttribute](classString, component + ' bs-' + component + '-' + placementSetting + ' ' + self[animation]); - }, - showPopover = function () { - !hasClass(popover, showClass) && addClass(popover, showClass); - }, - updatePopover = function () { - styleTip(element, popover, placementSetting, self[container]); - }, - // event toggle - dismissHandlerToggle = function (type) { - if (clickEvent == self[trigger] || 'focus' == self[trigger]) { - !self[dismissible] && type(element, 'blur', self.hide); - } - - self[dismissible] && type(DOC, clickEvent, dismissibleHandler); - type(globalObject, resizeEvent, self.hide, passiveHandler); - }, - // triggers - showTrigger = function () { - dismissHandlerToggle(on); - bootstrapCustomEvent.call(element, shownEvent, component); - }, - hideTrigger = function () { - dismissHandlerToggle(off); - removePopover(); - bootstrapCustomEvent.call(element, hiddenEvent, component); - }; // public methods / handlers - - - this.toggle = function () { - if (popover === null) { - self.show(); - } else { - self.hide(); - } - }; - - this.show = function () { - clearTimeout(timer); - timer = setTimeout(function () { - if (popover === null) { - placementSetting = self[placement]; // we reset placement in all cases - - createPopover(); - updatePopover(); - showPopover(); - bootstrapCustomEvent.call(element, showEvent, component); - !!self[animation] ? emulateTransitionEnd(popover, showTrigger) : showTrigger(); - } - }, 20); - }; - - this.hide = function () { - clearTimeout(timer); - timer = setTimeout(function () { - if (popover && popover !== null && hasClass(popover, showClass)) { - bootstrapCustomEvent.call(element, hideEvent, component); - removeClass(popover, showClass); - !!self[animation] ? emulateTransitionEnd(popover, hideTrigger) : hideTrigger(); - } - }, self[delay]); - }; // init - - - if (!(stringPopover in element)) { - // prevent adding event handlers twice - if (self[trigger] === hoverEvent) { - on(element, mouseHover[0], self.show); - - if (!self[dismissible]) { - on(element, mouseHover[1], self.hide); - } - } else if (clickEvent == self[trigger] || 'focus' == self[trigger]) { - on(element, self[trigger], self.toggle); - } - } - - element[stringPopover] = self; - }; // POPOVER DATA API - // ================ - - - supports[push]([stringPopover, Popover, '[' + dataToggle + '="popover"]']); - /* Native Javascript for Bootstrap 4 | Tab - -----------------------------------------*/ - // TAB DEFINITION - // ============== - - var Tab = function (element, options) { - // initialization element - element = queryElement(element); // DATA API - - var heightData = element[getAttribute](dataHeight), - // strings - component = 'tab', - height = 'height', - float = 'float', - isAnimating = 'isAnimating'; // set options - - options = options || {}; - this[height] = supportTransitions ? options[height] || heightData === 'true' : false; // bind, event targets - - var self = this, - next, - tabs = getClosest(element, '.nav'), - tabsContentContainer = false, - dropdown = tabs && queryElement('.dropdown-toggle', tabs), - activeTab, - activeContent, - nextContent, - containerHeight, - equalContents, - nextHeight, - // trigger - triggerEnd = function () { - tabsContentContainer[style][height] = ''; - removeClass(tabsContentContainer, collapsing); - tabs[isAnimating] = false; - }, - triggerShow = function () { - if (tabsContentContainer) { - // height animation - if (equalContents) { - triggerEnd(); - } else { - setTimeout(function () { - // enables height animation - tabsContentContainer[style][height] = nextHeight + 'px'; // height animation - - tabsContentContainer[offsetWidth]; - emulateTransitionEnd(tabsContentContainer, triggerEnd); - }, 50); - } - } else { - tabs[isAnimating] = false; - } - - bootstrapCustomEvent.call(next, shownEvent, component, activeTab); - }, - triggerHide = function () { - if (tabsContentContainer) { - activeContent[style][float] = left; - nextContent[style][float] = left; - containerHeight = activeContent[scrollHeight]; - } - - addClass(nextContent, active); - bootstrapCustomEvent.call(next, showEvent, component, activeTab); - removeClass(activeContent, active); - bootstrapCustomEvent.call(activeTab, hiddenEvent, component, next); - - if (tabsContentContainer) { - nextHeight = nextContent[scrollHeight]; - equalContents = nextHeight === containerHeight; - addClass(tabsContentContainer, collapsing); - tabsContentContainer[style][height] = containerHeight + 'px'; // height animation - - tabsContentContainer[offsetHeight]; - activeContent[style][float] = ''; - nextContent[style][float] = ''; - } - - if (hasClass(nextContent, 'fade')) { - setTimeout(function () { - addClass(nextContent, showClass); - emulateTransitionEnd(nextContent, triggerShow); - }, 20); - } else { - triggerShow(); - } - }; - - if (!tabs) return; // invalidate - // set default animation state - - tabs[isAnimating] = false; // private methods - - var getActiveTab = function () { - var activeTabs = getElementsByClassName(tabs, active), - activeTab; - - if (activeTabs[length] === 1 && !hasClass(activeTabs[0][parentNode], 'dropdown')) { - activeTab = activeTabs[0]; - } else if (activeTabs[length] > 1) { - activeTab = activeTabs[activeTabs[length] - 1]; - } - - return activeTab; - }, - getActiveContent = function () { - return queryElement(getActiveTab()[getAttribute]('href')); - }, - // handler - clickHandler = function (e) { - e[preventDefault](); - next = e[currentTarget]; - !tabs[isAnimating] && !hasClass(next, active) && self.show(); - }; // public method - - - this.show = function () { - // the tab we clicked is now the next tab - next = next || element; - nextContent = queryElement(next[getAttribute]('href')); //this is the actual object, the next tab content to activate - - activeTab = getActiveTab(); - activeContent = getActiveContent(); - tabs[isAnimating] = true; - removeClass(activeTab, active); - activeTab[setAttribute](ariaSelected, 'false'); - addClass(next, active); - next[setAttribute](ariaSelected, 'true'); - - if (dropdown) { - if (!hasClass(element[parentNode], 'dropdown-menu')) { - if (hasClass(dropdown, active)) removeClass(dropdown, active); - } else { - if (!hasClass(dropdown, active)) addClass(dropdown, active); - } - } - - bootstrapCustomEvent.call(activeTab, hideEvent, component, next); - - if (hasClass(activeContent, 'fade')) { - removeClass(activeContent, showClass); - emulateTransitionEnd(activeContent, triggerHide); - } else { - triggerHide(); - } - }; // init - - - if (!(stringTab in element)) { - // prevent adding event handlers twice - on(element, clickEvent, clickHandler); - } - - if (self[height]) { - tabsContentContainer = getActiveContent()[parentNode]; - } - - element[stringTab] = self; - }; // TAB DATA API - // ============ - - - supports[push]([stringTab, Tab, '[' + dataToggle + '="tab"]']); - /* Native Javascript for Bootstrap | Initialize Data API - --------------------------------------------------------*/ - - var initializeDataAPI = function (constructor, collection) { - for (var i = 0, l = collection[length]; i < l; i++) { - new constructor(collection[i]); - } - }, - initCallback = BSN.initCallback = function (lookUp) { - lookUp = lookUp || DOC; - - for (var i = 0, l = supports[length]; i < l; i++) { - initializeDataAPI(supports[i][1], lookUp[querySelectorAll](supports[i][2])); - } - }; // bulk initialize all components - - - DOC[body] ? initCallback() : on(DOC, 'DOMContentLoaded', function () { - initCallback(); - }); - return { - Alert: Alert, - Button: Button, - Collapse: Collapse, - Dropdown: Dropdown, - Modal: Modal, - Popover: Popover, - Tab: Tab - }; -}); - -/***/ }), - -/***/ 5820: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -__webpack_require__(964); - -var $Object = __webpack_require__(7913).Object; - -module.exports = function defineProperty(it, key, desc) { - return $Object.defineProperty(it, key, desc); -}; - -/***/ }), - -/***/ 3248: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -__webpack_require__(4180); - -module.exports = __webpack_require__(7913).Object.keys; - -/***/ }), - -/***/ 9830: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -__webpack_require__(6542); - -__webpack_require__(4815); - -__webpack_require__(8160); - -__webpack_require__(8314); - -__webpack_require__(8245); - -__webpack_require__(5953); - -module.exports = __webpack_require__(7913).Promise; - -/***/ }), - -/***/ 472: -/***/ ((module) => { - -module.exports = function (it) { - if (typeof it != 'function') throw TypeError(it + ' is not a function!'); - return it; -}; - -/***/ }), - -/***/ 5057: -/***/ ((module) => { - -module.exports = function () { - /* empty */ -}; - -/***/ }), - -/***/ 9945: -/***/ ((module) => { - -module.exports = function (it, Constructor, name, forbiddenField) { - if (!(it instanceof Constructor) || forbiddenField !== undefined && forbiddenField in it) { - throw TypeError(name + ': incorrect invocation!'); - } - - return it; -}; - -/***/ }), - -/***/ 7237: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var isObject = __webpack_require__(9900); - -module.exports = function (it) { - if (!isObject(it)) throw TypeError(it + ' is not an object!'); - return it; -}; - -/***/ }), - -/***/ 7097: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// false -> Array#indexOf -// true -> Array#includes -var toIObject = __webpack_require__(6591); - -var toLength = __webpack_require__(1872); - -var toAbsoluteIndex = __webpack_require__(8367); - -module.exports = function (IS_INCLUDES) { - return function ($this, el, fromIndex) { - var O = toIObject($this); - var length = toLength(O.length); - var index = toAbsoluteIndex(fromIndex, length); - var value; // Array#includes uses SameValueZero equality algorithm - // eslint-disable-next-line no-self-compare - - if (IS_INCLUDES && el != el) while (length > index) { - value = O[index++]; // eslint-disable-next-line no-self-compare - - if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not - } else for (; length > index; index++) if (IS_INCLUDES || index in O) { - if (O[index] === el) return IS_INCLUDES || index || 0; - } - return !IS_INCLUDES && -1; - }; -}; - -/***/ }), - -/***/ 8874: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// getting tag from 19.1.3.6 Object.prototype.toString() -var cof = __webpack_require__(4606); - -var TAG = __webpack_require__(9506)('toStringTag'); // ES3 wrong here - - -var ARG = cof(function () { - return arguments; -}()) == 'Arguments'; // fallback for IE11 Script Access Denied error - -var tryGet = function (it, key) { - try { - return it[key]; - } catch (e) { - /* empty */ - } -}; - -module.exports = function (it) { - var O, T, B; - return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case - : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T // builtinTag case - : ARG ? cof(O) // ES3 arguments fallback - : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; -}; - -/***/ }), - -/***/ 4606: -/***/ ((module) => { - -var toString = {}.toString; - -module.exports = function (it) { - return toString.call(it).slice(8, -1); -}; - -/***/ }), - -/***/ 7913: -/***/ ((module) => { - -var core = module.exports = { - version: '2.6.12' -}; -if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef - -/***/ }), - -/***/ 8773: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// optional / simple context binding -var aFunction = __webpack_require__(472); - -module.exports = function (fn, that, length) { - aFunction(fn); - if (that === undefined) return fn; - - switch (length) { - case 1: - return function (a) { - return fn.call(that, a); - }; - - case 2: - return function (a, b) { - return fn.call(that, a, b); - }; - - case 3: - return function (a, b, c) { - return fn.call(that, a, b, c); - }; - } - - return function () - /* ...args */ - { - return fn.apply(that, arguments); - }; -}; - -/***/ }), - -/***/ 1011: -/***/ ((module) => { - -// 7.2.1 RequireObjectCoercible(argument) -module.exports = function (it) { - if (it == undefined) throw TypeError("Can't call method on " + it); - return it; -}; - -/***/ }), - -/***/ 6580: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// Thank's IE8 for his funny defineProperty -module.exports = !__webpack_require__(7287)(function () { - return Object.defineProperty({}, 'a', { - get: function () { - return 7; - } - }).a != 7; -}); - -/***/ }), - -/***/ 6590: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var isObject = __webpack_require__(9900); - -var document = __webpack_require__(5677).document; // typeof document.createElement is 'object' in old IE - - -var is = isObject(document) && isObject(document.createElement); - -module.exports = function (it) { - return is ? document.createElement(it) : {}; -}; - -/***/ }), - -/***/ 4330: -/***/ ((module) => { - -// IE 8- don't enum bug keys -module.exports = 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'.split(','); - -/***/ }), - -/***/ 9749: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var global = __webpack_require__(5677); - -var core = __webpack_require__(7913); - -var ctx = __webpack_require__(8773); - -var hide = __webpack_require__(51); - -var has = __webpack_require__(3945); - -var PROTOTYPE = 'prototype'; - -var $export = function (type, name, source) { - var IS_FORCED = type & $export.F; - var IS_GLOBAL = type & $export.G; - var IS_STATIC = type & $export.S; - var IS_PROTO = type & $export.P; - var IS_BIND = type & $export.B; - var IS_WRAP = type & $export.W; - var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); - var expProto = exports[PROTOTYPE]; - var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; - var key, own, out; - if (IS_GLOBAL) source = name; - - for (key in source) { - // contains in native - own = !IS_FORCED && target && target[key] !== undefined; - if (own && has(exports, key)) continue; // export native or passed - - out = own ? target[key] : source[key]; // prevent global pollution for namespaces - - exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] // bind timers to global for call from export context - : IS_BIND && own ? ctx(out, global) // wrap global constructors for prevent change them in library - : IS_WRAP && target[key] == out ? function (C) { - var F = function (a, b, c) { - if (this instanceof C) { - switch (arguments.length) { - case 0: - return new C(); - - case 1: - return new C(a); - - case 2: - return new C(a, b); - } - - return new C(a, b, c); - } - - return C.apply(this, arguments); - }; - - F[PROTOTYPE] = C[PROTOTYPE]; - return F; // make static versions for prototype methods - }(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% - - if (IS_PROTO) { - (exports.virtual || (exports.virtual = {}))[key] = out; // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% - - if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); - } - } -}; // type bitmap - - -$export.F = 1; // forced - -$export.G = 2; // global - -$export.S = 4; // static - -$export.P = 8; // proto - -$export.B = 16; // bind - -$export.W = 32; // wrap - -$export.U = 64; // safe - -$export.R = 128; // real proto method for `library` - -module.exports = $export; - -/***/ }), - -/***/ 7287: -/***/ ((module) => { - -module.exports = function (exec) { - try { - return !!exec(); - } catch (e) { - return true; - } -}; - -/***/ }), - -/***/ 5614: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var ctx = __webpack_require__(8773); - -var call = __webpack_require__(352); - -var isArrayIter = __webpack_require__(2887); - -var anObject = __webpack_require__(7237); - -var toLength = __webpack_require__(1872); - -var getIterFn = __webpack_require__(7670); - -var BREAK = {}; -var RETURN = {}; - -var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) { - var iterFn = ITERATOR ? function () { - return iterable; - } : getIterFn(iterable); - var f = ctx(fn, that, entries ? 2 : 1); - var index = 0; - var length, step, iterator, result; - if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!'); // fast case for arrays with default iterator - - if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) { - result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); - if (result === BREAK || result === RETURN) return result; - } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) { - result = call(iterator, f, step.value, entries); - if (result === BREAK || result === RETURN) return result; - } -}; - -exports.BREAK = BREAK; -exports.RETURN = RETURN; - -/***/ }), - -/***/ 5677: -/***/ ((module) => { - -// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 -var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self // eslint-disable-next-line no-new-func -: Function('return this')(); -if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef - -/***/ }), - -/***/ 3945: -/***/ ((module) => { - -var hasOwnProperty = {}.hasOwnProperty; - -module.exports = function (it, key) { - return hasOwnProperty.call(it, key); -}; - -/***/ }), - -/***/ 51: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var dP = __webpack_require__(8301); - -var createDesc = __webpack_require__(7269); - -module.exports = __webpack_require__(6580) ? function (object, key, value) { - return dP.f(object, key, createDesc(1, value)); -} : function (object, key, value) { - object[key] = value; - return object; -}; - -/***/ }), - -/***/ 8387: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var document = __webpack_require__(5677).document; - -module.exports = document && document.documentElement; - -/***/ }), - -/***/ 1430: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = !__webpack_require__(6580) && !__webpack_require__(7287)(function () { - return Object.defineProperty(__webpack_require__(6590)('div'), 'a', { - get: function () { - return 7; - } - }).a != 7; -}); - -/***/ }), - -/***/ 2229: -/***/ ((module) => { - -// fast apply, http://jsperf.lnkit.com/fast-apply/5 -module.exports = function (fn, args, that) { - var un = that === undefined; - - switch (args.length) { - case 0: - return un ? fn() : fn.call(that); - - case 1: - return un ? fn(args[0]) : fn.call(that, args[0]); - - case 2: - return un ? fn(args[0], args[1]) : fn.call(that, args[0], args[1]); - - case 3: - return un ? fn(args[0], args[1], args[2]) : fn.call(that, args[0], args[1], args[2]); - - case 4: - return un ? fn(args[0], args[1], args[2], args[3]) : fn.call(that, args[0], args[1], args[2], args[3]); - } - - return fn.apply(that, args); -}; - -/***/ }), - -/***/ 9734: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// fallback for non-array-like ES3 and non-enumerable old V8 strings -var cof = __webpack_require__(4606); // eslint-disable-next-line no-prototype-builtins - - -module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { - return cof(it) == 'String' ? it.split('') : Object(it); -}; - -/***/ }), - -/***/ 2887: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// check on default Array iterator -var Iterators = __webpack_require__(3829); - -var ITERATOR = __webpack_require__(9506)('iterator'); - -var ArrayProto = Array.prototype; - -module.exports = function (it) { - return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); -}; - -/***/ }), - -/***/ 9900: -/***/ ((module) => { - -module.exports = function (it) { - return typeof it === 'object' ? it !== null : typeof it === 'function'; -}; - -/***/ }), - -/***/ 352: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// call something on iterator step with safe closing on error -var anObject = __webpack_require__(7237); - -module.exports = function (iterator, fn, value, entries) { - try { - return entries ? fn(anObject(value)[0], value[1]) : fn(value); // 7.4.6 IteratorClose(iterator, completion) - } catch (e) { - var ret = iterator['return']; - if (ret !== undefined) anObject(ret.call(iterator)); - throw e; - } -}; - -/***/ }), - -/***/ 4419: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -var create = __webpack_require__(8933); - -var descriptor = __webpack_require__(7269); - -var setToStringTag = __webpack_require__(8536); - -var IteratorPrototype = {}; // 25.1.2.1.1 %IteratorPrototype%[@@iterator]() - -__webpack_require__(51)(IteratorPrototype, __webpack_require__(9506)('iterator'), function () { - return this; -}); - -module.exports = function (Constructor, NAME, next) { - Constructor.prototype = create(IteratorPrototype, { - next: descriptor(1, next) - }); - setToStringTag(Constructor, NAME + ' Iterator'); -}; - -/***/ }), - -/***/ 2361: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -var LIBRARY = __webpack_require__(7560); - -var $export = __webpack_require__(9749); - -var redefine = __webpack_require__(836); - -var hide = __webpack_require__(51); - -var Iterators = __webpack_require__(3829); - -var $iterCreate = __webpack_require__(4419); - -var setToStringTag = __webpack_require__(8536); - -var getPrototypeOf = __webpack_require__(2008); - -var ITERATOR = __webpack_require__(9506)('iterator'); - -var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` - -var FF_ITERATOR = '@@iterator'; -var KEYS = 'keys'; -var VALUES = 'values'; - -var returnThis = function () { - return this; -}; - -module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { - $iterCreate(Constructor, NAME, next); - - var getMethod = function (kind) { - if (!BUGGY && kind in proto) return proto[kind]; - - switch (kind) { - case KEYS: - return function keys() { - return new Constructor(this, kind); - }; - - case VALUES: - return function values() { - return new Constructor(this, kind); - }; - } - - return function entries() { - return new Constructor(this, kind); - }; - }; - - var TAG = NAME + ' Iterator'; - var DEF_VALUES = DEFAULT == VALUES; - var VALUES_BUG = false; - var proto = Base.prototype; - var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; - var $default = $native || getMethod(DEFAULT); - var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; - var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; - var methods, key, IteratorPrototype; // Fix native - - if ($anyNative) { - IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); - - if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { - // Set @@toStringTag to native iterators - setToStringTag(IteratorPrototype, TAG, true); // fix for some old engines - - if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis); - } - } // fix Array#{values, @@iterator}.name in V8 / FF - - - if (DEF_VALUES && $native && $native.name !== VALUES) { - VALUES_BUG = true; - - $default = function values() { - return $native.call(this); - }; - } // Define iterator - - - if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { - hide(proto, ITERATOR, $default); - } // Plug for library - - - Iterators[NAME] = $default; - Iterators[TAG] = returnThis; - - if (DEFAULT) { - methods = { - values: DEF_VALUES ? $default : getMethod(VALUES), - keys: IS_SET ? $default : getMethod(KEYS), - entries: $entries - }; - if (FORCED) for (key in methods) { - if (!(key in proto)) redefine(proto, key, methods[key]); - } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); - } - - return methods; -}; - -/***/ }), - -/***/ 3540: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var ITERATOR = __webpack_require__(9506)('iterator'); - -var SAFE_CLOSING = false; - -try { - var riter = [7][ITERATOR](); - - riter['return'] = function () { - SAFE_CLOSING = true; - }; // eslint-disable-next-line no-throw-literal - - - Array.from(riter, function () { - throw 2; - }); -} catch (e) { - /* empty */ -} - -module.exports = function (exec, skipClosing) { - if (!skipClosing && !SAFE_CLOSING) return false; - var safe = false; - - try { - var arr = [7]; - var iter = arr[ITERATOR](); - - iter.next = function () { - return { - done: safe = true - }; - }; - - arr[ITERATOR] = function () { - return iter; - }; - - exec(arr); - } catch (e) { - /* empty */ - } - - return safe; -}; - -/***/ }), - -/***/ 4362: -/***/ ((module) => { - -module.exports = function (done, value) { - return { - value: value, - done: !!done - }; -}; - -/***/ }), - -/***/ 3829: -/***/ ((module) => { - -module.exports = {}; - -/***/ }), - -/***/ 7560: -/***/ ((module) => { - -module.exports = true; - -/***/ }), - -/***/ 7231: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var global = __webpack_require__(5677); - -var macrotask = __webpack_require__(8226).set; - -var Observer = global.MutationObserver || global.WebKitMutationObserver; -var process = global.process; -var Promise = global.Promise; -var isNode = __webpack_require__(4606)(process) == 'process'; - -module.exports = function () { - var head, last, notify; - - var flush = function () { - var parent, fn; - if (isNode && (parent = process.domain)) parent.exit(); - - while (head) { - fn = head.fn; - head = head.next; - - try { - fn(); - } catch (e) { - if (head) notify();else last = undefined; - throw e; - } - } - - last = undefined; - if (parent) parent.enter(); - }; // Node.js - - - if (isNode) { - notify = function () { - process.nextTick(flush); - }; // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339 - - } else if (Observer && !(global.navigator && global.navigator.standalone)) { - var toggle = true; - var node = document.createTextNode(''); - new Observer(flush).observe(node, { - characterData: true - }); // eslint-disable-line no-new - - notify = function () { - node.data = toggle = !toggle; - }; // environments with maybe non-completely correct, but existent Promise - - } else if (Promise && Promise.resolve) { - // Promise.resolve without an argument throws an error in LG WebOS 2 - var promise = Promise.resolve(undefined); - - notify = function () { - promise.then(flush); - }; // for other environments - macrotask based on: - // - setImmediate - // - MessageChannel - // - window.postMessag - // - onreadystatechange - // - setTimeout - - } else { - notify = function () { - // strange IE + webpack dev server bug - use .call(global) - macrotask.call(global, flush); - }; - } - - return function (fn) { - var task = { - fn: fn, - next: undefined - }; - if (last) last.next = task; - - if (!head) { - head = task; - notify(); - } - - last = task; - }; -}; - -/***/ }), - -/***/ 7789: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - // 25.4.1.5 NewPromiseCapability(C) - -var aFunction = __webpack_require__(472); - -function PromiseCapability(C) { - var resolve, reject; - this.promise = new C(function ($$resolve, $$reject) { - if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor'); - resolve = $$resolve; - reject = $$reject; - }); - this.resolve = aFunction(resolve); - this.reject = aFunction(reject); -} - -module.exports.f = function (C) { - return new PromiseCapability(C); -}; - -/***/ }), - -/***/ 8933: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) -var anObject = __webpack_require__(7237); - -var dPs = __webpack_require__(8138); - -var enumBugKeys = __webpack_require__(4330); - -var IE_PROTO = __webpack_require__(4261)('IE_PROTO'); - -var Empty = function () { - /* empty */ -}; - -var PROTOTYPE = 'prototype'; // Create object with fake `null` prototype: use iframe Object with cleared prototype - -var createDict = function () { - // Thrash, waste and sodomy: IE GC bug - var iframe = __webpack_require__(6590)('iframe'); - - var i = enumBugKeys.length; - var lt = '<'; - var gt = '>'; - var iframeDocument; - iframe.style.display = 'none'; - - __webpack_require__(8387).appendChild(iframe); - - iframe.src = 'javascript:'; // eslint-disable-line no-script-url - // createDict = iframe.contentWindow.Object; - // html.removeChild(iframe); - - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); - iframeDocument.close(); - createDict = iframeDocument.F; - - while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; - - return createDict(); -}; - -module.exports = Object.create || function create(O, Properties) { - var result; - - if (O !== null) { - Empty[PROTOTYPE] = anObject(O); - result = new Empty(); - Empty[PROTOTYPE] = null; // add "__proto__" for Object.getPrototypeOf polyfill - - result[IE_PROTO] = O; - } else result = createDict(); - - return Properties === undefined ? result : dPs(result, Properties); -}; - -/***/ }), - -/***/ 8301: -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - -var anObject = __webpack_require__(7237); - -var IE8_DOM_DEFINE = __webpack_require__(1430); - -var toPrimitive = __webpack_require__(3216); - -var dP = Object.defineProperty; -exports.f = __webpack_require__(6580) ? Object.defineProperty : function defineProperty(O, P, Attributes) { - anObject(O); - P = toPrimitive(P, true); - anObject(Attributes); - if (IE8_DOM_DEFINE) try { - return dP(O, P, Attributes); - } catch (e) { - /* empty */ - } - if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); - if ('value' in Attributes) O[P] = Attributes.value; - return O; -}; - -/***/ }), - -/***/ 8138: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var dP = __webpack_require__(8301); - -var anObject = __webpack_require__(7237); - -var getKeys = __webpack_require__(1302); - -module.exports = __webpack_require__(6580) ? Object.defineProperties : function defineProperties(O, Properties) { - anObject(O); - var keys = getKeys(Properties); - var length = keys.length; - var i = 0; - var P; - - while (length > i) dP.f(O, P = keys[i++], Properties[P]); - - return O; -}; - -/***/ }), - -/***/ 2008: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) -var has = __webpack_require__(3945); - -var toObject = __webpack_require__(6581); - -var IE_PROTO = __webpack_require__(4261)('IE_PROTO'); - -var ObjectProto = Object.prototype; - -module.exports = Object.getPrototypeOf || function (O) { - O = toObject(O); - if (has(O, IE_PROTO)) return O[IE_PROTO]; - - if (typeof O.constructor == 'function' && O instanceof O.constructor) { - return O.constructor.prototype; - } - - return O instanceof Object ? ObjectProto : null; -}; - -/***/ }), - -/***/ 9483: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var has = __webpack_require__(3945); - -var toIObject = __webpack_require__(6591); - -var arrayIndexOf = __webpack_require__(7097)(false); - -var IE_PROTO = __webpack_require__(4261)('IE_PROTO'); - -module.exports = function (object, names) { - var O = toIObject(object); - var i = 0; - var result = []; - var key; - - for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); // Don't enum bug & hidden keys - - - while (names.length > i) if (has(O, key = names[i++])) { - ~arrayIndexOf(result, key) || result.push(key); - } - - return result; -}; - -/***/ }), - -/***/ 1302: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// 19.1.2.14 / 15.2.3.14 Object.keys(O) -var $keys = __webpack_require__(9483); - -var enumBugKeys = __webpack_require__(4330); - -module.exports = Object.keys || function keys(O) { - return $keys(O, enumBugKeys); -}; - -/***/ }), - -/***/ 8438: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// most Object methods by ES6 should accept primitives -var $export = __webpack_require__(9749); - -var core = __webpack_require__(7913); - -var fails = __webpack_require__(7287); - -module.exports = function (KEY, exec) { - var fn = (core.Object || {})[KEY] || Object[KEY]; - var exp = {}; - exp[KEY] = exec(fn); - $export($export.S + $export.F * fails(function () { - fn(1); - }), 'Object', exp); -}; - -/***/ }), - -/***/ 5472: -/***/ ((module) => { - -module.exports = function (exec) { - try { - return { - e: false, - v: exec() - }; - } catch (e) { - return { - e: true, - v: e - }; - } -}; - -/***/ }), - -/***/ 3243: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var anObject = __webpack_require__(7237); - -var isObject = __webpack_require__(9900); - -var newPromiseCapability = __webpack_require__(7789); - -module.exports = function (C, x) { - anObject(C); - if (isObject(x) && x.constructor === C) return x; - var promiseCapability = newPromiseCapability.f(C); - var resolve = promiseCapability.resolve; - resolve(x); - return promiseCapability.promise; -}; - -/***/ }), - -/***/ 7269: -/***/ ((module) => { - -module.exports = function (bitmap, value) { - return { - enumerable: !(bitmap & 1), - configurable: !(bitmap & 2), - writable: !(bitmap & 4), - value: value - }; -}; - -/***/ }), - -/***/ 2853: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var hide = __webpack_require__(51); - -module.exports = function (target, src, safe) { - for (var key in src) { - if (safe && target[key]) target[key] = src[key];else hide(target, key, src[key]); - } - - return target; -}; - -/***/ }), - -/***/ 836: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = __webpack_require__(51); - -/***/ }), - -/***/ 5003: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -var global = __webpack_require__(5677); - -var core = __webpack_require__(7913); - -var dP = __webpack_require__(8301); - -var DESCRIPTORS = __webpack_require__(6580); - -var SPECIES = __webpack_require__(9506)('species'); - -module.exports = function (KEY) { - var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; - if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, { - configurable: true, - get: function () { - return this; - } - }); -}; - -/***/ }), - -/***/ 8536: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var def = __webpack_require__(8301).f; - -var has = __webpack_require__(3945); - -var TAG = __webpack_require__(9506)('toStringTag'); - -module.exports = function (it, tag, stat) { - if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { - configurable: true, - value: tag - }); -}; - -/***/ }), - -/***/ 4261: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var shared = __webpack_require__(7626)('keys'); - -var uid = __webpack_require__(1497); - -module.exports = function (key) { - return shared[key] || (shared[key] = uid(key)); -}; - -/***/ }), - -/***/ 7626: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var core = __webpack_require__(7913); - -var global = __webpack_require__(5677); - -var SHARED = '__core-js_shared__'; -var store = global[SHARED] || (global[SHARED] = {}); -(module.exports = function (key, value) { - return store[key] || (store[key] = value !== undefined ? value : {}); -})('versions', []).push({ - version: core.version, - mode: __webpack_require__(7560) ? 'pure' : 'global', - copyright: '© 2020 Denis Pushkarev (zloirock.ru)' -}); - -/***/ }), - -/***/ 6647: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// 7.3.20 SpeciesConstructor(O, defaultConstructor) -var anObject = __webpack_require__(7237); - -var aFunction = __webpack_require__(472); - -var SPECIES = __webpack_require__(9506)('species'); - -module.exports = function (O, D) { - var C = anObject(O).constructor; - var S; - return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); -}; - -/***/ }), - -/***/ 4757: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var toInteger = __webpack_require__(1517); - -var defined = __webpack_require__(1011); // true -> String#at -// false -> String#codePointAt - - -module.exports = function (TO_STRING) { - return function (that, pos) { - var s = String(defined(that)); - var i = toInteger(pos); - var l = s.length; - var a, b; - if (i < 0 || i >= l) return TO_STRING ? '' : undefined; - a = s.charCodeAt(i); - return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; - }; -}; - -/***/ }), - -/***/ 8226: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var ctx = __webpack_require__(8773); - -var invoke = __webpack_require__(2229); - -var html = __webpack_require__(8387); - -var cel = __webpack_require__(6590); - -var global = __webpack_require__(5677); - -var process = global.process; -var setTask = global.setImmediate; -var clearTask = global.clearImmediate; -var MessageChannel = global.MessageChannel; -var Dispatch = global.Dispatch; -var counter = 0; -var queue = {}; -var ONREADYSTATECHANGE = 'onreadystatechange'; -var defer, channel, port; - -var run = function () { - var id = +this; // eslint-disable-next-line no-prototype-builtins - - if (queue.hasOwnProperty(id)) { - var fn = queue[id]; - delete queue[id]; - fn(); - } -}; - -var listener = function (event) { - run.call(event.data); -}; // Node.js 0.9+ & IE10+ has setImmediate, otherwise: - - -if (!setTask || !clearTask) { - setTask = function setImmediate(fn) { - var args = []; - var i = 1; - - while (arguments.length > i) args.push(arguments[i++]); - - queue[++counter] = function () { - // eslint-disable-next-line no-new-func - invoke(typeof fn == 'function' ? fn : Function(fn), args); - }; - - defer(counter); - return counter; - }; - - clearTask = function clearImmediate(id) { - delete queue[id]; - }; // Node.js 0.8- - - - if (__webpack_require__(4606)(process) == 'process') { - defer = function (id) { - process.nextTick(ctx(run, id, 1)); - }; // Sphere (JS game engine) Dispatch API - - } else if (Dispatch && Dispatch.now) { - defer = function (id) { - Dispatch.now(ctx(run, id, 1)); - }; // Browsers with MessageChannel, includes WebWorkers - - } else if (MessageChannel) { - channel = new MessageChannel(); - port = channel.port2; - channel.port1.onmessage = listener; - defer = ctx(port.postMessage, port, 1); // Browsers with postMessage, skip WebWorkers - // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' - } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) { - defer = function (id) { - global.postMessage(id + '', '*'); - }; - - global.addEventListener('message', listener, false); // IE8- - } else if (ONREADYSTATECHANGE in cel('script')) { - defer = function (id) { - html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () { - html.removeChild(this); - run.call(id); - }; - }; // Rest old browsers - - } else { - defer = function (id) { - setTimeout(ctx(run, id, 1), 0); - }; - } -} - -module.exports = { - set: setTask, - clear: clearTask -}; - -/***/ }), - -/***/ 8367: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var toInteger = __webpack_require__(1517); - -var max = Math.max; -var min = Math.min; - -module.exports = function (index, length) { - index = toInteger(index); - return index < 0 ? max(index + length, 0) : min(index, length); -}; - -/***/ }), - -/***/ 1517: -/***/ ((module) => { - -// 7.1.4 ToInteger -var ceil = Math.ceil; -var floor = Math.floor; - -module.exports = function (it) { - return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); -}; - -/***/ }), - -/***/ 6591: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// to indexed object, toObject with fallback for non-array-like ES3 strings -var IObject = __webpack_require__(9734); - -var defined = __webpack_require__(1011); - -module.exports = function (it) { - return IObject(defined(it)); -}; - -/***/ }), - -/***/ 1872: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// 7.1.15 ToLength -var toInteger = __webpack_require__(1517); - -var min = Math.min; - -module.exports = function (it) { - return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 -}; - -/***/ }), - -/***/ 6581: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// 7.1.13 ToObject(argument) -var defined = __webpack_require__(1011); - -module.exports = function (it) { - return Object(defined(it)); -}; - -/***/ }), - -/***/ 3216: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -// 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(9900); // instead of the ES6 spec version, we didn't implement @@toPrimitive case -// and the second argument - flag - preferred type is a string - - -module.exports = function (it, S) { - if (!isObject(it)) return it; - var fn, val; - if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; - if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; - if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; - throw TypeError("Can't convert object to primitive value"); -}; - -/***/ }), - -/***/ 1497: -/***/ ((module) => { - -var id = 0; -var px = Math.random(); - -module.exports = function (key) { - return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); -}; - -/***/ }), - -/***/ 8877: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var global = __webpack_require__(5677); - -var navigator = global.navigator; -module.exports = navigator && navigator.userAgent || ''; - -/***/ }), - -/***/ 9506: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var store = __webpack_require__(7626)('wks'); - -var uid = __webpack_require__(1497); - -var Symbol = __webpack_require__(5677).Symbol; - -var USE_SYMBOL = typeof Symbol == 'function'; - -var $exports = module.exports = function (name) { - return store[name] || (store[name] = USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); -}; - -$exports.store = store; - -/***/ }), - -/***/ 7670: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var classof = __webpack_require__(8874); - -var ITERATOR = __webpack_require__(9506)('iterator'); - -var Iterators = __webpack_require__(3829); - -module.exports = __webpack_require__(7913).getIteratorMethod = function (it) { - if (it != undefined) return it[ITERATOR] || it['@@iterator'] || Iterators[classof(it)]; -}; - -/***/ }), - -/***/ 66: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -var addToUnscopables = __webpack_require__(5057); - -var step = __webpack_require__(4362); - -var Iterators = __webpack_require__(3829); - -var toIObject = __webpack_require__(6591); // 22.1.3.4 Array.prototype.entries() -// 22.1.3.13 Array.prototype.keys() -// 22.1.3.29 Array.prototype.values() -// 22.1.3.30 Array.prototype[@@iterator]() - - -module.exports = __webpack_require__(2361)(Array, 'Array', function (iterated, kind) { - this._t = toIObject(iterated); // target - - this._i = 0; // next index - - this._k = kind; // kind - // 22.1.5.2.1 %ArrayIteratorPrototype%.next() -}, function () { - var O = this._t; - var kind = this._k; - var index = this._i++; - - if (!O || index >= O.length) { - this._t = undefined; - return step(1); - } - - if (kind == 'keys') return step(0, index); - if (kind == 'values') return step(0, O[index]); - return step(0, [index, O[index]]); -}, 'values'); // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) - -Iterators.Arguments = Iterators.Array; -addToUnscopables('keys'); -addToUnscopables('values'); -addToUnscopables('entries'); - -/***/ }), - -/***/ 964: -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - -var $export = __webpack_require__(9749); // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes) - - -$export($export.S + $export.F * !__webpack_require__(6580), 'Object', { - defineProperty: __webpack_require__(8301).f -}); - -/***/ }), - -/***/ 4180: -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - -// 19.1.2.14 Object.keys(O) -var toObject = __webpack_require__(6581); - -var $keys = __webpack_require__(1302); - -__webpack_require__(8438)('keys', function () { - return function keys(it) { - return $keys(toObject(it)); - }; -}); - -/***/ }), - -/***/ 6542: -/***/ (() => { - - - -/***/ }), - -/***/ 8314: -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -var LIBRARY = __webpack_require__(7560); - -var global = __webpack_require__(5677); - -var ctx = __webpack_require__(8773); - -var classof = __webpack_require__(8874); - -var $export = __webpack_require__(9749); - -var isObject = __webpack_require__(9900); - -var aFunction = __webpack_require__(472); - -var anInstance = __webpack_require__(9945); - -var forOf = __webpack_require__(5614); - -var speciesConstructor = __webpack_require__(6647); - -var task = __webpack_require__(8226).set; - -var microtask = __webpack_require__(7231)(); - -var newPromiseCapabilityModule = __webpack_require__(7789); - -var perform = __webpack_require__(5472); - -var userAgent = __webpack_require__(8877); - -var promiseResolve = __webpack_require__(3243); - -var PROMISE = 'Promise'; -var TypeError = global.TypeError; -var process = global.process; -var versions = process && process.versions; -var v8 = versions && versions.v8 || ''; -var $Promise = global[PROMISE]; -var isNode = classof(process) == 'process'; - -var empty = function () { - /* empty */ -}; - -var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; -var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f; -var USE_NATIVE = !!function () { - try { - // correct subclassing with @@species support - var promise = $Promise.resolve(1); - - var FakePromise = (promise.constructor = {})[__webpack_require__(9506)('species')] = function (exec) { - exec(empty, empty); - }; // unhandled rejections tracking support, NodeJS Promise without it fails @@species test - - - return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables - // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 - // we can't detect it synchronously, so just check versions - && v8.indexOf('6.6') !== 0 && userAgent.indexOf('Chrome/66') === -1; - } catch (e) { - /* empty */ - } -}(); // helpers - -var isThenable = function (it) { - var then; - return isObject(it) && typeof (then = it.then) == 'function' ? then : false; -}; - -var notify = function (promise, isReject) { - if (promise._n) return; - promise._n = true; - var chain = promise._c; - microtask(function () { - var value = promise._v; - var ok = promise._s == 1; - var i = 0; - - var run = function (reaction) { - var handler = ok ? reaction.ok : reaction.fail; - var resolve = reaction.resolve; - var reject = reaction.reject; - var domain = reaction.domain; - var result, then, exited; - - try { - if (handler) { - if (!ok) { - if (promise._h == 2) onHandleUnhandled(promise); - promise._h = 1; - } - - if (handler === true) result = value;else { - if (domain) domain.enter(); - result = handler(value); // may throw - - if (domain) { - domain.exit(); - exited = true; - } - } - - if (result === reaction.promise) { - reject(TypeError('Promise-chain cycle')); - } else if (then = isThenable(result)) { - then.call(result, resolve, reject); - } else resolve(result); - } else reject(value); - } catch (e) { - if (domain && !exited) domain.exit(); - reject(e); - } - }; - - while (chain.length > i) run(chain[i++]); // variable length - can't use forEach - - - promise._c = []; - promise._n = false; - if (isReject && !promise._h) onUnhandled(promise); - }); -}; - -var onUnhandled = function (promise) { - task.call(global, function () { - var value = promise._v; - var unhandled = isUnhandled(promise); - var result, handler, console; - - if (unhandled) { - result = perform(function () { - if (isNode) { - process.emit('unhandledRejection', value, promise); - } else if (handler = global.onunhandledrejection) { - handler({ - promise: promise, - reason: value - }); - } else if ((console = global.console) && console.error) { - console.error('Unhandled promise rejection', value); - } - }); // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should - - promise._h = isNode || isUnhandled(promise) ? 2 : 1; - } - - promise._a = undefined; - if (unhandled && result.e) throw result.v; - }); -}; - -var isUnhandled = function (promise) { - return promise._h !== 1 && (promise._a || promise._c).length === 0; -}; - -var onHandleUnhandled = function (promise) { - task.call(global, function () { - var handler; - - if (isNode) { - process.emit('rejectionHandled', promise); - } else if (handler = global.onrejectionhandled) { - handler({ - promise: promise, - reason: promise._v - }); - } - }); -}; - -var $reject = function (value) { - var promise = this; - if (promise._d) return; - promise._d = true; - promise = promise._w || promise; // unwrap - - promise._v = value; - promise._s = 2; - if (!promise._a) promise._a = promise._c.slice(); - notify(promise, true); -}; - -var $resolve = function (value) { - var promise = this; - var then; - if (promise._d) return; - promise._d = true; - promise = promise._w || promise; // unwrap - - try { - if (promise === value) throw TypeError("Promise can't be resolved itself"); - - if (then = isThenable(value)) { - microtask(function () { - var wrapper = { - _w: promise, - _d: false - }; // wrap - - try { - then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); - } catch (e) { - $reject.call(wrapper, e); - } - }); - } else { - promise._v = value; - promise._s = 1; - notify(promise, false); - } - } catch (e) { - $reject.call({ - _w: promise, - _d: false - }, e); // wrap - } -}; // constructor polyfill - - -if (!USE_NATIVE) { - // 25.4.3.1 Promise(executor) - $Promise = function Promise(executor) { - anInstance(this, $Promise, PROMISE, '_h'); - aFunction(executor); - Internal.call(this); - - try { - executor(ctx($resolve, this, 1), ctx($reject, this, 1)); - } catch (err) { - $reject.call(this, err); - } - }; // eslint-disable-next-line no-unused-vars - - - Internal = function Promise(executor) { - this._c = []; // <- awaiting reactions - - this._a = undefined; // <- checked in isUnhandled reactions - - this._s = 0; // <- state - - this._d = false; // <- done - - this._v = undefined; // <- value - - this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled - - this._n = false; // <- notify - }; - - Internal.prototype = __webpack_require__(2853)($Promise.prototype, { - // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) - then: function then(onFulfilled, onRejected) { - var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); - reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; - reaction.fail = typeof onRejected == 'function' && onRejected; - reaction.domain = isNode ? process.domain : undefined; - - this._c.push(reaction); - - if (this._a) this._a.push(reaction); - if (this._s) notify(this, false); - return reaction.promise; - }, - // 25.4.5.1 Promise.prototype.catch(onRejected) - 'catch': function (onRejected) { - return this.then(undefined, onRejected); - } - }); - - OwnPromiseCapability = function () { - var promise = new Internal(); - this.promise = promise; - this.resolve = ctx($resolve, promise, 1); - this.reject = ctx($reject, promise, 1); - }; - - newPromiseCapabilityModule.f = newPromiseCapability = function (C) { - return C === $Promise || C === Wrapper ? new OwnPromiseCapability(C) : newGenericPromiseCapability(C); - }; -} - -$export($export.G + $export.W + $export.F * !USE_NATIVE, { - Promise: $Promise -}); - -__webpack_require__(8536)($Promise, PROMISE); - -__webpack_require__(5003)(PROMISE); - -Wrapper = __webpack_require__(7913)[PROMISE]; // statics - -$export($export.S + $export.F * !USE_NATIVE, PROMISE, { - // 25.4.4.5 Promise.reject(r) - reject: function reject(r) { - var capability = newPromiseCapability(this); - var $$reject = capability.reject; - $$reject(r); - return capability.promise; - } -}); -$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { - // 25.4.4.6 Promise.resolve(x) - resolve: function resolve(x) { - return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x); - } -}); -$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(3540)(function (iter) { - $Promise.all(iter)['catch'](empty); -})), PROMISE, { - // 25.4.4.1 Promise.all(iterable) - all: function all(iterable) { - var C = this; - var capability = newPromiseCapability(C); - var resolve = capability.resolve; - var reject = capability.reject; - var result = perform(function () { - var values = []; - var index = 0; - var remaining = 1; - forOf(iterable, false, function (promise) { - var $index = index++; - var alreadyCalled = false; - values.push(undefined); - remaining++; - C.resolve(promise).then(function (value) { - if (alreadyCalled) return; - alreadyCalled = true; - values[$index] = value; - --remaining || resolve(values); - }, reject); - }); - --remaining || resolve(values); - }); - if (result.e) reject(result.v); - return capability.promise; - }, - // 25.4.4.4 Promise.race(iterable) - race: function race(iterable) { - var C = this; - var capability = newPromiseCapability(C); - var reject = capability.reject; - var result = perform(function () { - forOf(iterable, false, function (promise) { - C.resolve(promise).then(capability.resolve, reject); - }); - }); - if (result.e) reject(result.v); - return capability.promise; - } -}); - -/***/ }), - -/***/ 4815: -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -var $at = __webpack_require__(4757)(true); // 21.1.3.27 String.prototype[@@iterator]() - - -__webpack_require__(2361)(String, 'String', function (iterated) { - this._t = String(iterated); // target - - this._i = 0; // next index - // 21.1.5.2.1 %StringIteratorPrototype%.next() -}, function () { - var O = this._t; - var index = this._i; - var point; - if (index >= O.length) return { - value: undefined, - done: true - }; - point = $at(O, index); - this._i += point.length; - return { - value: point, - done: false - }; -}); - -/***/ }), - -/***/ 8245: -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; -// https://github.com/tc39/proposal-promise-finally - - -var $export = __webpack_require__(9749); - -var core = __webpack_require__(7913); - -var global = __webpack_require__(5677); - -var speciesConstructor = __webpack_require__(6647); - -var promiseResolve = __webpack_require__(3243); - -$export($export.P + $export.R, 'Promise', { - 'finally': function (onFinally) { - var C = speciesConstructor(this, core.Promise || global.Promise); - var isFunction = typeof onFinally == 'function'; - return this.then(isFunction ? function (x) { - return promiseResolve(C, onFinally()).then(function () { - return x; - }); - } : onFinally, isFunction ? function (e) { - return promiseResolve(C, onFinally()).then(function () { - throw e; - }); - } : onFinally); - } -}); - -/***/ }), - -/***/ 5953: -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - // https://github.com/tc39/proposal-promise-try - -var $export = __webpack_require__(9749); - -var newPromiseCapability = __webpack_require__(7789); - -var perform = __webpack_require__(5472); - -$export($export.S, 'Promise', { - 'try': function (callbackfn) { - var promiseCapability = newPromiseCapability.f(this); - var result = perform(callbackfn); - (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v); - return promiseCapability.promise; - } -}); - -/***/ }), - -/***/ 8160: -/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - -__webpack_require__(66); - -var global = __webpack_require__(5677); - -var hide = __webpack_require__(51); - -var Iterators = __webpack_require__(3829); - -var TO_STRING_TAG = __webpack_require__(9506)('toStringTag'); - -var DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' + 'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' + 'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' + 'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' + 'TextTrackList,TouchList').split(','); - -for (var i = 0; i < DOMIterables.length; i++) { - var NAME = DOMIterables[i]; - var Collection = global[NAME]; - var proto = Collection && Collection.prototype; - if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME); - Iterators[NAME] = Iterators.Array; -} - -/***/ }), - -/***/ 1246: -/***/ ((module) => { - -"use strict"; - -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -// css base code, injected by the css-loader -// eslint-disable-next-line func-names - -module.exports = function (cssWithMappingToString) { - var list = []; // return the list of modules as css string - - list.toString = function toString() { - return this.map(function (item) { - var content = cssWithMappingToString(item); - - if (item[2]) { - return "@media ".concat(item[2], " {").concat(content, "}"); - } - - return content; - }).join(""); - }; // import a list of modules into the list - // eslint-disable-next-line func-names - - - list.i = function (modules, mediaQuery, dedupe) { - if (typeof modules === "string") { - // eslint-disable-next-line no-param-reassign - modules = [[null, modules, ""]]; - } - - var alreadyImportedModules = {}; - - if (dedupe) { - for (var i = 0; i < this.length; i++) { - // eslint-disable-next-line prefer-destructuring - var id = this[i][0]; - - if (id != null) { - alreadyImportedModules[id] = true; - } - } - } - - for (var _i = 0; _i < modules.length; _i++) { - var item = [].concat(modules[_i]); - - if (dedupe && alreadyImportedModules[item[0]]) { - // eslint-disable-next-line no-continue - continue; - } - - if (mediaQuery) { - if (!item[2]) { - item[2] = mediaQuery; - } else { - item[2] = "".concat(mediaQuery, " and ").concat(item[2]); - } - } - - list.push(item); - } - }; - - return list; -}; - -/***/ }), - -/***/ 7620: -/***/ ((module) => { - -"use strict"; - - -function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); -} - -function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -} - -function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); -} - -function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - - for (var i = 0, arr2 = new Array(len); i < len; i++) { - arr2[i] = arr[i]; - } - - return arr2; -} - -function _iterableToArrayLimit(arr, i) { - var _i = arr && (typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]); - - if (_i == null) return; - var _arr = []; - var _n = true; - var _d = false; - - var _s, _e; - - try { - for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; -} - -function _arrayWithHoles(arr) { - if (Array.isArray(arr)) return arr; -} - -module.exports = function cssWithMappingToString(item) { - var _item = _slicedToArray(item, 4), - content = _item[1], - cssMapping = _item[3]; - - if (!cssMapping) { - return content; - } - - if (typeof btoa === "function") { - // eslint-disable-next-line no-undef - var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping)))); - var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64); - var sourceMapping = "/*# ".concat(data, " */"); - var sourceURLs = cssMapping.sources.map(function (source) { - return "/*# sourceURL=".concat(cssMapping.sourceRoot || "").concat(source, " */"); - }); - return [content].concat(sourceURLs).concat([sourceMapping]).join("\n"); - } - - return [content].join("\n"); -}; - -/***/ }), - -/***/ 8169: -/***/ (function(module) { - -!function (t, e) { - true ? module.exports = e() : 0; -}(this, function () { - "use strict"; - - var t = 1e3, - e = 6e4, - n = 36e5, - r = "millisecond", - i = "second", - s = "minute", - u = "hour", - a = "day", - o = "week", - f = "month", - h = "quarter", - c = "year", - d = "date", - $ = "Invalid Date", - l = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, - y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, - M = { - name: "en", - weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_") - }, - m = function (t, e, n) { - var r = String(t); - return !r || r.length >= e ? t : "" + Array(e + 1 - r.length).join(n) + t; - }, - g = { - s: m, - z: function (t) { - var e = -t.utcOffset(), - n = Math.abs(e), - r = Math.floor(n / 60), - i = n % 60; - return (e <= 0 ? "+" : "-") + m(r, 2, "0") + ":" + m(i, 2, "0"); - }, - m: function t(e, n) { - if (e.date() < n.date()) return -t(n, e); - var r = 12 * (n.year() - e.year()) + (n.month() - e.month()), - i = e.clone().add(r, f), - s = n - i < 0, - u = e.clone().add(r + (s ? -1 : 1), f); - return +(-(r + (n - i) / (s ? i - u : u - i)) || 0); - }, - a: function (t) { - return t < 0 ? Math.ceil(t) || 0 : Math.floor(t); - }, - p: function (t) { - return { - M: f, - y: c, - w: o, - d: a, - D: d, - h: u, - m: s, - s: i, - ms: r, - Q: h - }[t] || String(t || "").toLowerCase().replace(/s$/, ""); - }, - u: function (t) { - return void 0 === t; - } - }, - D = "en", - v = {}; - - v[D] = M; - - var p = function (t) { - return t instanceof _; - }, - S = function (t, e, n) { - var r; - if (!t) return D; - if ("string" == typeof t) v[t] && (r = t), e && (v[t] = e, r = t);else { - var i = t.name; - v[i] = t, r = i; - } - return !n && r && (D = r), r || !n && D; - }, - w = function (t, e) { - if (p(t)) return t.clone(); - var n = "object" == typeof e ? e : {}; - return n.date = t, n.args = arguments, new _(n); - }, - O = g; - - O.l = S, O.i = p, O.w = function (t, e) { - return w(t, { - locale: e.$L, - utc: e.$u, - x: e.$x, - $offset: e.$offset - }); - }; - - var _ = function () { - function M(t) { - this.$L = S(t.locale, null, !0), this.parse(t); - } - - var m = M.prototype; - return m.parse = function (t) { - this.$d = function (t) { - var e = t.date, - n = t.utc; - if (null === e) return new Date(NaN); - if (O.u(e)) return new Date(); - if (e instanceof Date) return new Date(e); - - if ("string" == typeof e && !/Z$/i.test(e)) { - var r = e.match(l); - - if (r) { - var i = r[2] - 1 || 0, - s = (r[7] || "0").substring(0, 3); - return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)) : new Date(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s); - } - } - - return new Date(e); - }(t), this.$x = t.x || {}, this.init(); - }, m.init = function () { - var t = this.$d; - this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(), this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds(); - }, m.$utils = function () { - return O; - }, m.isValid = function () { - return !(this.$d.toString() === $); - }, m.isSame = function (t, e) { - var n = w(t); - return this.startOf(e) <= n && n <= this.endOf(e); - }, m.isAfter = function (t, e) { - return w(t) < this.startOf(e); - }, m.isBefore = function (t, e) { - return this.endOf(e) < w(t); - }, m.$g = function (t, e, n) { - return O.u(t) ? this[e] : this.set(n, t); - }, m.unix = function () { - return Math.floor(this.valueOf() / 1e3); - }, m.valueOf = function () { - return this.$d.getTime(); - }, m.startOf = function (t, e) { - var n = this, - r = !!O.u(e) || e, - h = O.p(t), - $ = function (t, e) { - var i = O.w(n.$u ? Date.UTC(n.$y, e, t) : new Date(n.$y, e, t), n); - return r ? i : i.endOf(a); - }, - l = function (t, e) { - return O.w(n.toDate()[t].apply(n.toDate("s"), (r ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e)), n); - }, - y = this.$W, - M = this.$M, - m = this.$D, - g = "set" + (this.$u ? "UTC" : ""); - - switch (h) { - case c: - return r ? $(1, 0) : $(31, 11); - - case f: - return r ? $(1, M) : $(0, M + 1); - - case o: - var D = this.$locale().weekStart || 0, - v = (y < D ? y + 7 : y) - D; - return $(r ? m - v : m + (6 - v), M); - - case a: - case d: - return l(g + "Hours", 0); - - case u: - return l(g + "Minutes", 1); - - case s: - return l(g + "Seconds", 2); - - case i: - return l(g + "Milliseconds", 3); - - default: - return this.clone(); - } - }, m.endOf = function (t) { - return this.startOf(t, !1); - }, m.$set = function (t, e) { - var n, - o = O.p(t), - h = "set" + (this.$u ? "UTC" : ""), - $ = (n = {}, n[a] = h + "Date", n[d] = h + "Date", n[f] = h + "Month", n[c] = h + "FullYear", n[u] = h + "Hours", n[s] = h + "Minutes", n[i] = h + "Seconds", n[r] = h + "Milliseconds", n)[o], - l = o === a ? this.$D + (e - this.$W) : e; - - if (o === f || o === c) { - var y = this.clone().set(d, 1); - y.$d[$](l), y.init(), this.$d = y.set(d, Math.min(this.$D, y.daysInMonth())).$d; - } else $ && this.$d[$](l); - - return this.init(), this; - }, m.set = function (t, e) { - return this.clone().$set(t, e); - }, m.get = function (t) { - return this[O.p(t)](); - }, m.add = function (r, h) { - var d, - $ = this; - r = Number(r); - - var l = O.p(h), - y = function (t) { - var e = w($); - return O.w(e.date(e.date() + Math.round(t * r)), $); - }; - - if (l === f) return this.set(f, this.$M + r); - if (l === c) return this.set(c, this.$y + r); - if (l === a) return y(1); - if (l === o) return y(7); - var M = (d = {}, d[s] = e, d[u] = n, d[i] = t, d)[l] || 1, - m = this.$d.getTime() + r * M; - return O.w(m, this); - }, m.subtract = function (t, e) { - return this.add(-1 * t, e); - }, m.format = function (t) { - var e = this, - n = this.$locale(); - if (!this.isValid()) return n.invalidDate || $; - - var r = t || "YYYY-MM-DDTHH:mm:ssZ", - i = O.z(this), - s = this.$H, - u = this.$m, - a = this.$M, - o = n.weekdays, - f = n.months, - h = function (t, n, i, s) { - return t && (t[n] || t(e, r)) || i[n].substr(0, s); - }, - c = function (t) { - return O.s(s % 12 || 12, t, "0"); - }, - d = n.meridiem || function (t, e, n) { - var r = t < 12 ? "AM" : "PM"; - return n ? r.toLowerCase() : r; - }, - l = { - YY: String(this.$y).slice(-2), - YYYY: this.$y, - M: a + 1, - MM: O.s(a + 1, 2, "0"), - MMM: h(n.monthsShort, a, f, 3), - MMMM: h(f, a), - D: this.$D, - DD: O.s(this.$D, 2, "0"), - d: String(this.$W), - dd: h(n.weekdaysMin, this.$W, o, 2), - ddd: h(n.weekdaysShort, this.$W, o, 3), - dddd: o[this.$W], - H: String(s), - HH: O.s(s, 2, "0"), - h: c(1), - hh: c(2), - a: d(s, u, !0), - A: d(s, u, !1), - m: String(u), - mm: O.s(u, 2, "0"), - s: String(this.$s), - ss: O.s(this.$s, 2, "0"), - SSS: O.s(this.$ms, 3, "0"), - Z: i - }; - - return r.replace(y, function (t, e) { - return e || l[t] || i.replace(":", ""); - }); - }, m.utcOffset = function () { - return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); - }, m.diff = function (r, d, $) { - var l, - y = O.p(d), - M = w(r), - m = (M.utcOffset() - this.utcOffset()) * e, - g = this - M, - D = O.m(this, M); - return D = (l = {}, l[c] = D / 12, l[f] = D, l[h] = D / 3, l[o] = (g - m) / 6048e5, l[a] = (g - m) / 864e5, l[u] = g / n, l[s] = g / e, l[i] = g / t, l)[y] || g, $ ? D : O.a(D); - }, m.daysInMonth = function () { - return this.endOf(f).$D; - }, m.$locale = function () { - return v[this.$L]; - }, m.locale = function (t, e) { - if (!t) return this.$L; - var n = this.clone(), - r = S(t, e, !0); - return r && (n.$L = r), n; - }, m.clone = function () { - return O.w(this.$d, this); - }, m.toDate = function () { - return new Date(this.valueOf()); - }, m.toJSON = function () { - return this.isValid() ? this.toISOString() : null; - }, m.toISOString = function () { - return this.$d.toISOString(); - }, m.toString = function () { - return this.$d.toUTCString(); - }, M; - }(), - b = _.prototype; - - return w.prototype = b, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", f], ["$y", c], ["$D", d]].forEach(function (t) { - b[t[1]] = function (e) { - return this.$g(e, t[0], t[1]); - }; - }), w.extend = function (t, e) { - return t.$i || (t(e, _, w), t.$i = !0), w; - }, w.locale = S, w.isDayjs = p, w.unix = function (t) { - return w(1e3 * t); - }, w.en = v[D], w.Ls = v, w.p = {}, w; -}); - -/***/ }), - -/***/ 8674: -/***/ (function(module) { - -!function (e, t) { - true ? module.exports = t() : 0; -}(this, function () { - "use strict"; - - return function (e, t, r) { - var n = t.prototype, - s = n.format; - r.en.ordinal = function (e) { - var t = ["th", "st", "nd", "rd"], - r = e % 100; - return "[" + e + (t[(r - 20) % 10] || t[r] || t[0]) + "]"; - }, n.format = function (e) { - var t = this, - r = this.$locale(), - n = this.$utils(), - a = (e || "YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g, function (e) { - switch (e) { - case "Q": - return Math.ceil((t.$M + 1) / 3); - - case "Do": - return r.ordinal(t.$D); - - case "gggg": - return t.weekYear(); - - case "GGGG": - return t.isoWeekYear(); - - case "wo": - return r.ordinal(t.week(), "W"); - - case "w": - case "ww": - return n.s(t.week(), "w" === e ? 1 : 2, "0"); - - case "W": - case "WW": - return n.s(t.isoWeek(), "W" === e ? 1 : 2, "0"); - - case "k": - case "kk": - return n.s(String(0 === t.$H ? 24 : t.$H), "k" === e ? 1 : 2, "0"); - - case "X": - return Math.floor(t.$d.getTime() / 1e3); - - case "x": - return t.$d.getTime(); - - case "z": - return "[" + t.offsetName() + "]"; - - case "zzz": - return "[" + t.offsetName("long") + "]"; - - default: - return e; - } - }); - return s.bind(this)(a); - }; - }; -}); - -/***/ }), - -/***/ 1041: -/***/ (function(module) { - -/*! @license DOMPurify 2.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.1/LICENSE */ -(function (global, factory) { - true ? module.exports = factory() : 0; -})(this, function () { - 'use strict'; - - function _toConsumableArray(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { - arr2[i] = arr[i]; - } - - return arr2; - } else { - return Array.from(arr); - } - } - - var hasOwnProperty = Object.hasOwnProperty, - setPrototypeOf = Object.setPrototypeOf, - isFrozen = Object.isFrozen, - getPrototypeOf = Object.getPrototypeOf, - getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; - var freeze = Object.freeze, - seal = Object.seal, - create = Object.create; // eslint-disable-line import/no-mutable-exports - - var _ref = typeof Reflect !== 'undefined' && Reflect, - apply = _ref.apply, - construct = _ref.construct; - - if (!apply) { - apply = function apply(fun, thisValue, args) { - return fun.apply(thisValue, args); - }; - } - - if (!freeze) { - freeze = function freeze(x) { - return x; - }; - } - - if (!seal) { - seal = function seal(x) { - return x; - }; - } - - if (!construct) { - construct = function construct(Func, args) { - return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray(args))))(); - }; - } - - var arrayForEach = unapply(Array.prototype.forEach); - var arrayPop = unapply(Array.prototype.pop); - var arrayPush = unapply(Array.prototype.push); - var stringToLowerCase = unapply(String.prototype.toLowerCase); - var stringMatch = unapply(String.prototype.match); - var stringReplace = unapply(String.prototype.replace); - var stringIndexOf = unapply(String.prototype.indexOf); - var stringTrim = unapply(String.prototype.trim); - var regExpTest = unapply(RegExp.prototype.test); - var typeErrorCreate = unconstruct(TypeError); - - function unapply(func) { - return function (thisArg) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - return apply(func, thisArg, args); - }; - } - - function unconstruct(func) { - return function () { - for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - - return construct(func, args); - }; - } - /* Add properties to a lookup table */ - - - function addToSet(set, array) { - if (setPrototypeOf) { - // Make 'in' and truthy checks like Boolean(set.constructor) - // independent of any properties defined on Object.prototype. - // Prevent prototype setters from intercepting set as a this value. - setPrototypeOf(set, null); - } - - var l = array.length; - - while (l--) { - var element = array[l]; - - if (typeof element === 'string') { - var lcElement = stringToLowerCase(element); - - if (lcElement !== element) { - // Config presets (e.g. tags.js, attrs.js) are immutable. - if (!isFrozen(array)) { - array[l] = lcElement; - } - - element = lcElement; - } - } - - set[element] = true; - } - - return set; - } - /* Shallow clone an object */ - - - function clone(object) { - var newObject = create(null); - var property = void 0; - - for (property in object) { - if (apply(hasOwnProperty, object, [property])) { - newObject[property] = object[property]; - } - } - - return newObject; - } - /* IE10 doesn't support __lookupGetter__ so lets' - * simulate it. It also automatically checks - * if the prop is function or getter and behaves - * accordingly. */ - - - function lookupGetter(object, prop) { - while (object !== null) { - var desc = getOwnPropertyDescriptor(object, prop); - - if (desc) { - if (desc.get) { - return unapply(desc.get); - } - - if (typeof desc.value === 'function') { - return unapply(desc.value); - } - } - - object = getPrototypeOf(object); - } - - function fallbackValue(element) { - console.warn('fallback value for', element); - return null; - } - - return fallbackValue; - } - - var html = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); // SVG - - var svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); - var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default. - // We still need to know them so that we can do namespace - // checks properly in case one wants to add them to - // allow-list. - - var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', 'feimage', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); - var mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']); // Similarly to SVG, we want to know all MathML elements, - // even those that we disallow by default. - - var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); - var text = freeze(['#text']); - var html$1 = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']); - var svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); - var mathMl$1 = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); - var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); // eslint-disable-next-line unicorn/better-regex - - var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode - - var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm); - var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape - - var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape - - var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape - ); - var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); - var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex - ); - - var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - - function _toConsumableArray$1(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { - arr2[i] = arr[i]; - } - - return arr2; - } else { - return Array.from(arr); - } - } - - var getGlobal = function getGlobal() { - return typeof window === 'undefined' ? null : window; - }; - /** - * Creates a no-op policy for internal use only. - * Don't export this function outside this module! - * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory. - * @param {Document} document The document object (to determine policy name suffix) - * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types - * are not supported). - */ - - - var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) { - if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') { - return null; - } // Allow the callers to control the unique policy name - // by adding a data-tt-policy-suffix to the script element with the DOMPurify. - // Policy creation with duplicate names throws in Trusted Types. - - - var suffix = null; - var ATTR_NAME = 'data-tt-policy-suffix'; - - if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) { - suffix = document.currentScript.getAttribute(ATTR_NAME); - } - - var policyName = 'dompurify' + (suffix ? '#' + suffix : ''); - - try { - return trustedTypes.createPolicy(policyName, { - createHTML: function createHTML(html$$1) { - return html$$1; - } - }); - } catch (_) { - // Policy creation failed (most likely another DOMPurify script has - // already run). Skip creating the policy, as this will only cause errors - // if TT are enforced. - console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); - return null; - } - }; - - function createDOMPurify() { - var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); - - var DOMPurify = function DOMPurify(root) { - return createDOMPurify(root); - }; - /** - * Version label, exposed for easier checks - * if DOMPurify is up to date or not - */ - - - DOMPurify.version = '2.3.1'; - /** - * Array of elements that DOMPurify removed during sanitation. - * Empty if nothing was removed. - */ - - DOMPurify.removed = []; - - if (!window || !window.document || window.document.nodeType !== 9) { - // Not running in a browser, provide a factory function - // so that you can pass your own Window - DOMPurify.isSupported = false; - return DOMPurify; - } - - var originalDocument = window.document; - var document = window.document; - var DocumentFragment = window.DocumentFragment, - HTMLTemplateElement = window.HTMLTemplateElement, - Node = window.Node, - Element = window.Element, - NodeFilter = window.NodeFilter, - _window$NamedNodeMap = window.NamedNodeMap, - NamedNodeMap = _window$NamedNodeMap === undefined ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap, - Text = window.Text, - Comment = window.Comment, - DOMParser = window.DOMParser, - trustedTypes = window.trustedTypes; - var ElementPrototype = Element.prototype; - var cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); - var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); - var getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); - var getParentNode = lookupGetter(ElementPrototype, 'parentNode'); // As per issue #47, the web-components registry is inherited by a - // new document created via createHTMLDocument. As per the spec - // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) - // a new empty registry is used when creating a template contents owner - // document, so we use that as our parent document to ensure nothing - // is inherited. - - if (typeof HTMLTemplateElement === 'function') { - var template = document.createElement('template'); - - if (template.content && template.content.ownerDocument) { - document = template.content.ownerDocument; - } - } - - var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument); - - var emptyHTML = trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML('') : ''; - var _document = document, - implementation = _document.implementation, - createNodeIterator = _document.createNodeIterator, - createDocumentFragment = _document.createDocumentFragment, - getElementsByTagName = _document.getElementsByTagName; - var importNode = originalDocument.importNode; - var documentMode = {}; - - try { - documentMode = clone(document).documentMode ? document.documentMode : {}; - } catch (_) {} - - var hooks = {}; - /** - * Expose whether this browser supports running the full DOMPurify. - */ - - DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9; - var MUSTACHE_EXPR$$1 = MUSTACHE_EXPR, - ERB_EXPR$$1 = ERB_EXPR, - DATA_ATTR$$1 = DATA_ATTR, - ARIA_ATTR$$1 = ARIA_ATTR, - IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA, - ATTR_WHITESPACE$$1 = ATTR_WHITESPACE; - var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI; - /** - * We consider the elements and attributes below to be safe. Ideally - * don't add any new ones but feel free to remove unwanted ones. - */ - - /* allowed element names */ - - var ALLOWED_TAGS = null; - var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(html), _toConsumableArray$1(svg), _toConsumableArray$1(svgFilters), _toConsumableArray$1(mathMl), _toConsumableArray$1(text))); - /* Allowed attribute names */ - - var ALLOWED_ATTR = null; - var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray$1(html$1), _toConsumableArray$1(svg$1), _toConsumableArray$1(mathMl$1), _toConsumableArray$1(xml))); - /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ - - var FORBID_TAGS = null; - /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ - - var FORBID_ATTR = null; - /* Decide if ARIA attributes are okay */ - - var ALLOW_ARIA_ATTR = true; - /* Decide if custom data attributes are okay */ - - var ALLOW_DATA_ATTR = true; - /* Decide if unknown protocols are okay */ - - var ALLOW_UNKNOWN_PROTOCOLS = false; - /* Output should be safe for common template engines. - * This means, DOMPurify removes data attributes, mustaches and ERB - */ - - var SAFE_FOR_TEMPLATES = false; - /* Decide if document with ... should be returned */ - - var WHOLE_DOCUMENT = false; - /* Track whether config is already set on this instance of DOMPurify. */ - - var SET_CONFIG = false; - /* Decide if all elements (e.g. style, script) must be children of - * document.body. By default, browsers might move them to document.head */ - - var FORCE_BODY = false; - /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported). - * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead - */ - - var RETURN_DOM = false; - /* Decide if a DOM `DocumentFragment` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported) */ - - var RETURN_DOM_FRAGMENT = false; - /* If `RETURN_DOM` or `RETURN_DOM_FRAGMENT` is enabled, decide if the returned DOM - * `Node` is imported into the current `Document`. If this flag is not enabled the - * `Node` will belong (its ownerDocument) to a fresh `HTMLDocument`, created by - * DOMPurify. - * - * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false` - * might cause XSS from attacks hidden in closed shadowroots in case the browser - * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/ - */ - - var RETURN_DOM_IMPORT = true; - /* Try to return a Trusted Type object instead of a string, return a string in - * case Trusted Types are not supported */ - - var RETURN_TRUSTED_TYPE = false; - /* Output should be free from DOM clobbering attacks? */ - - var SANITIZE_DOM = true; - /* Keep element content when removing element? */ - - var KEEP_CONTENT = true; - /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead - * of importing it into a new Document and returning a sanitized copy */ - - var IN_PLACE = false; - /* Allow usage of profiles like html, svg and mathMl */ - - var USE_PROFILES = {}; - /* Tags to ignore content of when KEEP_CONTENT is true */ - - var FORBID_CONTENTS = null; - var DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); - /* Tags that are safe for data: URIs */ - - var DATA_URI_TAGS = null; - var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); - /* Attributes safe for values like "javascript:" */ - - var URI_SAFE_ATTRIBUTES = null; - var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); - var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; - var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; - var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; - /* Document namespace */ - - var NAMESPACE = HTML_NAMESPACE; - var IS_EMPTY_INPUT = false; - /* Keep a reference to config to pass to hooks */ - - var CONFIG = null; - /* Ideally, do not touch anything below this line */ - - /* ______________________________________________ */ - - var formElement = document.createElement('form'); - /** - * _parseConfig - * - * @param {Object} cfg optional config literal - */ - // eslint-disable-next-line complexity - - var _parseConfig = function _parseConfig(cfg) { - if (CONFIG && CONFIG === cfg) { - return; - } - /* Shield configuration object from tampering */ - - - if (!cfg || (typeof cfg === 'undefined' ? 'undefined' : _typeof(cfg)) !== 'object') { - cfg = {}; - } - /* Shield configuration object from prototype pollution */ - - - cfg = clone(cfg); - /* Set configuration parameters */ - - ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS) : DEFAULT_ALLOWED_TAGS; - ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR) : DEFAULT_ALLOWED_ATTR; - URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR) : DEFAULT_URI_SAFE_ATTRIBUTES; - DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS) : DEFAULT_DATA_URI_TAGS; - FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS) : DEFAULT_FORBID_CONTENTS; - FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {}; - FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {}; - USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false; - ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true - - ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true - - ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false - - SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false - - WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false - - RETURN_DOM = cfg.RETURN_DOM || false; // Default false - - RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false - - RETURN_DOM_IMPORT = cfg.RETURN_DOM_IMPORT !== false; // Default true - - RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false - - FORCE_BODY = cfg.FORCE_BODY || false; // Default false - - SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true - - KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true - - IN_PLACE = cfg.IN_PLACE || false; // Default false - - IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1; - NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; - - if (SAFE_FOR_TEMPLATES) { - ALLOW_DATA_ATTR = false; - } - - if (RETURN_DOM_FRAGMENT) { - RETURN_DOM = true; - } - /* Parse profile info */ - - - if (USE_PROFILES) { - ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray$1(text))); - ALLOWED_ATTR = []; - - if (USE_PROFILES.html === true) { - addToSet(ALLOWED_TAGS, html); - addToSet(ALLOWED_ATTR, html$1); - } - - if (USE_PROFILES.svg === true) { - addToSet(ALLOWED_TAGS, svg); - addToSet(ALLOWED_ATTR, svg$1); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.svgFilters === true) { - addToSet(ALLOWED_TAGS, svgFilters); - addToSet(ALLOWED_ATTR, svg$1); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.mathMl === true) { - addToSet(ALLOWED_TAGS, mathMl); - addToSet(ALLOWED_ATTR, mathMl$1); - addToSet(ALLOWED_ATTR, xml); - } - } - /* Merge configuration parameters */ - - - if (cfg.ADD_TAGS) { - if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { - ALLOWED_TAGS = clone(ALLOWED_TAGS); - } - - addToSet(ALLOWED_TAGS, cfg.ADD_TAGS); - } - - if (cfg.ADD_ATTR) { - if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { - ALLOWED_ATTR = clone(ALLOWED_ATTR); - } - - addToSet(ALLOWED_ATTR, cfg.ADD_ATTR); - } - - if (cfg.ADD_URI_SAFE_ATTR) { - addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR); - } - - if (cfg.FORBID_CONTENTS) { - if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { - FORBID_CONTENTS = clone(FORBID_CONTENTS); - } - - addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS); - } - /* Add #text in case KEEP_CONTENT is set to true */ - - - if (KEEP_CONTENT) { - ALLOWED_TAGS['#text'] = true; - } - /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ - - - if (WHOLE_DOCUMENT) { - addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); - } - /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ - - - if (ALLOWED_TAGS.table) { - addToSet(ALLOWED_TAGS, ['tbody']); - delete FORBID_TAGS.tbody; - } // Prevent further manipulation of configuration. - // Not available in IE8, Safari 5, etc. - - - if (freeze) { - freeze(cfg); - } - - CONFIG = cfg; - }; - - var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); - var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); - /* Keep track of all possible SVG and MathML tags - * so that we can perform the namespace checks - * correctly. */ - - var ALL_SVG_TAGS = addToSet({}, svg); - addToSet(ALL_SVG_TAGS, svgFilters); - addToSet(ALL_SVG_TAGS, svgDisallowed); - var ALL_MATHML_TAGS = addToSet({}, mathMl); - addToSet(ALL_MATHML_TAGS, mathMlDisallowed); - /** - * - * - * @param {Element} element a DOM element whose namespace is being checked - * @returns {boolean} Return false if the element has a - * namespace that a spec-compliant parser would never - * return. Return true otherwise. - */ - - var _checkValidNamespace = function _checkValidNamespace(element) { - var parent = getParentNode(element); // In JSDOM, if we're inside shadow DOM, then parentNode - // can be null. We just simulate parent in this case. - - if (!parent || !parent.tagName) { - parent = { - namespaceURI: HTML_NAMESPACE, - tagName: 'template' - }; - } - - var tagName = stringToLowerCase(element.tagName); - var parentTagName = stringToLowerCase(parent.tagName); - - if (element.namespaceURI === SVG_NAMESPACE) { - // The only way to switch from HTML namespace to SVG - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'svg'; - } // The only way to switch from MathML to SVG is via - // svg if parent is either or MathML - // text integration points. - - - if (parent.namespaceURI === MATHML_NAMESPACE) { - return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); - } // We only allow elements that are defined in SVG - // spec. All others are disallowed in SVG namespace. - - - return Boolean(ALL_SVG_TAGS[tagName]); - } - - if (element.namespaceURI === MATHML_NAMESPACE) { - // The only way to switch from HTML namespace to MathML - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'math'; - } // The only way to switch from SVG to MathML is via - // and HTML integration points - - - if (parent.namespaceURI === SVG_NAMESPACE) { - return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; - } // We only allow elements that are defined in MathML - // spec. All others are disallowed in MathML namespace. - - - return Boolean(ALL_MATHML_TAGS[tagName]); - } - - if (element.namespaceURI === HTML_NAMESPACE) { - // The only way to switch from SVG to HTML is via - // HTML integration points, and from MathML to HTML - // is via MathML text integration points - if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { - return false; - } - - if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { - return false; - } // Certain elements are allowed in both SVG and HTML - // namespace. We need to specify them explicitly - // so that they don't get erronously deleted from - // HTML namespace. - - - var commonSvgAndHTMLElements = addToSet({}, ['title', 'style', 'font', 'a', 'script']); // We disallow tags that are specific for MathML - // or SVG and should never appear in HTML namespace - - return !ALL_MATHML_TAGS[tagName] && (commonSvgAndHTMLElements[tagName] || !ALL_SVG_TAGS[tagName]); - } // The code should never reach this place (this means - // that the element somehow got namespace that is not - // HTML, SVG or MathML). Return false just in case. - - - return false; - }; - /** - * _forceRemove - * - * @param {Node} node a DOM node - */ - - - var _forceRemove = function _forceRemove(node) { - arrayPush(DOMPurify.removed, { - element: node - }); - - try { - // eslint-disable-next-line unicorn/prefer-dom-node-remove - node.parentNode.removeChild(node); - } catch (_) { - try { - node.outerHTML = emptyHTML; - } catch (_) { - node.remove(); - } - } - }; - /** - * _removeAttribute - * - * @param {String} name an Attribute name - * @param {Node} node a DOM node - */ - - - var _removeAttribute = function _removeAttribute(name, node) { - try { - arrayPush(DOMPurify.removed, { - attribute: node.getAttributeNode(name), - from: node - }); - } catch (_) { - arrayPush(DOMPurify.removed, { - attribute: null, - from: node - }); - } - - node.removeAttribute(name); // We void attribute values for unremovable "is"" attributes - - if (name === 'is' && !ALLOWED_ATTR[name]) { - if (RETURN_DOM || RETURN_DOM_FRAGMENT) { - try { - _forceRemove(node); - } catch (_) {} - } else { - try { - node.setAttribute(name, ''); - } catch (_) {} - } - } - }; - /** - * _initDocument - * - * @param {String} dirty a string of dirty markup - * @return {Document} a DOM, filled with the dirty markup - */ - - - var _initDocument = function _initDocument(dirty) { - /* Create a HTML document */ - var doc = void 0; - var leadingWhitespace = void 0; - - if (FORCE_BODY) { - dirty = '' + dirty; - } else { - /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ - var matches = stringMatch(dirty, /^[\r\n\t ]+/); - leadingWhitespace = matches && matches[0]; - } - - var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; - /* - * Use the DOMParser API by default, fallback later if needs be - * DOMParser not work for svg when has multiple root element. - */ - - if (NAMESPACE === HTML_NAMESPACE) { - try { - doc = new DOMParser().parseFromString(dirtyPayload, 'text/html'); - } catch (_) {} - } - /* Use createHTMLDocument in case DOMParser is not available */ - - - if (!doc || !doc.documentElement) { - doc = implementation.createDocument(NAMESPACE, 'template', null); - - try { - doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload; - } catch (_) {// Syntax error if dirtyPayload is invalid xml - } - } - - var body = doc.body || doc.documentElement; - - if (dirty && leadingWhitespace) { - body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); - } - /* Work on whole document or just its body */ - - - if (NAMESPACE === HTML_NAMESPACE) { - return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; - } - - return WHOLE_DOCUMENT ? doc.documentElement : body; - }; - /** - * _createIterator - * - * @param {Document} root document/fragment to create iterator for - * @return {Iterator} iterator instance - */ - - - var _createIterator = function _createIterator(root) { - return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false); - }; - /** - * _isClobbered - * - * @param {Node} elm element to check for clobbering attacks - * @return {Boolean} true if clobbered, false if safe - */ - - - var _isClobbered = function _isClobbered(elm) { - if (elm instanceof Text || elm instanceof Comment) { - return false; - } - - if (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function') { - return true; - } - - return false; - }; - /** - * _isNode - * - * @param {Node} obj object to check whether it's a DOM node - * @return {Boolean} true is object is a DOM node - */ - - - var _isNode = function _isNode(object) { - return (typeof Node === 'undefined' ? 'undefined' : _typeof(Node)) === 'object' ? object instanceof Node : object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'; - }; - /** - * _executeHook - * Execute user configurable hooks - * - * @param {String} entryPoint Name of the hook's entry point - * @param {Node} currentNode node to work on with the hook - * @param {Object} data additional hook parameters - */ - - - var _executeHook = function _executeHook(entryPoint, currentNode, data) { - if (!hooks[entryPoint]) { - return; - } - - arrayForEach(hooks[entryPoint], function (hook) { - hook.call(DOMPurify, currentNode, data, CONFIG); - }); - }; - /** - * _sanitizeElements - * - * @protect nodeName - * @protect textContent - * @protect removeChild - * - * @param {Node} currentNode to check for permission to exist - * @return {Boolean} true if node was killed, false if left alive - */ - - - var _sanitizeElements = function _sanitizeElements(currentNode) { - var content = void 0; - /* Execute a hook if present */ - - _executeHook('beforeSanitizeElements', currentNode, null); - /* Check if element is clobbered or can clobber */ - - - if (_isClobbered(currentNode)) { - _forceRemove(currentNode); - - return true; - } - /* Check if tagname contains Unicode */ - - - if (stringMatch(currentNode.nodeName, /[\u0080-\uFFFF]/)) { - _forceRemove(currentNode); - - return true; - } - /* Now let's check the element's type and name */ - - - var tagName = stringToLowerCase(currentNode.nodeName); - /* Execute a hook if present */ - - _executeHook('uponSanitizeElement', currentNode, { - tagName: tagName, - allowedTags: ALLOWED_TAGS - }); - /* Detect mXSS attempts abusing namespace confusion */ - - - if (!_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { - _forceRemove(currentNode); - - return true; - } - /* Mitigate a problem with templates inside select */ - - - if (tagName === 'select' && regExpTest(/ tag of the message stanza - * @property { String } chat_state - The XEP-0085 chat state notification contained in this message - * @property { String } contact_jid - The JID of the other person or entity - * @property { String } edited - An ISO8601 string recording the time that the message was edited per XEP-0308 - * @property { String } error_condition - The defined error condition - * @property { String } error_text - The error text received from the server - * @property { String } error_type - The type of error received from the server - * @property { String } from - The sender JID - * @property { String } fullname - The full name of the sender - * @property { String } marker - The XEP-0333 Chat Marker value - * @property { String } marker_id - The `id` attribute of a XEP-0333 chat marker - * @property { String } msgid - The root `id` attribute of the stanza - * @property { String } nick - The roster nickname of the sender - * @property { String } oob_desc - The description of the XEP-0066 out of band data - * @property { String } oob_url - The URL of the XEP-0066 out of band data - * @property { String } origin_id - The XEP-0359 Origin ID - * @property { String } receipt_id - The `id` attribute of a XEP-0184 element - * @property { String } received - An ISO8601 string recording the time that the message was received - * @property { String } replace_id - The `id` attribute of a XEP-0308 element - * @property { String } retracted - An ISO8601 string recording the time that the message was retracted - * @property { String } retracted_id - The `id` attribute of a XEP-424 element - * @property { String } spoiler_hint The XEP-0382 spoiler hint - * @property { String } stanza_id - The XEP-0359 Stanza ID. Note: the key is actualy `stanza_id ${by_jid}` and there can be multiple. - * @property { String } subject - The element value - * @property { String } thread - The element value - * @property { String } time - The time (in ISO8601 format), either given by the XEP-0203 element, or of receipt. - * @property { String } to - The recipient JID - * @property { String } type - The type of message - */ - - - const delay = parsers_sizzle(`delay[xmlns="${parsers_Strophe.NS.DELAY}"]`, original_stanza).pop(); - const marker = getChatMarker(stanza); - const now = new Date().toISOString(); - let attrs = Object.assign({ - contact_jid, - is_archived, - is_headline, - is_server_message, - 'body': (_stanza$querySelector = stanza.querySelector('body')) === null || _stanza$querySelector === void 0 ? void 0 : (_stanza$querySelector2 = _stanza$querySelector.textContent) === null || _stanza$querySelector2 === void 0 ? void 0 : _stanza$querySelector2.trim(), - 'chat_state': getChatState(stanza), - 'from': parsers_Strophe.getBareJidFromJid(stanza.getAttribute('from')), - 'is_carbon': isCarbon(original_stanza), - 'is_delayed': !!delay, - 'is_markable': !!parsers_sizzle(`markable[xmlns="${parsers_Strophe.NS.MARKERS}"]`, stanza).length, - 'is_marker': !!marker, - 'is_unstyled': !!parsers_sizzle(`unstyled[xmlns="${parsers_Strophe.NS.STYLING}"]`, stanza).length, - 'marker_id': marker && marker.getAttribute('id'), - 'msgid': stanza.getAttribute('id') || original_stanza.getAttribute('id'), - 'nick': (_contact = contact) === null || _contact === void 0 ? void 0 : (_contact$attributes = _contact.attributes) === null || _contact$attributes === void 0 ? void 0 : _contact$attributes.nickname, - 'receipt_id': getReceiptId(stanza), - 'received': new Date().toISOString(), - 'references': getReferences(stanza), - 'sender': is_me ? 'me' : 'them', - 'subject': (_stanza$querySelector3 = stanza.querySelector('subject')) === null || _stanza$querySelector3 === void 0 ? void 0 : _stanza$querySelector3.textContent, - 'thread': (_stanza$querySelector4 = stanza.querySelector('thread')) === null || _stanza$querySelector4 === void 0 ? void 0 : _stanza$querySelector4.textContent, - 'time': delay ? dayjs_min_default()(delay.getAttribute('stamp')).toISOString() : now, - 'to': stanza.getAttribute('to'), - 'type': stanza.getAttribute('type') - }, getErrorAttributes(stanza), getOutOfBandAttributes(stanza), getSpoilerAttributes(stanza), getCorrectionAttributes(stanza, original_stanza), getStanzaIDs(stanza, original_stanza), getRetractionAttributes(stanza, original_stanza), getEncryptionAttributes(stanza, _converse)); - - if (attrs.is_archived) { - const from = original_stanza.getAttribute('from'); - - if (from && from !== _converse.bare_jid) { - return new StanzaParseError(`Invalid Stanza: Forged MAM message from ${from}`, stanza); - } - } - - await api.emojis.initialize(); - attrs = Object.assign({ - 'message': attrs.body || attrs.error, - // TODO: Remove and use body and error attributes instead - 'is_only_emojis': attrs.body ? utils_core.isOnlyEmojis(attrs.body) : false, - 'is_valid_receipt_request': isValidReceiptRequest(stanza, attrs) - }, attrs); // We prefer to use one of the XEP-0359 unique and stable stanza IDs - // as the Model id, to avoid duplicates. - - attrs['id'] = attrs['origin_id'] || attrs[`stanza_id ${attrs.from}`] || utils_core.getUniqueId(); - /** - * *Hook* which allows plugins to add additional parsing - * @event _converse#parseMessage - */ - - attrs = await api.hook('parseMessage', stanza, attrs); // We call this after the hook, to allow plugins to decrypt encrypted - // messages, since we need to parse the message text to determine whether - // there are media urls. - - return Object.assign(attrs, getMediaURLs(attrs.is_encrypted ? attrs.plaintext : attrs.body)); -} -;// CONCATENATED MODULE: ./src/headless/plugins/chat/model.js - - - - - - - - - - - - - - -const { - Strophe: model_Strophe, - $msg: model_$msg -} = core_converse.env; -const model_u = core_converse.env.utils; -/** - * Represents an open/ongoing chat conversation. - * - * @class - * @namespace _converse.ChatBox - * @memberOf _converse - */ - -const ChatBox = model_with_contact.extend({ - defaults() { - return { - 'bookmarked': false, - 'chat_state': undefined, - 'hidden': shared_converse.isUniView() && !api.settings.get('singleton'), - 'message_type': 'chat', - 'nickname': undefined, - 'num_unread': 0, - 'time_opened': this.get('time_opened') || new Date().getTime(), - 'time_sent': new Date(0).toISOString(), - 'type': shared_converse.PRIVATE_CHAT_TYPE, - 'url': '' - }; - }, - - async initialize() { - this.initialized = getOpenPromise(); - model_with_contact.prototype.initialize.apply(this, arguments); - const jid = this.get('jid'); - - if (!jid) { - // XXX: The `validate` method will prevent this model - // from being persisted if there's no jid, but that gets - // called after model instantiation, so we have to deal - // with invalid models here also. - // This happens when the controlbox is in browser storage, - // but we're in embedded mode. - return; - } - - this.set({ - 'box_id': `box-${jid}` - }); - this.initNotifications(); - this.initUI(); - this.initMessages(); - - if (this.get('type') === shared_converse.PRIVATE_CHAT_TYPE) { - this.presence = shared_converse.presences.findWhere({ - 'jid': jid - }) || shared_converse.presences.create({ - 'jid': jid - }); - await this.setRosterContact(jid); - this.presence.on('change:show', item => this.onPresenceChanged(item)); - } - - this.on('change:chat_state', this.sendChatState, this); - this.ui.on('change:scrolled', this.onScrolledChanged, this); - await this.fetchMessages(); - /** - * Triggered once a {@link _converse.ChatBox} has been created and initialized. - * @event _converse#chatBoxInitialized - * @type { _converse.ChatBox} - * @example _converse.api.listen.on('chatBoxInitialized', model => { ... }); - */ - - await api.trigger('chatBoxInitialized', this, { - 'Synchronous': true - }); - this.initialized.resolve(); - }, - - getMessagesCollection() { - return new shared_converse.Messages(); - }, - - getMessagesCacheKey() { - return `converse.messages-${this.get('jid')}-${shared_converse.bare_jid}`; - }, - - initMessages() { - this.messages = this.getMessagesCollection(); - this.messages.fetched = getOpenPromise(); - this.messages.fetched.then(() => { - this.pruneHistoryWhenScrolledDown(); - /** - * Triggered whenever a `_converse.ChatBox` instance has fetched its messages from - * `sessionStorage` but **NOT** from the server. - * @event _converse#afterMessagesFetched - * @type {_converse.ChatBoxView | _converse.ChatRoomView} - * @example _converse.api.listen.on('afterMessagesFetched', view => { ... }); - */ - - api.trigger('afterMessagesFetched', this); - }); - this.messages.chatbox = this; - initStorage(this.messages, this.getMessagesCacheKey()); - this.listenTo(this.messages, 'change:upload', this.onMessageUploadChanged, this); - this.listenTo(this.messages, 'add', this.onMessageAdded, this); - }, - - initUI() { - this.ui = new Model(); - }, - - initNotifications() { - this.notifications = new Model(); - }, - - getNotificationsText() { - var _this$notifications, _this$notifications2, _this$notifications3; - - const { - __ - } = shared_converse; - - if (((_this$notifications = this.notifications) === null || _this$notifications === void 0 ? void 0 : _this$notifications.get('chat_state')) === shared_converse.COMPOSING) { - return __('%1$s is typing', this.getDisplayName()); - } else if (((_this$notifications2 = this.notifications) === null || _this$notifications2 === void 0 ? void 0 : _this$notifications2.get('chat_state')) === shared_converse.PAUSED) { - return __('%1$s has stopped typing', this.getDisplayName()); - } else if (((_this$notifications3 = this.notifications) === null || _this$notifications3 === void 0 ? void 0 : _this$notifications3.get('chat_state')) === shared_converse.GONE) { - return __('%1$s has gone away', this.getDisplayName()); - } else { - return ''; - } - }, - - afterMessagesFetched(messages) { - this.most_recent_cached_message = messages ? this.getMostRecentMessage(messages) : null; - /** - * Triggered whenever a `_converse.ChatBox` instance has fetched its messages from - * `sessionStorage` but **NOT** from the server. - * @event _converse#afterMessagesFetched - * @type {_converse.ChatBox | _converse.ChatRoom} - * @example _converse.api.listen.on('afterMessagesFetched', view => { ... }); - */ - - api.trigger('afterMessagesFetched', this); - }, - - fetchMessages() { - if (this.messages.fetched_flag) { - headless_log.info(`Not re-fetching messages for ${this.get('jid')}`); - return; - } - - this.most_recent_cached_message = null; - this.messages.fetched_flag = true; - const resolve = this.messages.fetched.resolve; - this.messages.fetch({ - 'add': true, - 'success': msgs => { - this.afterMessagesFetched(msgs); - resolve(); - }, - 'error': () => { - this.afterMessagesFetched(); - resolve(); - } - }); - return this.messages.fetched; - }, - - async handleErrorMessageStanza(stanza) { - const { - __ - } = shared_converse; - const attrs = await parseMessage(stanza, shared_converse); - - if (!(await this.shouldShowErrorMessage(attrs))) { - return; - } - - const message = this.getMessageReferencedByError(attrs); - - if (message) { - const new_attrs = { - 'error': attrs.error, - 'error_condition': attrs.error_condition, - 'error_text': attrs.error_text, - 'error_type': attrs.error_type, - 'editable': false - }; - - if (attrs.msgid === message.get('retraction_id')) { - // The error message refers to a retraction - new_attrs.retraction_id = undefined; - - if (!attrs.error) { - if (attrs.error_condition === 'forbidden') { - new_attrs.error = __("You're not allowed to retract your message."); - } else { - new_attrs.error = __('Sorry, an error occurred while trying to retract your message.'); - } - } - } else if (!attrs.error) { - if (attrs.error_condition === 'forbidden') { - new_attrs.error = __("You're not allowed to send a message."); - } else { - new_attrs.error = __('Sorry, an error occurred while trying to send your message.'); - } - } - - message.save(new_attrs); - } else { - this.createMessage(attrs); - } - }, - - /** - * Queue an incoming `chat` message stanza for processing. - * @async - * @private - * @method _converse.ChatBox#queueMessage - * @param { Promise } attrs - A promise which resolves to the message attributes - */ - queueMessage(attrs) { - this.msg_chain = (this.msg_chain || this.messages.fetched).then(() => this.onMessage(attrs)).catch(e => headless_log.error(e)); - return this.msg_chain; - }, - - /** - * @async - * @private - * @method _converse.ChatBox#onMessage - * @param { MessageAttributes } attrs_promse - A promise which resolves to the message attributes. - */ - async onMessage(attrs) { - attrs = await attrs; - - if (model_u.isErrorObject(attrs)) { - attrs.stanza && headless_log.error(attrs.stanza); - return headless_log.error(attrs.message); - } - - const message = this.getDuplicateMessage(attrs); - - if (message) { - this.updateMessage(message, attrs); - } else if (!this.handleReceipt(attrs) && !this.handleChatMarker(attrs) && !(await this.handleRetraction(attrs))) { - this.setEditable(attrs, attrs.time); - - if (attrs['chat_state'] && attrs.sender === 'them') { - this.notifications.set('chat_state', attrs.chat_state); - } - - if (model_u.shouldCreateMessage(attrs)) { - const msg = this.handleCorrection(attrs) || (await this.createMessage(attrs)); - this.notifications.set({ - 'chat_state': null - }); - this.handleUnreadMessage(msg); - } - } - }, - - async onMessageUploadChanged(message) { - if (message.get('upload') === shared_converse.SUCCESS) { - const attrs = { - 'body': message.get('message'), - 'spoiler_hint': message.get('spoiler_hint'), - 'oob_url': message.get('oob_url') - }; - await this.sendMessage(attrs); - message.destroy(); - } - }, - - onMessageAdded(message) { - if (api.settings.get('prune_messages_above') && (api.settings.get('pruning_behavior') === 'scrolled' || !this.ui.get('scrolled')) && !model_u.isEmptyMessage(message)) { - debouncedPruneHistory(this); - } - }, - - async clearMessages() { - try { - await this.messages.clearStore(); - } catch (e) { - this.messages.trigger('reset'); - headless_log.error(e); - } finally { - delete this.msg_chain; - delete this.messages.fetched_flag; - this.messages.fetched = getOpenPromise(); - } - }, - - async close() { - if (api.connection.connected()) { - // Immediately sending the chat state, because the - // model is going to be destroyed afterwards. - this.setChatState(shared_converse.INACTIVE); - this.sendChatState(); - } - - try { - await new Promise((success, reject) => { - return this.destroy({ - success, - 'error': (m, e) => reject(e) - }); - }); - } catch (e) { - headless_log.error(e); - } finally { - if (api.settings.get('clear_messages_on_reconnection')) { - await this.clearMessages(); - } - } - /** - * Triggered once a chatbox has been closed. - * @event _converse#chatBoxClosed - * @type {_converse.ChatBox | _converse.ChatRoom} - * @example _converse.api.listen.on('chatBoxClosed', chat => { ... }); - */ - - - api.trigger('chatBoxClosed', this); - }, - - announceReconnection() { - /** - * Triggered whenever a `_converse.ChatBox` instance has reconnected after an outage - * @event _converse#onChatReconnected - * @type {_converse.ChatBox | _converse.ChatRoom} - * @example _converse.api.listen.on('onChatReconnected', chat => { ... }); - */ - api.trigger('chatReconnected', this); - }, - - async onReconnection() { - if (api.settings.get('clear_messages_on_reconnection')) { - await this.clearMessages(); - } - - this.announceReconnection(); - }, - - onPresenceChanged(item) { - const { - __ - } = shared_converse; - const show = item.get('show'); - const fullname = this.getDisplayName(); - let text; - - if (show === 'offline') { - text = __('%1$s has gone offline', fullname); - } else if (show === 'away') { - text = __('%1$s has gone away', fullname); - } else if (show === 'dnd') { - text = __('%1$s is busy', fullname); - } else if (show === 'online') { - text = __('%1$s is online', fullname); - } - - text && this.createMessage({ - 'message': text, - 'type': 'info' - }); - }, - - onScrolledChanged() { - if (!this.ui.get('scrolled')) { - this.clearUnreadMsgCounter(); - this.pruneHistoryWhenScrolledDown(); - } - }, - - pruneHistoryWhenScrolledDown() { - if (api.settings.get('prune_messages_above') && api.settings.get('pruning_behavior') === 'unscrolled' && !this.ui.get('scrolled')) { - pruneHistory(this); - } - }, - - validate(attrs) { - if (!attrs.jid) { - return 'Ignored ChatBox without JID'; - } - - const room_jids = api.settings.get('auto_join_rooms').map(s => lodash_es_isObject(s) ? s.jid : s); - const auto_join = api.settings.get('auto_join_private_chats').concat(room_jids); - - if (api.settings.get("singleton") && !auto_join.includes(attrs.jid) && !api.settings.get('auto_join_on_invite')) { - const msg = `${attrs.jid} is not allowed because singleton is true and it's not being auto_joined`; - headless_log.warn(msg); - return msg; - } - }, - - getDisplayName() { - if (this.contact) { - return this.contact.getDisplayName(); - } else if (this.vcard) { - return this.vcard.getDisplayName(); - } else { - return this.get('jid'); - } - }, - - async createMessageFromError(error) { - if (error instanceof shared_converse.TimeoutError) { - const msg = await this.createMessage({ - 'type': 'error', - 'message': error.message, - 'retry_event_id': error.retry_event_id - }); - msg.error = error; - } - }, - - editEarlierMessage() { - let message; - let idx = this.messages.findLastIndex('correcting'); - - if (idx >= 0) { - this.messages.at(idx).save('correcting', false); - - while (idx > 0) { - idx -= 1; - const candidate = this.messages.at(idx); - - if (candidate.get('editable')) { - message = candidate; - break; - } - } - } - - message = message || this.messages.filter({ - 'sender': 'me' - }).reverse().find(m => m.get('editable')); - - if (message) { - message.save('correcting', true); - } - }, - - editLaterMessage() { - let message; - let idx = this.messages.findLastIndex('correcting'); - - if (idx >= 0) { - this.messages.at(idx).save('correcting', false); - - while (idx < this.messages.length - 1) { - idx += 1; - const candidate = this.messages.at(idx); - - if (candidate.get('editable')) { - message = candidate; - message.save('correcting', true); - break; - } - } - } - - return message; - }, - - getOldestMessage() { - for (let i = 0; i < this.messages.length; i++) { - const message = this.messages.at(i); - - if (message.get('type') === this.get('message_type')) { - return message; - } - } - }, - - getMostRecentMessage(messages) { - messages = messages || this.messages; - - for (let i = messages.length - 1; i >= 0; i--) { - const message = messages.at(i); - - if (message.get('type') === this.get('message_type')) { - return message; - } - } - }, - - getUpdatedMessageAttributes(message, attrs) { - // Filter the attrs object, restricting it to only the `is_archived` key. - return (({ - is_archived - }) => ({ - is_archived - }))(attrs); - }, - - updateMessage(message, attrs) { - const new_attrs = this.getUpdatedMessageAttributes(message, attrs); - new_attrs && message.save(new_attrs); - }, - - /** - * Mutator for setting the chat state of this chat session. - * Handles clearing of any chat state notification timeouts and - * setting new ones if necessary. - * Timeouts are set when the state being set is COMPOSING or PAUSED. - * After the timeout, COMPOSING will become PAUSED and PAUSED will become INACTIVE. - * See XEP-0085 Chat State Notifications. - * @private - * @method _converse.ChatBox#setChatState - * @param { string } state - The chat state (consts ACTIVE, COMPOSING, PAUSED, INACTIVE, GONE) - */ - setChatState(state, options) { - if (this.chat_state_timeout !== undefined) { - window.clearTimeout(this.chat_state_timeout); - delete this.chat_state_timeout; - } - - if (state === shared_converse.COMPOSING) { - this.chat_state_timeout = window.setTimeout(this.setChatState.bind(this), shared_converse.TIMEOUTS.PAUSED, shared_converse.PAUSED); - } else if (state === shared_converse.PAUSED) { - this.chat_state_timeout = window.setTimeout(this.setChatState.bind(this), shared_converse.TIMEOUTS.INACTIVE, shared_converse.INACTIVE); - } - - this.set('chat_state', state, options); - return this; - }, - - /** - * Given an error `` stanza's attributes, find the saved message model which is - * referenced by that error. - * @param { Object } attrs - */ - getMessageReferencedByError(attrs) { - const id = attrs.msgid; - return id && this.messages.models.find(m => [m.get('msgid'), m.get('retraction_id')].includes(id)); - }, - - /** - * @private - * @method _converse.ChatBox#shouldShowErrorMessage - * @returns {boolean} - */ - shouldShowErrorMessage(attrs) { - const msg = this.getMessageReferencedByError(attrs); - - if (!msg && !attrs.body) { - // If the error refers to a message not included in our store, - // and it doesn't have a tag, we assume that this was a - // CSI message (which we don't store). - // See https://github.com/conversejs/converse.js/issues/1317 - return; - } // Gets overridden in ChatRoom - - - return true; - }, - - isSameUser(jid1, jid2) { - return model_u.isSameBareJID(jid1, jid2); - }, - - /** - * Looks whether we already have a retraction for this - * incoming message. If so, it's considered "dangling" because it - * probably hasn't been applied to anything yet, given that the - * relevant message is only coming in now. - * @private - * @method _converse.ChatBox#findDanglingRetraction - * @param { object } attrs - Attributes representing a received - * message, as returned by {@link parseMessage} - * @returns { _converse.Message } - */ - findDanglingRetraction(attrs) { - if (!attrs.origin_id || !this.messages.length) { - return null; - } // Only look for dangling retractions if there are newer - // messages than this one, since retractions come after. - - - if (this.messages.last().get('time') > attrs.time) { - // Search from latest backwards - const messages = Array.from(this.messages.models); - messages.reverse(); - return messages.find(({ - attributes - }) => attributes.retracted_id === attrs.origin_id && attributes.from === attrs.from && !attributes.moderated_by); - } - }, - - /** - * Handles message retraction based on the passed in attributes. - * @private - * @method _converse.ChatBox#handleRetraction - * @param { object } attrs - Attributes representing a received - * message, as returned by {@link parseMessage} - * @returns { Boolean } Returns `true` or `false` depending on - * whether a message was retracted or not. - */ - async handleRetraction(attrs) { - const RETRACTION_ATTRIBUTES = ['retracted', 'retracted_id', 'editable']; - - if (attrs.retracted) { - if (attrs.is_tombstone) { - return false; - } - - const message = this.messages.findWhere({ - 'origin_id': attrs.retracted_id, - 'from': attrs.from - }); - - if (!message) { - attrs['dangling_retraction'] = true; - await this.createMessage(attrs); - return true; - } - - message.save(lodash_es_pick(attrs, RETRACTION_ATTRIBUTES)); - return true; - } else { - // Check if we have dangling retraction - const message = this.findDanglingRetraction(attrs); - - if (message) { - const retraction_attrs = lodash_es_pick(message.attributes, RETRACTION_ATTRIBUTES); - const new_attrs = Object.assign({ - 'dangling_retraction': false - }, attrs, retraction_attrs); - delete new_attrs['id']; // Delete id, otherwise a new cache entry gets created - - message.save(new_attrs); - return true; - } - } - - return false; - }, - - /** - * Determines whether the passed in message attributes represent a - * message which corrects a previously received message, or an - * older message which has already been corrected. - * In both cases, update the corrected message accordingly. - * @private - * @method _converse.ChatBox#handleCorrection - * @param { object } attrs - Attributes representing a received - * message, as returned by {@link parseMessage} - * @returns { _converse.Message|undefined } Returns the corrected - * message or `undefined` if not applicable. - */ - handleCorrection(attrs) { - if (!attrs.replace_id || !attrs.from) { - return; - } - - const message = this.messages.findWhere({ - 'msgid': attrs.replace_id, - 'from': attrs.from - }); - - if (!message) { - return; - } - - const older_versions = message.get('older_versions') || {}; - - if (attrs.time < message.get('time') && message.get('edited')) { - // This is an older message which has been corrected afterwards - older_versions[attrs.time] = attrs['message']; - message.save({ - 'older_versions': older_versions - }); - } else { - // This is a correction of an earlier message we already received - if (Object.keys(older_versions).length) { - older_versions[message.get('edited')] = message.get('message'); - } else { - older_versions[message.get('time')] = message.get('message'); - } - - attrs = Object.assign(attrs, { - 'older_versions': older_versions - }); - delete attrs['id']; // Delete id, otherwise a new cache entry gets created - - attrs['time'] = message.get('time'); - message.save(attrs); - } - - return message; - }, - - /** - * Returns an already cached message (if it exists) based on the - * passed in attributes map. - * @private - * @method _converse.ChatBox#getDuplicateMessage - * @param { object } attrs - Attributes representing a received - * message, as returned by {@link parseMessage} - * @returns {Promise<_converse.Message>} - */ - getDuplicateMessage(attrs) { - const queries = [...this.getStanzaIdQueryAttrs(attrs), this.getOriginIdQueryAttrs(attrs), this.getMessageBodyQueryAttrs(attrs)].filter(s => s); - const msgs = this.messages.models; - return msgs.find(m => queries.reduce((out, q) => out || lodash_es_isMatch(m.attributes, q), false)); - }, - - getOriginIdQueryAttrs(attrs) { - return attrs.origin_id && { - 'origin_id': attrs.origin_id, - 'from': attrs.from - }; - }, - - getStanzaIdQueryAttrs(attrs) { - const keys = Object.keys(attrs).filter(k => k.startsWith('stanza_id ')); - return keys.map(key => { - const by_jid = key.replace(/^stanza_id /, ''); - const query = {}; - query[`stanza_id ${by_jid}`] = attrs[key]; - return query; - }); - }, - - getMessageBodyQueryAttrs(attrs) { - if (attrs.message && attrs.msgid) { - const query = { - 'from': attrs.from, - 'msgid': attrs.msgid - }; - - if (!attrs.is_encrypted) { - // We can't match the message if it's a reflected - // encrypted message (e.g. via MAM or in a MUC) - query['message'] = attrs.message; - } - - return query; - } - }, - - /** - * Retract one of your messages in this chat - * @private - * @method _converse.ChatBoxView#retractOwnMessage - * @param { _converse.Message } message - The message which we're retracting. - */ - retractOwnMessage(message) { - this.sendRetractionMessage(message); - message.save({ - 'retracted': new Date().toISOString(), - 'retracted_id': message.get('origin_id'), - 'retraction_id': message.get('id'), - 'is_ephemeral': true, - 'editable': false - }); - }, - - /** - * Sends a message stanza to retract a message in this chat - * @private - * @method _converse.ChatBox#sendRetractionMessage - * @param { _converse.Message } message - The message which we're retracting. - */ - sendRetractionMessage(message) { - const origin_id = message.get('origin_id'); - - if (!origin_id) { - throw new Error("Can't retract message without a XEP-0359 Origin ID"); - } - - const msg = model_$msg({ - 'id': model_u.getUniqueId(), - 'to': this.get('jid'), - 'type': "chat" - }).c('store', { - xmlns: model_Strophe.NS.HINTS - }).up().c("apply-to", { - 'id': origin_id, - 'xmlns': model_Strophe.NS.FASTEN - }).c('retract', { - xmlns: model_Strophe.NS.RETRACT - }); - return shared_converse.connection.send(msg); - }, - - /** - * Finds the last eligible message and then sends a XEP-0333 chat marker for it. - * @param { ('received'|'displayed'|'acknowledged') } [type='displayed'] - * @param { Boolean } force - Whether a marker should be sent for the - * message, even if it didn't include a `markable` element. - */ - sendMarkerForLastMessage(type = 'displayed', force = false) { - const msgs = Array.from(this.messages.models); - msgs.reverse(); - const msg = msgs.find(m => m.get('sender') === 'them' && (force || m.get('is_markable'))); - msg && this.sendMarkerForMessage(msg, type, force); - }, - - /** - * Given the passed in message object, send a XEP-0333 chat marker. - * @param { _converse.Message } msg - * @param { ('received'|'displayed'|'acknowledged') } [type='displayed'] - * @param { Boolean } force - Whether a marker should be sent for the - * message, even if it didn't include a `markable` element. - */ - sendMarkerForMessage(msg, type = 'displayed', force = false) { - if (!msg || !api.settings.get('send_chat_markers').includes(type)) { - return; - } - - if (msg !== null && msg !== void 0 && msg.get('is_markable') || force) { - const from_jid = model_Strophe.getBareJidFromJid(msg.get('from')); - sendMarker(from_jid, msg.get('msgid'), type, msg.get('type')); - } - }, - - handleChatMarker(attrs) { - const to_bare_jid = model_Strophe.getBareJidFromJid(attrs.to); - - if (to_bare_jid !== shared_converse.bare_jid) { - return false; - } - - if (attrs.is_markable) { - if (this.contact && !attrs.is_archived && !attrs.is_carbon) { - sendMarker(attrs.from, attrs.msgid, 'received'); - } - - return false; - } else if (attrs.marker_id) { - const message = this.messages.findWhere({ - 'msgid': attrs.marker_id - }); - const field_name = `marker_${attrs.marker}`; - - if (message && !message.get(field_name)) { - message.save({ - field_name: new Date().toISOString() - }); - } - - return true; - } - }, - - sendReceiptStanza(to_jid, id) { - const receipt_stanza = model_$msg({ - 'from': shared_converse.connection.jid, - 'id': model_u.getUniqueId(), - 'to': to_jid, - 'type': 'chat' - }).c('received', { - 'xmlns': model_Strophe.NS.RECEIPTS, - 'id': id - }).up().c('store', { - 'xmlns': model_Strophe.NS.HINTS - }).up(); - api.send(receipt_stanza); - }, - - handleReceipt(attrs) { - if (attrs.sender === 'them') { - if (attrs.is_valid_receipt_request) { - this.sendReceiptStanza(attrs.from, attrs.msgid); - } else if (attrs.receipt_id) { - const message = this.messages.findWhere({ - 'msgid': attrs.receipt_id - }); - - if (message && !message.get('received')) { - message.save({ - 'received': new Date().toISOString() - }); - } - - return true; - } - } - - return false; - }, - - /** - * Given a {@link _converse.Message} return the XML stanza that represents it. - * @private - * @method _converse.ChatBox#createMessageStanza - * @param { _converse.Message } message - The message object - */ - createMessageStanza(message) { - const stanza = model_$msg({ - 'from': shared_converse.connection.jid, - 'to': this.get('jid'), - 'type': this.get('message_type'), - 'id': message.get('edited') && model_u.getUniqueId() || message.get('msgid') - }).c('body').t(message.get('message')).up().c(shared_converse.ACTIVE, { - 'xmlns': model_Strophe.NS.CHATSTATES - }).root(); - - if (message.get('type') === 'chat') { - stanza.c('request', { - 'xmlns': model_Strophe.NS.RECEIPTS - }).root(); - } - - if (message.get('is_spoiler')) { - if (message.get('spoiler_hint')) { - stanza.c('spoiler', { - 'xmlns': model_Strophe.NS.SPOILER - }, message.get('spoiler_hint')).root(); - } else { - stanza.c('spoiler', { - 'xmlns': model_Strophe.NS.SPOILER - }).root(); - } - } - - (message.get('references') || []).forEach(reference => { - const attrs = { - 'xmlns': model_Strophe.NS.REFERENCE, - 'begin': reference.begin, - 'end': reference.end, - 'type': reference.type - }; - - if (reference.uri) { - attrs.uri = reference.uri; - } - - stanza.c('reference', attrs).root(); - }); - - if (message.get('oob_url')) { - stanza.c('x', { - 'xmlns': model_Strophe.NS.OUTOFBAND - }).c('url').t(message.get('oob_url')).root(); - } - - if (message.get('edited')) { - stanza.c('replace', { - 'xmlns': model_Strophe.NS.MESSAGE_CORRECT, - 'id': message.get('msgid') - }).root(); - } - - if (message.get('origin_id')) { - stanza.c('origin-id', { - 'xmlns': model_Strophe.NS.SID, - 'id': message.get('origin_id') - }).root(); - } - - return stanza; - }, - - getOutgoingMessageAttributes(attrs) { - const is_spoiler = !!this.get('composing_spoiler'); - const origin_id = model_u.getUniqueId(); - const text = attrs === null || attrs === void 0 ? void 0 : attrs.body; - const body = text ? model_u.httpToGeoUri(model_u.shortnamesToUnicode(text), shared_converse) : undefined; - return Object.assign({}, attrs, { - 'from': shared_converse.bare_jid, - 'fullname': shared_converse.xmppstatus.get('fullname'), - 'id': origin_id, - 'is_only_emojis': text ? model_u.isOnlyEmojis(text) : false, - 'jid': this.get('jid'), - 'message': body, - 'msgid': origin_id, - 'nickname': this.get('nickname'), - 'sender': 'me', - 'time': new Date().toISOString(), - 'type': this.get('message_type'), - body, - is_spoiler, - origin_id - }, getMediaURLs(text)); - }, - - /** - * Responsible for setting the editable attribute of messages. - * If api.settings.get('allow_message_corrections') is "last", then only the last - * message sent from me will be editable. If set to "all" all messages - * will be editable. Otherwise no messages will be editable. - * @method _converse.ChatBox#setEditable - * @memberOf _converse.ChatBox - * @param { Object } attrs An object containing message attributes. - * @param { String } send_time - time when the message was sent - */ - setEditable(attrs, send_time) { - if (attrs.is_headline || model_u.isEmptyMessage(attrs) || attrs.sender !== 'me') { - return; - } - - if (api.settings.get('allow_message_corrections') === 'all') { - attrs.editable = !(attrs.file || attrs.retracted || 'oob_url' in attrs); - } else if (api.settings.get('allow_message_corrections') === 'last' && send_time > this.get('time_sent')) { - this.set({ - 'time_sent': send_time - }); - const msg = this.messages.findWhere({ - 'editable': true - }); - - if (msg) { - msg.save({ - 'editable': false - }); - } - - attrs.editable = !(attrs.file || attrs.retracted || 'oob_url' in attrs); - } - }, - - /** - * Queue the creation of a message, to make sure that we don't run - * into a race condition whereby we're creating a new message - * before the collection has been fetched. - * @async - * @private - * @method _converse.ChatBox#queueMessageCreation - * @param { Object } attrs - */ - async createMessage(attrs, options) { - attrs.time = attrs.time || new Date().toISOString(); - await this.messages.fetched; - return this.messages.create(attrs, options); - }, - - /** - * Responsible for sending off a text message inside an ongoing chat conversation. - * @private - * @method _converse.ChatBox#sendMessage - * @memberOf _converse.ChatBox - * @param { Object } [attrs] - A map of attributes to be saved on the message - * @returns { _converse.Message } - * @example - * const chat = api.chats.get('buddy1@example.org'); - * chat.sendMessage({'body': 'hello world'}); - */ - async sendMessage(attrs) { - attrs = this.getOutgoingMessageAttributes(attrs); - let message = this.messages.findWhere('correcting'); - - if (message) { - const older_versions = message.get('older_versions') || {}; - older_versions[message.get('time')] = message.get('message'); - message.save({ - 'correcting': false, - 'edited': new Date().toISOString(), - 'message': attrs.message, - 'older_versions': older_versions, - 'references': attrs.references, - 'is_only_emojis': attrs.is_only_emojis, - 'origin_id': model_u.getUniqueId(), - 'received': undefined - }); - } else { - this.setEditable(attrs, new Date().toISOString()); - message = await this.createMessage(attrs); - } - - api.send(this.createMessageStanza(message)); - /** - * Triggered when a message is being sent out - * @event _converse#sendMessage - * @type { Object } - * @param { Object } data - * @property { (_converse.ChatBox | _converse.ChatRoom) } data.chatbox - * @property { (_converse.Message | _converse.ChatRoomMessage) } data.message - */ - - api.trigger('sendMessage', { - 'chatbox': this, - message - }); - return message; - }, - - /** - * Sends a message with the current XEP-0085 chat state of the user - * as taken from the `chat_state` attribute of the {@link _converse.ChatBox}. - * @private - * @method _converse.ChatBox#sendChatState - */ - sendChatState() { - if (api.settings.get('send_chat_state_notifications') && this.get('chat_state')) { - const allowed = api.settings.get('send_chat_state_notifications'); - - if (Array.isArray(allowed) && !allowed.includes(this.get('chat_state'))) { - return; - } - - api.send(model_$msg({ - 'id': model_u.getUniqueId(), - 'to': this.get('jid'), - 'type': 'chat' - }).c(this.get('chat_state'), { - 'xmlns': model_Strophe.NS.CHATSTATES - }).up().c('no-store', { - 'xmlns': model_Strophe.NS.HINTS - }).up().c('no-permanent-store', { - 'xmlns': model_Strophe.NS.HINTS - })); - } - }, - - async sendFiles(files) { - var _maxFileSize; - - const { - __ - } = shared_converse; - const result = await api.disco.features.get(model_Strophe.NS.HTTPUPLOAD, shared_converse.domain); - const item = result.pop(); - - if (!item) { - this.createMessage({ - 'message': __("Sorry, looks like file upload is not supported by your server."), - 'type': 'error', - 'is_ephemeral': true - }); - return; - } - - const data = item.dataforms.where({ - 'FORM_TYPE': { - 'value': model_Strophe.NS.HTTPUPLOAD, - 'type': "hidden" - } - }).pop(); - const max_file_size = window.parseInt((_maxFileSize = ((data === null || data === void 0 ? void 0 : data.attributes) || {})['max-file-size']) === null || _maxFileSize === void 0 ? void 0 : _maxFileSize.value); - const slot_request_url = item === null || item === void 0 ? void 0 : item.id; - - if (!slot_request_url) { - this.createMessage({ - 'message': __("Sorry, looks like file upload is not supported by your server."), - 'type': 'error', - 'is_ephemeral': true - }); - return; - } - - Array.from(files).forEach(async file => { - /** - * *Hook* which allows plugins to transform files before they'll be - * uploaded. The main use-case is to encrypt the files. - * @event _converse#beforeFileUpload - */ - file = await api.hook('beforeFileUpload', this, file); - - if (!window.isNaN(max_file_size) && window.parseInt(file.size) > max_file_size) { - return this.createMessage({ - 'message': __('The size of your file, %1$s, exceeds the maximum allowed by your server, which is %2$s.', file.name, filesize_min_default()(max_file_size)), - 'type': 'error', - 'is_ephemeral': true - }); - } else { - const attrs = Object.assign(this.getOutgoingMessageAttributes(), { - 'file': true, - 'progress': 0, - 'slot_request_url': slot_request_url - }); - this.setEditable(attrs, new Date().toISOString()); - const message = await this.createMessage(attrs, { - 'silent': true - }); - message.file = file; - this.messages.trigger('add', message); - message.getRequestSlotURL(); - } - }); - }, - - maybeShow(force) { - if (shared_converse.isUniView()) { - const filter = c => !c.get('hidden') && c.get('jid') !== this.get('jid') && c.get('id') !== 'controlbox'; - - const other_chats = shared_converse.chatboxes.filter(filter); - - if (force || other_chats.length === 0) { - // We only have one chat visible at any one time. - // So before opening a chat, we make sure all other chats are hidden. - other_chats.forEach(c => model_u.safeSave(c, { - 'hidden': true - })); - model_u.safeSave(this, { - 'hidden': false - }); - } - - return; - } - - model_u.safeSave(this, { - 'hidden': false - }); - this.trigger('show'); - return this; - }, - - /** - * Indicates whether the chat is hidden and therefore - * whether a newly received message will be visible - * to the user or not. - * @returns {boolean} - */ - isHidden() { - // Note: This methods gets overridden by converse-minimize - return this.get('hidden') || this.isScrolledUp() || shared_converse.windowState === 'hidden'; - }, - - /** - * Given a newly received {@link _converse.Message} instance, - * update the unread counter if necessary. - * @private - * @method _converse.ChatBox#handleUnreadMessage - * @param {_converse.Message} message - */ - handleUnreadMessage(message) { - if (!(message !== null && message !== void 0 && message.get('body'))) { - return; - } - - if (model_u.isNewMessage(message)) { - if (message.get('sender') === 'me') { - // We remove the "scrolled" flag so that the chat area - // gets scrolled down. We always want to scroll down - // when the user writes a message as opposed to when a - // message is received. - this.ui.set('scrolled', false); - } else if (this.isHidden()) { - this.incrementUnreadMsgsCounter(message); - } else { - this.sendMarkerForMessage(message); - } - } - }, - - incrementUnreadMsgsCounter(message) { - const settings = { - 'num_unread': this.get('num_unread') + 1 - }; - - if (this.get('num_unread') === 0) { - settings['first_unread_id'] = message.get('id'); - } - - this.save(settings); - }, - - clearUnreadMsgCounter() { - if (this.get('num_unread') > 0) { - this.sendMarkerForMessage(this.messages.last()); - } - - model_u.safeSave(this, { - 'num_unread': 0 - }); - }, - - isScrolledUp() { - return this.ui.get('scrolled'); - } - -}); -/* harmony default export */ const model = (ChatBox); -;// CONCATENATED MODULE: ./src/headless/plugins/chat/message.js - - - - - -const message_u = core_converse.env.utils; -const { - Strophe: message_Strophe -} = core_converse.env; -/** - * Mixin which turns a `ModelWithContact` model into a non-MUC message. These can be either `chat` messages or `headline` messages. - * @mixin - * @namespace _converse.Message - * @memberOf _converse - * @example const msg = new _converse.Message({'message': 'hello world!'}); - */ - -const MessageMixin = { - defaults() { - return { - 'msgid': message_u.getUniqueId(), - 'time': new Date().toISOString(), - 'is_ephemeral': false - }; - }, - - async initialize() { - if (!this.checkValidity()) { - return; - } - - this.initialized = getOpenPromise(); - - if (this.get('type') === 'chat') { - model_with_contact.prototype.initialize.apply(this, arguments); - this.setRosterContact(message_Strophe.getBareJidFromJid(this.get('from'))); - } - - if (this.get('file')) { - this.on('change:put', this.uploadFile, this); - } - - this.setTimerForEphemeralMessage(); - /** - * Triggered once a {@link _converse.Message} has been created and initialized. - * @event _converse#messageInitialized - * @type { _converse.Message} - * @example _converse.api.listen.on('messageInitialized', model => { ... }); - */ - - await api.trigger('messageInitialized', this, { - 'Synchronous': true - }); - this.initialized.resolve(); - }, - - /** - * Sets an auto-destruct timer for this message, if it's is_ephemeral. - * @private - * @method _converse.Message#setTimerForEphemeralMessage - * @returns { Boolean } - Indicates whether the message is - * ephemeral or not, and therefore whether the timer was set or not. - */ - setTimerForEphemeralMessage() { - const setTimer = () => { - this.ephemeral_timer = window.setTimeout(this.safeDestroy.bind(this), 10000); - }; - - if (this.isEphemeral()) { - setTimer(); - return true; - } else { - this.on('change:is_ephemeral', () => this.isEphemeral() ? setTimer() : clearTimeout(this.ephemeral_timer)); - return false; - } - }, - - checkValidity() { - if (Object.keys(this.attributes).length === 3) { - // XXX: This is an empty message with only the 3 default values. - // This seems to happen when saving a newly created message - // fails for some reason. - // TODO: This is likely fixable by setting `wait` when - // creating messages. See the wait-for-messages branch. - this.validationError = 'Empty message'; - this.safeDestroy(); - return false; - } - - return true; - }, - - /** - * Determines whether this messsage may be retracted by the current user. - * @private - * @method _converse.Messages#mayBeRetracted - * @returns { Boolean } - */ - mayBeRetracted() { - const is_own_message = this.get('sender') === 'me'; - const not_canceled = this.get('error_type') !== 'cancel'; - return is_own_message && not_canceled && ['all', 'own'].includes(api.settings.get('allow_message_retraction')); - }, - - safeDestroy() { - try { - this.destroy(); - } catch (e) { - headless_log.error(e); - } - }, - - /** - * Returns a boolean indicating whether this message is ephemeral, - * meaning it will get automatically removed after ten seconds. - * @returns { boolean } - */ - isEphemeral() { - return this.get('is_ephemeral'); - }, - - /** - * Returns a boolean indicating whether this message is a XEP-0245 /me command. - * @returns { boolean } - */ - isMeCommand() { - const text = this.getMessageText(); - - if (!text) { - return false; - } - - return text.startsWith('/me '); - }, - - /** - * Returns a boolean indicating whether this message is considered a followup - * message from the previous one. Followup messages are shown grouped together - * under one author heading. - * A message is considered a followup of it's predecessor when it's a chat - * message from the same author, within 10 minutes. - * @returns { boolean } - */ - isFollowup() { - const messages = this.collection.models; - const idx = messages.indexOf(this); - const prev_model = idx ? messages[idx - 1] : null; - - if (prev_model === null) { - return false; - } - - const date = dayjs_min_default()(this.get('time')); - return this.get('from') === prev_model.get('from') && !this.isMeCommand() && !prev_model.isMeCommand() && this.get('type') !== 'info' && prev_model.get('type') !== 'info' && date.isBefore(dayjs_min_default()(prev_model.get('time')).add(10, 'minutes')) && !!this.get('is_encrypted') === !!prev_model.get('is_encrypted'); - }, - - getDisplayName() { - if (this.get('type') === 'groupchat') { - return this.get('nick'); - } else if (this.contact) { - return this.contact.getDisplayName(); - } else if (this.vcard) { - return this.vcard.getDisplayName(); - } else { - return this.get('from'); - } - }, - - getMessageText() { - const { - __ - } = shared_converse; - - if (this.get('is_encrypted')) { - return this.get('plaintext') || this.get('body') || __('Undecryptable OMEMO message'); - } - - return this.get('message'); - }, - - /** - * Send out an IQ stanza to request a file upload slot. - * https://xmpp.org/extensions/xep-0363.html#request - * @private - * @method _converse.Message#sendSlotRequestStanza - */ - sendSlotRequestStanza() { - if (!this.file) { - return Promise.reject(new Error('file is undefined')); - } - - const iq = core_converse.env.$iq({ - 'from': shared_converse.jid, - 'to': this.get('slot_request_url'), - 'type': 'get' - }).c('request', { - 'xmlns': message_Strophe.NS.HTTPUPLOAD, - 'filename': this.file.name, - 'size': this.file.size, - 'content-type': this.file.type - }); - return api.sendIQ(iq); - }, - - async getRequestSlotURL() { - const { - __ - } = shared_converse; - let stanza; - - try { - stanza = await this.sendSlotRequestStanza(); - } catch (e) { - headless_log.error(e); - return this.save({ - 'type': 'error', - 'message': __('Sorry, could not determine upload URL.'), - 'is_ephemeral': true - }); - } - - const slot = stanza.querySelector('slot'); - - if (slot) { - this.save({ - 'get': slot.querySelector('get').getAttribute('url'), - 'put': slot.querySelector('put').getAttribute('url') - }); - } else { - return this.save({ - 'type': 'error', - 'message': __('Sorry, could not determine file upload URL.'), - 'is_ephemeral': true - }); - } - }, - - uploadFile() { - const xhr = new XMLHttpRequest(); - - xhr.onreadystatechange = async () => { - if (xhr.readyState === XMLHttpRequest.DONE) { - headless_log.info('Status: ' + xhr.status); - - if (xhr.status === 200 || xhr.status === 201) { - let attrs = { - 'upload': shared_converse.SUCCESS, - 'oob_url': this.get('get'), - 'message': this.get('get'), - 'body': this.get('get') - }; - /** - * *Hook* which allows plugins to change the attributes - * saved on the message once a file has been uploaded. - * @event _converse#afterFileUploaded - */ - - attrs = await api.hook('afterFileUploaded', this, attrs); - this.save(attrs); - } else { - xhr.onerror(); - } - } - }; - - xhr.upload.addEventListener('progress', evt => { - if (evt.lengthComputable) { - this.set('progress', evt.loaded / evt.total); - } - }, false); - - xhr.onerror = () => { - const { - __ - } = shared_converse; - let message; - - if (xhr.responseText) { - message = __('Sorry, could not succesfully upload your file. Your server’s response: "%1$s"', xhr.responseText); - } else { - message = __('Sorry, could not succesfully upload your file.'); - } - - this.save({ - 'type': 'error', - 'upload': shared_converse.FAILURE, - 'message': message, - 'is_ephemeral': true - }); - }; - - xhr.open('PUT', this.get('put'), true); - xhr.setRequestHeader('Content-type', this.file.type); - xhr.send(this.file); - } - -}; -/* harmony default export */ const message = (MessageMixin); -;// CONCATENATED MODULE: ./src/headless/plugins/chat/api.js - - -/* harmony default export */ const chat_api = ({ - /** - * The "chats" namespace (used for one-on-one chats) - * - * @namespace api.chats - * @memberOf api - */ - chats: { - /** - * @method api.chats.create - * @param {string|string[]} jid|jids An jid or array of jids - * @param {object} [attrs] An object containing configuration attributes. - */ - async create(jids, attrs) { - if (typeof jids === 'string') { - if (attrs && !(attrs !== null && attrs !== void 0 && attrs.fullname)) { - var _contact$attributes; - - const contact = await api.contacts.get(jids); - attrs.fullname = contact === null || contact === void 0 ? void 0 : (_contact$attributes = contact.attributes) === null || _contact$attributes === void 0 ? void 0 : _contact$attributes.fullname; - } - - const chatbox = api.chats.get(jids, attrs, true); - - if (!chatbox) { - headless_log.error("Could not open chatbox for JID: " + jids); - return; - } - - return chatbox; - } - - if (Array.isArray(jids)) { - return Promise.all(jids.forEach(async jid => { - var _contact$attributes2; - - const contact = await api.contacts.get(jids); - attrs.fullname = contact === null || contact === void 0 ? void 0 : (_contact$attributes2 = contact.attributes) === null || _contact$attributes2 === void 0 ? void 0 : _contact$attributes2.fullname; - return api.chats.get(jid, attrs, true).maybeShow(); - })); - } - - headless_log.error("chats.create: You need to provide at least one JID"); - return null; - }, - - /** - * Opens a new one-on-one chat. - * - * @method api.chats.open - * @param {String|string[]} name - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com'] - * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model. - * @param {Boolean} [attrs.minimized] - Should the chat be created in minimized state. - * @param {Boolean} [force=false] - By default, a minimized - * chat won't be maximized (in `overlayed` view mode) and in - * `fullscreen` view mode a newly opened chat won't replace - * another chat already in the foreground. - * Set `force` to `true` if you want to force the chat to be - * maximized or shown. - * @returns {Promise} Promise which resolves with the - * _converse.ChatBox representing the chat. - * - * @example - * // To open a single chat, provide the JID of the contact you're chatting with in that chat: - * converse.plugins.add('myplugin', { - * initialize: function() { - * const _converse = this._converse; - * // Note, buddy@example.org must be in your contacts roster! - * api.chats.open('buddy@example.com').then(chat => { - * // Now you can do something with the chat model - * }); - * } - * }); - * - * @example - * // To open an array of chats, provide an array of JIDs: - * converse.plugins.add('myplugin', { - * initialize: function () { - * const _converse = this._converse; - * // Note, these users must first be in your contacts roster! - * api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then(chats => { - * // Now you can do something with the chat models - * }); - * } - * }); - */ - async open(jids, attrs, force) { - if (typeof jids === 'string') { - const chat = await api.chats.get(jids, attrs, true); - - if (chat) { - return chat.maybeShow(force); - } - - return chat; - } else if (Array.isArray(jids)) { - return Promise.all(jids.map(j => api.chats.get(j, attrs, true).then(c => c && c.maybeShow(force))).filter(c => c)); - } - - const err_msg = "chats.open: You need to provide at least one JID"; - headless_log.error(err_msg); - throw new Error(err_msg); - }, - - /** - * Retrieves a chat or all chats. - * - * @method api.chats.get - * @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com'] - * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model. - * @param {Boolean} [create=false] - Whether the chat should be created if it's not found. - * @returns { Promise<_converse.ChatBox> } - * - * @example - * // To return a single chat, provide the JID of the contact you're chatting with in that chat: - * const model = await api.chats.get('buddy@example.com'); - * - * @example - * // To return an array of chats, provide an array of JIDs: - * const models = await api.chats.get(['buddy1@example.com', 'buddy2@example.com']); - * - * @example - * // To return all open chats, call the method without any parameters:: - * const models = await api.chats.get(); - * - */ - async get(jids, attrs = {}, create = false) { - await api.waitUntil('chatBoxesFetched'); - - async function _get(jid) { - let model = await api.chatboxes.get(jid); - - if (!model && create) { - model = await api.chatboxes.create(jid, attrs, shared_converse.ChatBox); - } else { - model = model && model.get('type') === shared_converse.PRIVATE_CHAT_TYPE ? model : null; - - if (model && Object.keys(attrs).length) { - model.save(attrs); - } - } - - return model; - } - - if (jids === undefined) { - const chats = await api.chatboxes.get(); - return chats.filter(c => c.get('type') === shared_converse.PRIVATE_CHAT_TYPE); - } else if (typeof jids === 'string') { - return _get(jids); - } - - return Promise.all(jids.map(jid => _get(jid))); - } - - } -}); -;// CONCATENATED MODULE: ./src/headless/plugins/chat/utils.js - - - - -const { - Strophe: utils_Strophe, - sizzle: utils_sizzle, - u: chat_utils_u -} = core_converse.env; -function openChat(jid) { - if (!chat_utils_u.isValidJID(jid)) { - return headless_log.warn(`Invalid JID "${jid}" provided in URL fragment`); - } - - api.chats.open(jid); -} -async function onClearSession() { - if (shared_converse.shouldClearCache()) { - await Promise.all(shared_converse.chatboxes.map(c => c.messages && c.messages.clearStore({ - 'silent': true - }))); - - const filter = o => o.get('type') !== shared_converse.CONTROLBOX_TYPE; - - shared_converse.chatboxes.clearStore({ - 'silent': true - }, filter); - } -} - -async function handleErrorMessage(stanza) { - const from_jid = utils_Strophe.getBareJidFromJid(stanza.getAttribute('from')); - - if (chat_utils_u.isSameBareJID(from_jid, shared_converse.bare_jid)) { - return; - } - - const chatbox = await api.chatboxes.get(from_jid); - - if (chatbox.get('type') === shared_converse.PRIVATE_CHAT_TYPE) { - chatbox === null || chatbox === void 0 ? void 0 : chatbox.handleErrorMessageStanza(stanza); - } -} - -function autoJoinChats() { - // Automatically join private chats, based on the - // "auto_join_private_chats" configuration setting. - api.settings.get('auto_join_private_chats').forEach(jid => { - if (shared_converse.chatboxes.where({ - 'jid': jid - }).length) { - return; - } - - if (typeof jid === 'string') { - api.chats.open(jid); - } else { - headless_log.error('Invalid jid criteria specified for "auto_join_private_chats"'); - } - }); - /** - * Triggered once any private chats have been automatically joined as - * specified by the `auto_join_private_chats` setting. - * See: https://conversejs.org/docs/html/configuration.html#auto-join-private-chats - * @event _converse#privateChatsAutoJoined - * @example _converse.api.listen.on('privateChatsAutoJoined', () => { ... }); - * @example _converse.api.waitUntil('privateChatsAutoJoined').then(() => { ... }); - */ - - api.trigger('privateChatsAutoJoined'); -} -function registerMessageHandlers() { - shared_converse.connection.addHandler(stanza => { - if (utils_sizzle(`message > result[xmlns="${utils_Strophe.NS.MAM}"]`, stanza).pop()) { - // MAM messages are handled in converse-mam. - // We shouldn't get MAM messages here because - // they shouldn't have a `type` attribute. - headless_log.warn(`Received a MAM message with type "chat".`); - return true; - } - - shared_converse.handleMessageStanza(stanza); - - return true; - }, null, 'message', 'chat'); - - shared_converse.connection.addHandler(stanza => { - // Message receipts are usually without the `type` attribute. See #1353 - if (stanza.getAttribute('type') !== null) { - // TODO: currently Strophe has no way to register a handler - // for stanzas without a `type` attribute. - // We could update it to accept null to mean no attribute, - // but that would be a backward-incompatible change - return true; // Gets handled above. - } - - shared_converse.handleMessageStanza(stanza); - - return true; - }, utils_Strophe.NS.RECEIPTS, 'message'); - - shared_converse.connection.addHandler(stanza => { - handleErrorMessage(stanza); - return true; - }, null, 'message', 'error'); -} -/** - * Handler method for all incoming single-user chat "message" stanzas. - * @private - * @param { MessageAttributes } attrs - The message attributes - */ - -async function handleMessageStanza(stanza) { - if (isServerMessage(stanza)) { - // Prosody sends headline messages with type `chat`, so we need to filter them out here. - const from = stanza.getAttribute('from'); - return headless_log.info(`handleMessageStanza: Ignoring incoming server message from JID: ${from}`); - } - - const attrs = await parseMessage(stanza, shared_converse); - - if (chat_utils_u.isErrorObject(attrs)) { - attrs.stanza && headless_log.error(attrs.stanza); - return headless_log.error(attrs.message); - } - - const has_body = !!utils_sizzle(`body, encrypted[xmlns="${utils_Strophe.NS.OMEMO}"]`, stanza).length; - const chatbox = await api.chats.get(attrs.contact_jid, { - 'nickname': attrs.nick - }, has_body); - await (chatbox === null || chatbox === void 0 ? void 0 : chatbox.queueMessage(attrs)); - /** - * @typedef { Object } MessageData - * An object containing the original message stanza, as well as the - * parsed attributes. - * @property { XMLElement } stanza - * @property { MessageAttributes } stanza - * @property { ChatBox } chatbox - */ - - const data = { - stanza, - attrs, - chatbox - }; - /** - * Triggered when a message stanza is been received and processed. - * @event _converse#message - * @type { object } - * @property { module:converse-chat~MessageData } data - */ - - api.trigger('message', data); -} -;// CONCATENATED MODULE: ./src/headless/plugins/chat/index.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - -core_converse.plugins.add('converse-chat', { - /* Optional dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. They are called "optional" because they might not be - * available, in which case any overrides applicable to them will be - * ignored. - * - * It's possible however to make optional dependencies non-optional. - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ['converse-chatboxes', 'converse-disco'], - - initialize() { - // Configuration values for this plugin - // ==================================== - // Refer to docs/source/configuration.rst for explanations of these - // configuration settings. - api.settings.extend({ - 'allow_message_corrections': 'all', - 'allow_message_retraction': 'all', - 'allow_message_styling': true, - 'auto_join_private_chats': [], - 'clear_messages_on_reconnection': false, - 'filter_by_resource': false, - 'prune_messages_above': undefined, - 'pruning_behavior': 'unscrolled', - 'send_chat_markers': ["received", "displayed", "acknowledged"], - 'send_chat_state_notifications': true - }); - shared_converse.Message = model_with_contact.extend(message); - shared_converse.Messages = Collection.extend({ - model: shared_converse.Message, - comparator: 'time' - }); - Object.assign(shared_converse, { - ChatBox: model, - handleMessageStanza: handleMessageStanza - }); - Object.assign(api, chat_api); - - shared_converse.router.route('converse/chat?jid=:jid', openChat); - - api.listen.on('chatBoxesFetched', autoJoinChats); - api.listen.on('presencesInitialized', registerMessageHandlers); - api.listen.on('clearSession', onClearSession); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/disco/entity.js - - - - - - -const { - Strophe: entity_Strophe -} = core_converse.env; -/** - * @class - * @namespace _converse.DiscoEntity - * @memberOf _converse - * - * A Disco Entity is a JID addressable entity that can be queried for features. - * - * See XEP-0030: https://xmpp.org/extensions/xep-0030.html - */ - -const DiscoEntity = Model.extend({ - idAttribute: 'jid', - - initialize(attrs, options) { - this.waitUntilFeaturesDiscovered = getOpenPromise(); - this.dataforms = new Collection(); - let id = `converse.dataforms-${this.get('jid')}`; - this.dataforms.browserStorage = shared_converse.createStore(id, 'session'); - this.features = new Collection(); - id = `converse.features-${this.get('jid')}`; - this.features.browserStorage = shared_converse.createStore(id, 'session'); - this.listenTo(this.features, 'add', this.onFeatureAdded); - this.fields = new Collection(); - id = `converse.fields-${this.get('jid')}`; - this.fields.browserStorage = shared_converse.createStore(id, 'session'); - this.listenTo(this.fields, 'add', this.onFieldAdded); - this.identities = new Collection(); - id = `converse.identities-${this.get('jid')}`; - this.identities.browserStorage = shared_converse.createStore(id, 'session'); - this.fetchFeatures(options); - this.items = new shared_converse.DiscoEntities(); - id = `converse.disco-items-${this.get('jid')}`; - this.items.browserStorage = shared_converse.createStore(id, 'session'); - this.items.fetch(); - }, - - /** - * Returns a Promise which resolves with a map indicating - * whether a given identity is provided by this entity. - * @private - * @method _converse.DiscoEntity#getIdentity - * @param { String } category - The identity category - * @param { String } type - The identity type - */ - async getIdentity(category, type) { - await this.waitUntilFeaturesDiscovered; - return this.identities.findWhere({ - 'category': category, - 'type': type - }); - }, - - /** - * Returns a Promise which resolves with a map indicating - * whether a given feature is supported. - * @private - * @method _converse.DiscoEntity#hasFeature - * @param { String } feature - The feature that might be supported. - */ - async hasFeature(feature) { - await this.waitUntilFeaturesDiscovered; - - if (this.features.findWhere({ - 'var': feature - })) { - return this; - } - }, - - onFeatureAdded(feature) { - feature.entity = this; - /** - * Triggered when Converse has learned of a service provided by the XMPP server. - * See XEP-0030. - * @event _converse#serviceDiscovered - * @type { Model } - * @example _converse.api.listen.on('featuresDiscovered', feature => { ... }); - */ - - api.trigger('serviceDiscovered', feature); - }, - - onFieldAdded(field) { - field.entity = this; - /** - * Triggered when Converse has learned of a disco extension field. - * See XEP-0030. - * @event _converse#discoExtensionFieldDiscovered - * @example _converse.api.listen.on('discoExtensionFieldDiscovered', () => { ... }); - */ - - api.trigger('discoExtensionFieldDiscovered', field); - }, - - async fetchFeatures(options) { - if (options.ignore_cache) { - this.queryInfo(); - } else { - const store_id = this.features.browserStorage.name; - const result = await this.features.browserStorage.store.getItem(store_id); - - if (result && result.length === 0 || result === null) { - this.queryInfo(); - } else { - this.features.fetch({ - add: true, - success: () => { - this.waitUntilFeaturesDiscovered.resolve(this); - this.trigger('featuresDiscovered'); - } - }); - this.identities.fetch({ - add: true - }); - } - } - }, - - async queryInfo() { - let stanza; - - try { - stanza = await api.disco.info(this.get('jid'), null); - } catch (iq) { - iq === null ? headless_log.error(`Timeout for disco#info query for ${this.get('jid')}`) : headless_log.error(iq); - this.waitUntilFeaturesDiscovered.resolve(this); - return; - } - - this.onInfo(stanza); - }, - - onDiscoItems(stanza) { - sizzle_default()(`query[xmlns="${entity_Strophe.NS.DISCO_ITEMS}"] item`, stanza).forEach(item => { - if (item.getAttribute("node")) { - // XXX: Ignore nodes for now. - // See: https://xmpp.org/extensions/xep-0030.html#items-nodes - return; - } - - const jid = item.getAttribute('jid'); - - if (this.items.get(jid) === undefined) { - const entity = shared_converse.disco_entities.get(jid); - - if (entity) { - this.items.add(entity); - } else { - this.items.create({ - 'jid': jid - }); - } - } - }); - }, - - async queryForItems() { - if (this.identities.where({ - 'category': 'server' - }).length === 0) { - // Don't fetch features and items if this is not a - // server or a conference component. - return; - } - - const stanza = await api.disco.items(this.get('jid')); - this.onDiscoItems(stanza); - }, - - onInfo(stanza) { - Array.from(stanza.querySelectorAll('identity')).forEach(identity => { - this.identities.create({ - 'category': identity.getAttribute('category'), - 'type': identity.getAttribute('type'), - 'name': identity.getAttribute('name') - }); - }); - sizzle_default()(`x[type="result"][xmlns="${entity_Strophe.NS.XFORM}"]`, stanza).forEach(form => { - const data = {}; - sizzle_default()('field', form).forEach(field => { - var _field$querySelector; - - data[field.getAttribute('var')] = { - 'value': (_field$querySelector = field.querySelector('value')) === null || _field$querySelector === void 0 ? void 0 : _field$querySelector.textContent, - 'type': field.getAttribute('type') - }; - }); - this.dataforms.create(data); - }); - - if (stanza.querySelector(`feature[var="${entity_Strophe.NS.DISCO_ITEMS}"]`)) { - this.queryForItems(); - } - - Array.from(stanza.querySelectorAll('feature')).forEach(feature => { - this.features.create({ - 'var': feature.getAttribute('var'), - 'from': stanza.getAttribute('from') - }); - }); // XEP-0128 Service Discovery Extensions - - sizzle_default()('x[type="result"][xmlns="jabber:x:data"] field', stanza).forEach(field => { - var _field$querySelector2; - - this.fields.create({ - 'var': field.getAttribute('var'), - 'value': (_field$querySelector2 = field.querySelector('value')) === null || _field$querySelector2 === void 0 ? void 0 : _field$querySelector2.textContent, - 'from': stanza.getAttribute('from') - }); - }); - this.waitUntilFeaturesDiscovered.resolve(this); - this.trigger('featuresDiscovered'); - } - -}); -/* harmony default export */ const entity = (DiscoEntity); -;// CONCATENATED MODULE: ./src/headless/plugins/disco/entities.js - - - -const DiscoEntities = Collection.extend({ - model: entity, - - fetchEntities() { - return new Promise((resolve, reject) => { - this.fetch({ - add: true, - success: resolve, - - error(m, e) { - headless_log.error(e); - reject(new Error("Could not fetch disco entities")); - } - - }); - }); - } - -}); -/* harmony default export */ const entities = (DiscoEntities); -;// CONCATENATED MODULE: ./src/headless/plugins/disco/utils.js - - -const { - Strophe: disco_utils_Strophe, - $iq: utils_$iq -} = core_converse.env; - -function onDiscoInfoRequest(stanza) { - const node = stanza.getElementsByTagName('query')[0].getAttribute('node'); - const attrs = { - xmlns: disco_utils_Strophe.NS.DISCO_INFO - }; - - if (node) { - attrs.node = node; - } - - const iqresult = utils_$iq({ - 'type': 'result', - 'id': stanza.getAttribute('id') - }); - const from = stanza.getAttribute('from'); - - if (from !== null) { - iqresult.attrs({ - 'to': from - }); - } - - iqresult.c('query', attrs); - - shared_converse.disco._identities.forEach(identity => { - const attrs = { - 'category': identity.category, - 'type': identity.type - }; - - if (identity.name) { - attrs.name = identity.name; - } - - if (identity.lang) { - attrs['xml:lang'] = identity.lang; - } - - iqresult.c('identity', attrs).up(); - }); - - shared_converse.disco._features.forEach(feature => iqresult.c('feature', { - 'var': feature - }).up()); - - api.send(iqresult.tree()); - return true; -} - -function addClientFeatures() { - // See https://xmpp.org/registrar/disco-categories.html - api.disco.own.identities.add('client', 'web', 'Converse'); - api.disco.own.features.add(disco_utils_Strophe.NS.CHATSTATES); - api.disco.own.features.add(disco_utils_Strophe.NS.DISCO_INFO); - api.disco.own.features.add(disco_utils_Strophe.NS.ROSTERX); // Limited support - - if (api.settings.get("message_carbons")) { - api.disco.own.features.add(disco_utils_Strophe.NS.CARBONS); - } - /** - * Triggered in converse-disco once the core disco features of - * Converse have been added. - * @event _converse#addClientFeatures - * @example _converse.api.listen.on('addClientFeatures', () => { ... }); - */ - - - api.trigger('addClientFeatures'); - return this; -} - -async function initializeDisco() { - addClientFeatures(); - - shared_converse.connection.addHandler(stanza => onDiscoInfoRequest(stanza), disco_utils_Strophe.NS.DISCO_INFO, 'iq', 'get', null, null); - - shared_converse.disco_entities = new shared_converse.DiscoEntities(); - const id = `converse.disco-entities-${shared_converse.bare_jid}`; - shared_converse.disco_entities.browserStorage = shared_converse.createStore(id, 'session'); - const collection = await shared_converse.disco_entities.fetchEntities(); - - if (collection.length === 0 || !collection.get(shared_converse.domain)) { - // If we don't have an entity for our own XMPP server, - // create one. - shared_converse.disco_entities.create({ - 'jid': shared_converse.domain - }); - } - /** - * Triggered once the `converse-disco` plugin has been initialized and the - * `_converse.disco_entities` collection will be available and populated with at - * least the service discovery features of the user's own server. - * @event _converse#discoInitialized - * @example _converse.api.listen.on('discoInitialized', () => { ... }); - */ - - - api.trigger('discoInitialized'); -} -function initStreamFeatures() { - // Initialize the stream_features collection, and if we're - // re-attaching to a pre-existing BOSH session, we restore the - // features from cache. - // Otherwise the features will be created once we've received them - // from the server (see populateStreamFeatures). - if (!shared_converse.stream_features) { - const bare_jid = disco_utils_Strophe.getBareJidFromJid(shared_converse.jid); - const id = `converse.stream-features-${bare_jid}`; - api.promises.add('streamFeaturesAdded'); - shared_converse.stream_features = new Collection(); - shared_converse.stream_features.browserStorage = shared_converse.createStore(id, "session"); - } -} -function notifyStreamFeaturesAdded() { - /** - * Triggered as soon as the stream features are known. - * If you want to check whether a stream feature is supported before proceeding, - * then you'll first want to wait for this event. - * @event _converse#streamFeaturesAdded - * @example _converse.api.listen.on('streamFeaturesAdded', () => { ... }); - */ - api.trigger('streamFeaturesAdded'); -} -function populateStreamFeatures() { - // Strophe.js sets the element on the - // Strophe.Connection instance (_converse.connection). - // - // Once this is we populate the _converse.stream_features collection - // and trigger streamFeaturesAdded. - initStreamFeatures(); - Array.from(shared_converse.connection.features.childNodes).forEach(feature => { - shared_converse.stream_features.create({ - 'name': feature.nodeName, - 'xmlns': feature.getAttribute('xmlns') - }); - }); - notifyStreamFeaturesAdded(); -} -function utils_clearSession() { - var _converse$disco_entit, _converse$disco_entit2, _converse$disco_entit3, _converse$disco_entit4, _converse$disco_entit5; - - (_converse$disco_entit = shared_converse.disco_entities) === null || _converse$disco_entit === void 0 ? void 0 : _converse$disco_entit.forEach(e => e.features.clearStore()); - (_converse$disco_entit2 = shared_converse.disco_entities) === null || _converse$disco_entit2 === void 0 ? void 0 : _converse$disco_entit2.forEach(e => e.identities.clearStore()); - (_converse$disco_entit3 = shared_converse.disco_entities) === null || _converse$disco_entit3 === void 0 ? void 0 : _converse$disco_entit3.forEach(e => e.dataforms.clearStore()); - (_converse$disco_entit4 = shared_converse.disco_entities) === null || _converse$disco_entit4 === void 0 ? void 0 : _converse$disco_entit4.forEach(e => e.fields.clearStore()); - (_converse$disco_entit5 = shared_converse.disco_entities) === null || _converse$disco_entit5 === void 0 ? void 0 : _converse$disco_entit5.clearStore(); - delete shared_converse.disco_entities; -} -;// CONCATENATED MODULE: ./src/headless/plugins/disco/api.js - - - - -const { - Strophe: api_Strophe, - $iq: api_$iq -} = core_converse.env; -/* harmony default export */ const disco_api = ({ - /** - * The XEP-0030 service discovery API - * - * This API lets you discover information about entities on the - * XMPP network. - * - * @namespace api.disco - * @memberOf api - */ - disco: { - /** - * @namespace api.disco.stream - * @memberOf api.disco - */ - stream: { - /** - * @method api.disco.stream.getFeature - * @param {String} name The feature name - * @param {String} xmlns The XML namespace - * @example _converse.api.disco.stream.getFeature('ver', 'urn:xmpp:features:rosterver') - */ - async getFeature(name, xmlns) { - await api.waitUntil('streamFeaturesAdded'); - - if (!name || !xmlns) { - throw new Error("name and xmlns need to be provided when calling disco.stream.getFeature"); - } - - if (shared_converse.stream_features === undefined && !api.connection.connected()) { - // Happens during tests when disco lookups happen asynchronously after teardown. - const msg = `Tried to get feature ${name} ${xmlns} but _converse.stream_features has been torn down`; - headless_log.warn(msg); - return; - } - - return shared_converse.stream_features.findWhere({ - 'name': name, - 'xmlns': xmlns - }); - } - - }, - - /** - * @namespace api.disco.own - * @memberOf api.disco - */ - own: { - /** - * @namespace api.disco.own.identities - * @memberOf api.disco.own - */ - identities: { - /** - * Lets you add new identities for this client (i.e. instance of Converse) - * @method api.disco.own.identities.add - * - * @param {String} category - server, client, gateway, directory, etc. - * @param {String} type - phone, pc, web, etc. - * @param {String} name - "Converse" - * @param {String} lang - en, el, de, etc. - * - * @example _converse.api.disco.own.identities.clear(); - */ - add(category, type, name, lang) { - for (var i = 0; i < shared_converse.disco._identities.length; i++) { - if (shared_converse.disco._identities[i].category == category && shared_converse.disco._identities[i].type == type && shared_converse.disco._identities[i].name == name && shared_converse.disco._identities[i].lang == lang) { - return false; - } - } - - shared_converse.disco._identities.push({ - category: category, - type: type, - name: name, - lang: lang - }); - }, - - /** - * Clears all previously registered identities. - * @method api.disco.own.identities.clear - * @example _converse.api.disco.own.identities.clear(); - */ - clear() { - shared_converse.disco._identities = []; - }, - - /** - * Returns all of the identities registered for this client - * (i.e. instance of Converse). - * @method api.disco.identities.get - * @example const identities = api.disco.own.identities.get(); - */ - get() { - return shared_converse.disco._identities; - } - - }, - - /** - * @namespace api.disco.own.features - * @memberOf api.disco.own - */ - features: { - /** - * Lets you register new disco features for this client (i.e. instance of Converse) - * @method api.disco.own.features.add - * @param {String} name - e.g. http://jabber.org/protocol/caps - * @example _converse.api.disco.own.features.add("http://jabber.org/protocol/caps"); - */ - add(name) { - for (var i = 0; i < shared_converse.disco._features.length; i++) { - if (shared_converse.disco._features[i] == name) { - return false; - } - } - - shared_converse.disco._features.push(name); - }, - - /** - * Clears all previously registered features. - * @method api.disco.own.features.clear - * @example _converse.api.disco.own.features.clear(); - */ - clear() { - shared_converse.disco._features = []; - }, - - /** - * Returns all of the features registered for this client (i.e. instance of Converse). - * @method api.disco.own.features.get - * @example const features = api.disco.own.features.get(); - */ - get() { - return shared_converse.disco._features; - } - - } - }, - - /** - * Query for information about an XMPP entity - * - * @method api.disco.info - * @param {string} jid The Jabber ID of the entity to query - * @param {string} [node] A specific node identifier associated with the JID - * @returns {promise} Promise which resolves once we have a result from the server. - */ - info(jid, node) { - const attrs = { - xmlns: api_Strophe.NS.DISCO_INFO - }; - - if (node) { - attrs.node = node; - } - - const info = api_$iq({ - 'from': shared_converse.connection.jid, - 'to': jid, - 'type': 'get' - }).c('query', attrs); - return api.sendIQ(info); - }, - - /** - * Query for items associated with an XMPP entity - * - * @method api.disco.items - * @param {string} jid The Jabber ID of the entity to query for items - * @param {string} [node] A specific node identifier associated with the JID - * @returns {promise} Promise which resolves once we have a result from the server. - */ - items(jid, node) { - const attrs = { - 'xmlns': api_Strophe.NS.DISCO_ITEMS - }; - - if (node) { - attrs.node = node; - } - - return api.sendIQ(api_$iq({ - 'from': shared_converse.connection.jid, - 'to': jid, - 'type': 'get' - }).c('query', attrs)); - }, - - /** - * Namespace for methods associated with disco entities - * - * @namespace api.disco.entities - * @memberOf api.disco - */ - entities: { - /** - * Get the corresponding `DiscoEntity` instance. - * - * @method api.disco.entities.get - * @param {string} jid The Jabber ID of the entity - * @param {boolean} [create] Whether the entity should be created if it doesn't exist. - * @example _converse.api.disco.entities.get(jid); - */ - async get(jid, create = false) { - await api.waitUntil('discoInitialized'); - - if (!jid) { - return shared_converse.disco_entities; - } - - if (shared_converse.disco_entities === undefined && !api.connection.connected()) { - // Happens during tests when disco lookups happen asynchronously after teardown. - const msg = `Tried to look up entity ${jid} but _converse.disco_entities has been torn down`; - headless_log.warn(msg); - return; - } - - const entity = shared_converse.disco_entities.get(jid); - - if (entity || !create) { - return entity; - } - - return api.disco.entities.create(jid); - }, - - /** - * Create a new disco entity. It's identity and features - * will automatically be fetched from cache or from the - * XMPP server. - * - * Fetching from cache can be disabled by passing in - * `ignore_cache: true` in the options parameter. - * - * @method api.disco.entities.create - * @param {string} jid The Jabber ID of the entity - * @param {object} [options] Additional options - * @param {boolean} [options.ignore_cache] - * If true, fetch all features from the XMPP server instead of restoring them from cache - * @example _converse.api.disco.entities.create(jid, {'ignore_cache': true}); - */ - create(jid, options) { - return shared_converse.disco_entities.create({ - 'jid': jid - }, options); - } - - }, - - /** - * @namespace api.disco.features - * @memberOf api.disco - */ - features: { - /** - * Return a given feature of a disco entity - * - * @method api.disco.features.get - * @param {string} feature The feature that might be - * supported. In the XML stanza, this is the `var` - * attribute of the `` element. For - * example: `http://jabber.org/protocol/muc` - * @param {string} jid The JID of the entity - * (and its associated items) which should be queried - * @returns {promise} A promise which resolves with a list containing - * _converse.Entity instances representing the entity - * itself or those items associated with the entity if - * they support the given feature. - * @example - * api.disco.features.get(Strophe.NS.MAM, _converse.bare_jid); - */ - async get(feature, jid) { - if (!jid) { - throw new TypeError('You need to provide an entity JID'); - } - - await api.waitUntil('discoInitialized'); - let entity = await api.disco.entities.get(jid, true); - - if (shared_converse.disco_entities === undefined && !api.connection.connected()) { - // Happens during tests when disco lookups happen asynchronously after teardown. - const msg = `Tried to get feature ${feature} for ${jid} but _converse.disco_entities has been torn down`; - headless_log.warn(msg); - return; - } - - entity = await entity.waitUntilFeaturesDiscovered; - const promises = [...entity.items.map(i => i.hasFeature(feature)), entity.hasFeature(feature)]; - const result = await Promise.all(promises); - return result.filter(lodash_es_isObject); - } - - }, - - /** - * Used to determine whether an entity supports a given feature. - * - * @method api.disco.supports - * @param {string} feature The feature that might be - * supported. In the XML stanza, this is the `var` - * attribute of the `` element. For - * example: `http://jabber.org/protocol/muc` - * @param {string} jid The JID of the entity - * (and its associated items) which should be queried - * @returns {promise} A promise which resolves with `true` or `false`. - * @example - * if (await api.disco.supports(Strophe.NS.MAM, _converse.bare_jid)) { - * // The feature is supported - * } else { - * // The feature is not supported - * } - */ - async supports(feature, jid) { - const features = (await api.disco.features.get(feature, jid)) || []; - return features.length > 0; - }, - - /** - * Refresh the features, fields and identities associated with a - * disco entity by refetching them from the server - * @method api.disco.refresh - * @param {string} jid The JID of the entity whose features are refreshed. - * @returns {promise} A promise which resolves once the features have been refreshed - * @example - * await api.disco.refresh('room@conference.example.org'); - */ - async refresh(jid) { - if (!jid) { - throw new TypeError('api.disco.refresh: You need to provide an entity JID'); - } - - await api.waitUntil('discoInitialized'); - let entity = await api.disco.entities.get(jid); - - if (entity) { - entity.features.reset(); - entity.fields.reset(); - entity.identities.reset(); - - if (!entity.waitUntilFeaturesDiscovered.isPending) { - entity.waitUntilFeaturesDiscovered = getOpenPromise(); - } - - entity.queryInfo(); - } else { - // Create it if it doesn't exist - entity = await api.disco.entities.create(jid, { - 'ignore_cache': true - }); - } - - return entity.waitUntilFeaturesDiscovered; - }, - - /** - * @deprecated Use {@link api.disco.refresh} instead. - * @method api.disco.refreshFeatures - */ - refreshFeatures(jid) { - return api.refresh(jid); - }, - - /** - * Return all the features associated with a disco entity - * - * @method api.disco.getFeatures - * @param {string} jid The JID of the entity whose features are returned. - * @returns {promise} A promise which resolves with the returned features - * @example - * const features = await api.disco.getFeatures('room@conference.example.org'); - */ - async getFeatures(jid) { - if (!jid) { - throw new TypeError('api.disco.getFeatures: You need to provide an entity JID'); - } - - await api.waitUntil('discoInitialized'); - let entity = await api.disco.entities.get(jid, true); - entity = await entity.waitUntilFeaturesDiscovered; - return entity.features; - }, - - /** - * Return all the service discovery extensions fields - * associated with an entity. - * - * See [XEP-0129: Service Discovery Extensions](https://xmpp.org/extensions/xep-0128.html) - * - * @method api.disco.getFields - * @param {string} jid The JID of the entity whose fields are returned. - * @example - * const fields = await api.disco.getFields('room@conference.example.org'); - */ - async getFields(jid) { - if (!jid) { - throw new TypeError('api.disco.getFields: You need to provide an entity JID'); - } - - await api.waitUntil('discoInitialized'); - let entity = await api.disco.entities.get(jid, true); - entity = await entity.waitUntilFeaturesDiscovered; - return entity.fields; - }, - - /** - * Get the identity (with the given category and type) for a given disco entity. - * - * For example, when determining support for PEP (personal eventing protocol), you - * want to know whether the user's own JID has an identity with - * `category='pubsub'` and `type='pep'` as explained in this section of - * XEP-0163: https://xmpp.org/extensions/xep-0163.html#support - * - * @method api.disco.getIdentity - * @param {string} The identity category. - * In the XML stanza, this is the `category` - * attribute of the `` element. - * For example: 'pubsub' - * @param {string} type The identity type. - * In the XML stanza, this is the `type` - * attribute of the `` element. - * For example: 'pep' - * @param {string} jid The JID of the entity which might have the identity - * @returns {promise} A promise which resolves with a map indicating - * whether an identity with a given type is provided by the entity. - * @example - * api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid).then( - * function (identity) { - * if (identity) { - * // The entity DOES have this identity - * } else { - * // The entity DOES NOT have this identity - * } - * } - * ).catch(e => log.error(e)); - */ - async getIdentity(category, type, jid) { - const e = await api.disco.entities.get(jid, true); - - if (e === undefined && !api.connection.connected()) { - // Happens during tests when disco lookups happen asynchronously after teardown. - const msg = `Tried to look up category ${category} for ${jid} but _converse.disco_entities has been torn down`; - headless_log.warn(msg); - return; - } - - return e.getIdentity(category, type); - } - - } -}); -;// CONCATENATED MODULE: ./src/headless/plugins/disco/index.js -/** - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description Converse plugin which add support for XEP-0030: Service Discovery - */ - - - - - -const { - Strophe: disco_Strophe -} = core_converse.env; -core_converse.plugins.add('converse-disco', { - initialize() { - Object.assign(api, disco_api); - api.promises.add('discoInitialized'); - api.promises.add('streamFeaturesAdded'); - shared_converse.DiscoEntity = entity; - shared_converse.DiscoEntities = entities; - shared_converse.disco = { - _identities: [], - _features: [] - }; - api.listen.on('userSessionInitialized', async () => { - initStreamFeatures(); - - if (shared_converse.connfeedback.get('connection_status') === disco_Strophe.Status.ATTACHED) { - // When re-attaching to a BOSH session, we fetch the stream features from the cache. - await new Promise((success, error) => shared_converse.stream_features.fetch({ - success, - error - })); - notifyStreamFeaturesAdded(); - } - }); - api.listen.on('beforeResourceBinding', populateStreamFeatures); - api.listen.on('reconnected', initializeDisco); - api.listen.on('connected', initializeDisco); - api.listen.on('beforeTearDown', async () => { - api.promises.add('streamFeaturesAdded'); - - if (shared_converse.stream_features) { - await shared_converse.stream_features.clearStore(); - delete shared_converse.stream_features; - } - }); // All disco entities stored in sessionStorage and are refetched - // upon login or reconnection and then stored with new ids, so to - // avoid sessionStorage filling up, we remove them. - - api.listen.on('will-reconnect', utils_clearSession); - api.listen.on('clearSession', utils_clearSession); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/emoji/regexes.js -const ASCII_REGEX = '(\\*\\\\0\\/\\*|\\*\\\\O\\/\\*|\\-___\\-|\\:\'\\-\\)|\'\\:\\-\\)|\'\\:\\-D|\\>\\:\\-\\)|>\\:\\-\\)|\'\\:\\-\\(|\\>\\:\\-\\(|>\\:\\-\\(|\\:\'\\-\\(|O\\:\\-\\)|0\\:\\-3|0\\:\\-\\)|0;\\^\\)|O;\\-\\)|0;\\-\\)|O\\:\\-3|\\-__\\-|\\:\\-Þ|\\:\\-Þ|\\<\\/3|<\\/3|\\:\'\\)|\\:\\-D|\'\\:\\)|\'\\=\\)|\'\\:D|\'\\=D|\\>\\:\\)|>\\:\\)|\\>;\\)|>;\\)|\\>\\=\\)|>\\=\\)|;\\-\\)|\\*\\-\\)|;\\-\\]|;\\^\\)|\'\\:\\(|\'\\=\\(|\\:\\-\\*|\\:\\^\\*|\\>\\:P|>\\:P|X\\-P|\\>\\:\\[|>\\:\\[|\\:\\-\\(|\\:\\-\\[|\\>\\:\\(|>\\:\\(|\\:\'\\(|;\\-\\(|\\>\\.\\<|>\\.<|#\\-\\)|%\\-\\)|X\\-\\)|\\\\0\\/|\\\\O\\/|0\\:3|0\\:\\)|O\\:\\)|O\\=\\)|O\\:3|B\\-\\)|8\\-\\)|B\\-D|8\\-D|\\-_\\-|\\>\\:\\\\|>\\:\\\\|\\>\\:\\/|>\\:\\/|\\:\\-\\/|\\:\\-\\.|\\:\\-P|\\:Þ|\\:Þ|\\:\\-b|\\:\\-O|O_O|\\>\\:O|>\\:O|\\:\\-X|\\:\\-#|\\:\\-\\)|\\(y\\)|\\<3|<3|\\:D|\\=D|;\\)|\\*\\)|;\\]|;D|\\:\\*|\\=\\*|\\:\\(|\\:\\[|\\=\\(|\\:@|;\\(|D\\:|\\:\\$|\\=\\$|#\\)|%\\)|X\\)|B\\)|8\\)|\\:\\/|\\:\\\\|\\=\\/|\\=\\\\|\\:L|\\=L|\\:P|\\=P|\\:b|\\:O|\\:X|\\:#|\\=X|\\=#|\\:\\)|\\=\\]|\\=\\)|\\:\\])'; -const ASCII_REPLACE_REGEX = new RegExp("]*>.*?<\/object>|]*>.*?<\/span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|((\\s|^)" + ASCII_REGEX + "(?=\\s|$|[!,.?]))", "gi"); -const CODEPOINTS_REGEX = /(?:\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5\udeeb\udeec\udef4-\udefa\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd71\udd73-\udd76\udd7a-\udda2\udda5-\uddaa\uddae-\uddb4\uddb7\uddba\uddbc-\uddca\uddd0\uddde-\uddff\ude70-\ude73\ude78-\ude7a\ude80-\ude82\ude90-\ude95]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g; -;// CONCATENATED MODULE: ./src/headless/plugins/emoji/index.js -/** - * @module converse-emoji - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - -const emoji_u = core_converse.env.utils; -core_converse.emojis = { - 'initialized': false, - 'initialized_promise': getOpenPromise() -}; -const ASCII_LIST = { - '*\\0/*': '1f646', - '*\\O/*': '1f646', - '-___-': '1f611', - ':\'-)': '1f602', - '\':-)': '1f605', - '\':-D': '1f605', - '>:-)': '1f606', - '\':-(': '1f613', - '>:-(': '1f620', - ':\'-(': '1f622', - 'O:-)': '1f607', - '0:-3': '1f607', - '0:-)': '1f607', - '0;^)': '1f607', - 'O;-)': '1f607', - '0;-)': '1f607', - 'O:-3': '1f607', - '-__-': '1f611', - ':-Þ': '1f61b', - ':)': '1f606', - '>;)': '1f606', - '>=)': '1f606', - ';-)': '1f609', - '*-)': '1f609', - ';-]': '1f609', - ';^)': '1f609', - '\':(': '1f613', - '\'=(': '1f613', - ':-*': '1f618', - ':^*': '1f618', - '>:P': '1f61c', - 'X-P': '1f61c', - '>:[': '1f61e', - ':-(': '1f61e', - ':-[': '1f61e', - '>:(': '1f620', - ':\'(': '1f622', - ';-(': '1f622', - '>.<': '1f623', - '#-)': '1f635', - '%-)': '1f635', - 'X-)': '1f635', - '\\0/': '1f646', - '\\O/': '1f646', - '0:3': '1f607', - '0:)': '1f607', - 'O:)': '1f607', - 'O=)': '1f607', - 'O:3': '1f607', - 'B-)': '1f60e', - '8-)': '1f60e', - 'B-D': '1f60e', - '8-D': '1f60e', - '-_-': '1f611', - '>:\\': '1f615', - '>:/': '1f615', - ':-/': '1f615', - ':-.': '1f615', - ':-P': '1f61b', - ':Þ': '1f61b', - ':-b': '1f61b', - ':-O': '1f62e', - 'O_O': '1f62e', - '>:O': '1f62e', - ':-X': '1f636', - ':-#': '1f636', - ':-)': '1f642', - '(y)': '1f44d', - '<3': '2764', - ':D': '1f603', - '=D': '1f603', - ';)': '1f609', - '*)': '1f609', - ';]': '1f609', - ';D': '1f609', - ':*': '1f618', - '=*': '1f618', - ':(': '1f61e', - ':[': '1f61e', - '=(': '1f61e', - ':@': '1f620', - ';(': '1f622', - 'D:': '1f628', - ':$': '1f633', - '=$': '1f633', - '#)': '1f635', - '%)': '1f635', - 'X)': '1f635', - 'B)': '1f60e', - '8)': '1f60e', - ':/': '1f615', - ':\\': '1f615', - '=/': '1f615', - '=\\': '1f615', - ':L': '1f615', - '=L': '1f615', - ':P': '1f61b', - '=P': '1f61b', - ':b': '1f61b', - ':O': '1f62e', - ':X': '1f636', - ':#': '1f636', - '=X': '1f636', - '=#': '1f636', - ':)': '1f642', - '=]': '1f642', - '=)': '1f642', - ':]': '1f642' -}; - -function toCodePoint(unicode_surrogates) { - const r = []; - let p = 0; - let i = 0; - - while (i < unicode_surrogates.length) { - const c = unicode_surrogates.charCodeAt(i++); - - if (p) { - r.push((0x10000 + (p - 0xD800 << 10) + (c - 0xDC00)).toString(16)); - p = 0; - } else if (0xD800 <= c && c <= 0xDBFF) { - p = c; - } else { - r.push(c.toString(16)); - } - } - - return r.join('-'); -} - -function fromCodePoint(codepoint) { - let code = typeof codepoint === 'string' ? parseInt(codepoint, 16) : codepoint; - - if (code < 0x10000) { - return String.fromCharCode(code); - } - - code -= 0x10000; - return String.fromCharCode(0xD800 + (code >> 10), 0xDC00 + (code & 0x3FF)); -} - -function convert(unicode) { - // Converts unicode code points and code pairs to their respective characters - if (unicode.indexOf("-") > -1) { - const parts = [], - s = unicode.split('-'); - - for (let i = 0; i < s.length; i++) { - let part = parseInt(s[i], 16); - - if (part >= 0x10000 && part <= 0x10FFFF) { - const hi = Math.floor((part - 0x10000) / 0x400) + 0xD800; - const lo = (part - 0x10000) % 0x400 + 0xDC00; - part = String.fromCharCode(hi) + String.fromCharCode(lo); - } else { - part = String.fromCharCode(part); - } - - parts.push(part); - } - - return parts.join(''); - } - - return fromCodePoint(unicode); -} - -function unique(arr) { - return [...new Set(arr)]; -} - -function getTonedEmojis() { - if (!core_converse.emojis.toned) { - core_converse.emojis.toned = unique(Object.values(core_converse.emojis.json.people).filter(person => person.sn.includes('_tone')).map(person => person.sn.replace(/_tone[1-5]/, ''))); - } - - return core_converse.emojis.toned; -} - -function convertASCII2Emoji(str) { - // Replace ASCII smileys - return str.replace(ASCII_REPLACE_REGEX, (entire, m1, m2, m3) => { - if (typeof m3 === 'undefined' || m3 === '' || !(emoji_u.unescapeHTML(m3) in ASCII_LIST)) { - // if the ascii doesnt exist just return the entire match - return entire; - } - - m3 = emoji_u.unescapeHTML(m3); - const unicode = ASCII_LIST[m3].toUpperCase(); - return m2 + convert(unicode); - }); -} -function getEmojiMarkup(data, options = { - unicode_only: false, - add_title_wrapper: false -}) { - const emoji = data.emoji; - const shortname = data.shortname; - - if (emoji) { - if (options.unicode_only) { - return emoji; - } else if (api.settings.get('use_system_emojis')) { - if (options.add_title_wrapper) { - return shortname ? T`${emoji}` : emoji; - } else { - return emoji; - } - } else { - const path = api.settings.get('emoji_image_path'); - return T`${emoji}`; - } - } else if (options.unicode_only) { - return shortname; - } else { - return T`${shortname}`; - } -} -function getShortnameReferences(text) { - if (!core_converse.emojis.initialized) { - throw new Error('getShortnameReferences called before emojis are initialized. ' + 'To avoid this problem, first await the converse.emojis.initilaized_promise.'); - } - - const references = [...text.matchAll(core_converse.emojis.shortnames_regex)].filter(ref => ref[0].length > 0); - return references.map(ref => { - const cp = core_converse.emojis.by_sn[ref[0]].cp; - return { - cp, - 'begin': ref.index, - 'end': ref.index + ref[0].length, - 'shortname': ref[0], - 'emoji': cp ? convert(cp) : null - }; - }); -} - -function parseStringForEmojis(str, callback) { - const UFE0Fg = /\uFE0F/g; - const U200D = String.fromCharCode(0x200D); - return String(str).replace(CODEPOINTS_REGEX, (emoji, _, offset) => { - const icon_id = toCodePoint(emoji.indexOf(U200D) < 0 ? emoji.replace(UFE0Fg, '') : emoji); - if (icon_id) callback(icon_id, emoji, offset); - }); -} - -function getCodePointReferences(text) { - const references = []; - parseStringForEmojis(text, (icon_id, emoji, offset) => { - var _u$getEmojisByAtrribu; - - references.push({ - 'begin': offset, - 'cp': icon_id, - 'emoji': emoji, - 'end': offset + emoji.length, - 'shortname': ((_u$getEmojisByAtrribu = emoji_u.getEmojisByAtrribute('cp')[icon_id]) === null || _u$getEmojisByAtrribu === void 0 ? void 0 : _u$getEmojisByAtrribu.sn) || '' - }); - }); - return references; -} - -function addEmojisMarkup(text, options) { - let list = [text]; - [...getShortnameReferences(text), ...getCodePointReferences(text)].sort((a, b) => b.begin - a.begin).forEach(ref => { - const text = list.shift(); - const emoji = getEmojiMarkup(ref, options); - - if (typeof emoji === 'string') { - list = [text.slice(0, ref.begin) + emoji + text.slice(ref.end), ...list]; - } else { - list = [text.slice(0, ref.begin), emoji, text.slice(ref.end), ...list]; - } - }); - return list; -} - -core_converse.plugins.add('converse-emoji', { - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - const { - ___ - } = shared_converse; - api.settings.extend({ - 'emoji_image_path': 'https://twemoji.maxcdn.com/v/12.1.6/', - 'emoji_categories': { - "smileys": ":grinning:", - "people": ":thumbsup:", - "activity": ":soccer:", - "travel": ":motorcycle:", - "objects": ":bomb:", - "nature": ":rainbow:", - "food": ":hotdog:", - "symbols": ":musical_note:", - "flags": ":flag_ac:", - "custom": null - }, - // We use the triple-underscore method which doesn't actually - // translate but does signify to gettext that these strings should - // go into the POT file. The translation then happens in the - // template. We do this so that users can pass in their own - // strings via converse.initialize, which is before __ is - // available. - 'emoji_category_labels': { - "smileys": ___("Smileys and emotions"), - "people": ___("People"), - "activity": ___("Activities"), - "travel": ___("Travel"), - "objects": ___("Objects"), - "nature": ___("Animals and nature"), - "food": ___("Food and drink"), - "symbols": ___("Symbols"), - "flags": ___("Flags"), - "custom": ___("Stickers") - } - }); - /** - * Model for storing data related to the Emoji picker widget - * @class - * @namespace _converse.EmojiPicker - * @memberOf _converse - */ - - shared_converse.EmojiPicker = Model.extend({ - defaults: { - 'current_category': 'smileys', - 'current_skintone': '', - 'scroll_position': 0 - } - }); - /************************ BEGIN Utils ************************/ - // Closured cache - - const emojis_by_attribute = {}; - Object.assign(emoji_u, { - /** - * Returns an emoji represented by the passed in shortname. - * Scans the passed in text for shortnames and replaces them with - * emoji unicode glyphs or alternatively if it's a custom emoji - * without unicode representation then a lit TemplateResult - * which represents image tag markup is returned. - * - * The shortname needs to be defined in `emojis.json` - * and needs to have either a `cp` attribute for the codepoint, or - * an `url` attribute which points to the source for the image. - * - * @method u.shortnamesToEmojis - * @param { String } str - String containg the shortname(s) - * @param { Object } options - * @param { Boolean } options.unicode_only - Whether emojis are rendered as - * unicode codepoints. If so, the returned result will be an array - * with containing one string, because the emojis themselves will - * also be strings. If set to false, emojis will be represented by - * lit TemplateResult objects. - * @param { Boolean } options.add_title_wrapper - Whether unicode - * codepoints should be wrapped with a `` element with a - * title, so that the shortname is shown upon hovering with the - * mouse. - * @returns {Array} An array of at least one string, or otherwise - * strings and lit TemplateResult objects. - */ - shortnamesToEmojis(str, options = { - unicode_only: false, - add_title_wrapper: false - }) { - str = convertASCII2Emoji(str); - return addEmojisMarkup(str, options); - }, - - /** - * Replaces all shortnames in the passed in string with their - * unicode (emoji) representation. - * @method u.shortnamesToUnicode - * @param { String } str - String containing the shortname(s) - * @returns { String } - */ - shortnamesToUnicode(str) { - return emoji_u.shortnamesToEmojis(str, { - 'unicode_only': true - })[0]; - }, - - /** - * Determines whether the passed in string is just a single emoji shortname; - * @method u.isOnlyEmojis - * @param { String } shortname - A string which migh be just an emoji shortname - * @returns { Boolean } - */ - isOnlyEmojis(text) { - const words = text.trim().split(/\s+/); - - if (words.length === 0 || words.length > 3) { - return false; - } - - const emojis = words.filter(text => { - const refs = getCodePointReferences(emoji_u.shortnamesToUnicode(text)); - return refs.length === 1 && (text === refs[0]['shortname'] || text === refs[0]['emoji']); - }); - return emojis.length === words.length; - }, - - /** - * @method u.getEmojisByAtrribute - * @param { String } attr - The attribute according to which the - * returned map should be keyed. - * @returns { Object } - Map of emojis with the passed in attribute values - * as keys and a list of emojis for a particular category as values. - */ - getEmojisByAtrribute(attr) { - if (emojis_by_attribute[attr]) { - return emojis_by_attribute[attr]; - } - - if (attr === 'category') { - return core_converse.emojis.json; - } - - const all_variants = core_converse.emojis.list.map(e => e[attr]).filter((c, i, arr) => arr.indexOf(c) == i); - emojis_by_attribute[attr] = {}; - all_variants.forEach(v => emojis_by_attribute[attr][v] = core_converse.emojis.list.find(i => i[attr] === v)); - return emojis_by_attribute[attr]; - } - - }); - /************************ END Utils ************************/ - - /************************ BEGIN API ************************/ - // We extend the default converse.js API to add methods specific to MUC groupchats. - - Object.assign(api, { - /** - * @namespace api.emojis - * @memberOf api - */ - emojis: { - /** - * Initializes Emoji support by downloading the emojis JSON (and any applicable images). - * @method api.emojis.initialize - * @returns {Promise} - */ - async initialize() { - if (!core_converse.emojis.initialized) { - core_converse.emojis.initialized = true; - const { - default: json - } = await __webpack_require__.e(/* import() | emojis */ 4610).then(__webpack_require__.t.bind(__webpack_require__, 7530, 19)); - core_converse.emojis.json = json; - core_converse.emojis.by_sn = Object.keys(json).reduce((result, cat) => Object.assign(result, json[cat]), {}); - core_converse.emojis.list = Object.values(core_converse.emojis.by_sn); - core_converse.emojis.list.sort((a, b) => a.sn < b.sn ? -1 : a.sn > b.sn ? 1 : 0); - core_converse.emojis.shortnames = core_converse.emojis.list.map(m => m.sn); - - const getShortNames = () => core_converse.emojis.shortnames.map(s => s.replace(/[+]/g, "\\$&")).join('|'); - - core_converse.emojis.shortnames_regex = new RegExp(getShortNames(), "gi"); - core_converse.emojis.toned = getTonedEmojis(); - core_converse.emojis.initialized_promise.resolve(); - } - - return core_converse.emojis.initialized_promise; - } - - } - }); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/message.js - - - -/** - * Mixing that turns a Message model into a ChatRoomMessage model. - * @class - * @namespace _converse.ChatRoomMessage - * @memberOf _converse - */ - -const ChatRoomMessageMixin = { - initialize() { - if (!this.checkValidity()) { - return; - } - - if (this.get('file')) { - this.on('change:put', this.uploadFile, this); - } - - if (!this.setTimerForEphemeralMessage()) { - this.setOccupant(); - } - /** - * Triggered once a {@link _converse.ChatRoomMessageInitialized} has been created and initialized. - * @event _converse#chatRoomMessageInitialized - * @type { _converse.ChatRoomMessages} - * @example _converse.api.listen.on('chatRoomMessageInitialized', model => { ... }); - */ - - - api.trigger('chatRoomMessageInitialized', this); - }, - - /** - * Determines whether this messsage may be moderated, - * based on configuration settings and server support. - * @async - * @private - * @method _converse.ChatRoomMessages#mayBeModerated - * @returns { Boolean } - */ - mayBeModerated() { - return ['all', 'moderator'].includes(api.settings.get('allow_message_retraction')) && this.collection.chatbox.canModerateMessages(); - }, - - checkValidity() { - const result = shared_converse.Message.prototype.checkValidity.call(this); - - !result && this.collection.chatbox.debouncedRejoin(); - return result; - }, - - onOccupantRemoved() { - var _this$collection; - - this.stopListening(this.occupant); - delete this.occupant; - const chatbox = this === null || this === void 0 ? void 0 : (_this$collection = this.collection) === null || _this$collection === void 0 ? void 0 : _this$collection.chatbox; - - if (!chatbox) { - return headless_log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`); - } - - this.listenTo(chatbox.occupants, 'add', this.onOccupantAdded); - }, - - onOccupantAdded(occupant) { - if (occupant.get('nick') === Strophe.getResourceFromJid(this.get('from'))) { - var _this$collection2; - - this.occupant = occupant; - this.trigger('occupantAdded'); - this.listenTo(this.occupant, 'destroy', this.onOccupantRemoved); - const chatbox = this === null || this === void 0 ? void 0 : (_this$collection2 = this.collection) === null || _this$collection2 === void 0 ? void 0 : _this$collection2.chatbox; - - if (!chatbox) { - return headless_log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`); - } - - this.stopListening(chatbox.occupants, 'add', this.onOccupantAdded); - } - }, - - setOccupant() { - var _this$collection3; - - if (this.get('type') !== 'groupchat') { - return; - } - - const chatbox = this === null || this === void 0 ? void 0 : (_this$collection3 = this.collection) === null || _this$collection3 === void 0 ? void 0 : _this$collection3.chatbox; - - if (!chatbox) { - return headless_log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`); - } - - const nick = Strophe.getResourceFromJid(this.get('from')); - this.occupant = chatbox.occupants.findWhere({ - nick - }); - - if (!this.occupant && api.settings.get('muc_send_probes')) { - this.occupant = chatbox.occupants.create({ - nick, - 'type': 'unavailable' - }); - const jid = `${chatbox.get('jid')}/${nick}`; - api.user.presence.send('probe', jid); - } - - if (this.occupant) { - this.listenTo(this.occupant, 'destroy', this.onOccupantRemoved); - } else { - this.listenTo(chatbox.occupants, 'add', this.onOccupantAdded); - } - } - -}; -/* harmony default export */ const muc_message = (ChatRoomMessageMixin); -;// CONCATENATED MODULE: ./src/headless/utils/parse-helpers.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description Pure functions to help functionally parse messages. - * @todo Other parsing helpers can be made more abstract and placed here. - */ -const helpers = {}; - -const escapeRegexChars = (string, char) => string.replace(RegExp('\\' + char, 'ig'), '\\' + char); - -helpers.escapeCharacters = characters => string => characters.split('').reduce(escapeRegexChars, string); - -helpers.escapeRegexString = helpers.escapeCharacters('[\\^$.?*+(){}|'); // `for` is ~25% faster than using `Array.find()` - -helpers.findFirstMatchInArray = array => text => { - for (let i = 0; i < array.length; i++) { - if (text.localeCompare(array[i], undefined, { - sensitivity: 'base' - }) === 0) { - return array[i]; - } - } - - return null; -}; - -const reduceReferences = ([text, refs], ref, index) => { - let updated_text = text; - let { - begin, - end - } = ref; - const { - value - } = ref; - begin = begin - index; - end = end - index - 1; // -1 to compensate for the removed @ - - updated_text = `${updated_text.slice(0, begin)}${value}${updated_text.slice(end + 1)}`; - return [updated_text, [...refs, { ...ref, - begin, - end - }]]; -}; - -helpers.reduceTextFromReferences = (text, refs) => refs.reduce(reduceReferences, [text, []]); - -/* harmony default export */ const parse_helpers = (helpers); -;// CONCATENATED MODULE: ./src/headless/utils/form.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description This is the form utilities module. - */ - -/** - * Takes an HTML DOM and turns it into an XForm field. - * @private - * @method u#webForm2xForm - * @param { DOMElement } field - the field to convert - */ - -utils_core.webForm2xForm = function (field) { - const name = field.getAttribute('name'); - - if (!name) { - return null; // See #1924 - } - - let value; - - if (field.getAttribute('type') === 'checkbox') { - value = field.checked && 1 || 0; - } else if (field.tagName == "TEXTAREA") { - value = field.value.split('\n').filter(s => s.trim()); - } else if (field.tagName == "SELECT") { - value = utils_core.getSelectValues(field); - } else { - value = field.value; - } - - return utils_core.toStanza(` - - ${value.constructor === Array ? value.map(v => `${v}`) : `${value}`} - `); -}; - -/* harmony default export */ const utils_form = (utils_core); -;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js -/** - * This base implementation of `_.zipObject` which assigns values using `assignFunc`. - * - * @private - * @param {Array} props The property identifiers. - * @param {Array} values The property values. - * @param {Function} assignFunc The function to assign values. - * @returns {Object} Returns the new object. - */ -function baseZipObject(props, values, assignFunc) { - var index = -1, - length = props.length, - valsLength = values.length, - result = {}; - - while (++index < length) { - var value = index < valsLength ? values[index] : undefined; - assignFunc(result, props[index], value); - } - - return result; -} - -/* harmony default export */ const _baseZipObject = (baseZipObject); -;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js - - -/** - * This method is like `_.fromPairs` except that it accepts two arrays, - * one of property identifiers and one of corresponding values. - * - * @static - * @memberOf _ - * @since 0.4.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject(['a', 'b'], [1, 2]); - * // => { 'a': 1, 'b': 2 } - */ - -function zipObject(props, values) { - return _baseZipObject(props || [], values || [], _assignValue); -} - -/* harmony default export */ const lodash_es_zipObject = (zipObject); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/parsers.js - - - -const { - Strophe: muc_parsers_Strophe, - sizzle: muc_parsers_sizzle, - u: parsers_u -} = core_converse.env; -const { - NS: parsers_NS -} = muc_parsers_Strophe; -/** - * Parses a message stanza for XEP-0317 MEP notification data - * @param { XMLElement } stanza - The message stanza - * @returns { Array } Returns an array of objects representing elements. - */ - -function getMEPActivities(stanza) { - const items_el = muc_parsers_sizzle(`items[node="${muc_parsers_Strophe.NS.CONFINFO}"]`, stanza).pop(); - - if (!items_el) { - return null; - } - - const from = stanza.getAttribute('from'); - const msgid = stanza.getAttribute('id'); - const selector = `item ` + `conference-info[xmlns="${muc_parsers_Strophe.NS.CONFINFO}"] ` + `activity[xmlns="${muc_parsers_Strophe.NS.ACTIVITY}"]`; - return muc_parsers_sizzle(selector, items_el).map(el => { - var _el$querySelector; - - const message = (_el$querySelector = el.querySelector('text')) === null || _el$querySelector === void 0 ? void 0 : _el$querySelector.textContent; - - if (message) { - var _el$querySelector2; - - const references = getReferences(stanza); - const reason = (_el$querySelector2 = el.querySelector('reason')) === null || _el$querySelector2 === void 0 ? void 0 : _el$querySelector2.textContent; - return { - from, - msgid, - message, - reason, - references, - 'type': 'info' - }; - } - - return {}; - }); -} -/** - * @private - * @param { XMLElement } stanza - The message stanza - * @param { XMLElement } original_stanza - The original stanza, that contains the - * message stanza, if it was contained, otherwise it's the message stanza itself. - * @returns { Object } - */ - -function getModerationAttributes(stanza) { - const fastening = muc_parsers_sizzle(`apply-to[xmlns="${muc_parsers_Strophe.NS.FASTEN}"]`, stanza).pop(); - - if (fastening) { - const applies_to_id = fastening.getAttribute('id'); - const moderated = muc_parsers_sizzle(`moderated[xmlns="${muc_parsers_Strophe.NS.MODERATE}"]`, fastening).pop(); - - if (moderated) { - const retracted = muc_parsers_sizzle(`retract[xmlns="${muc_parsers_Strophe.NS.RETRACT}"]`, moderated).pop(); - - if (retracted) { - var _moderated$querySelec; - - return { - 'editable': false, - 'moderated': 'retracted', - 'moderated_by': moderated.getAttribute('by'), - 'moderated_id': applies_to_id, - 'moderation_reason': (_moderated$querySelec = moderated.querySelector('reason')) === null || _moderated$querySelec === void 0 ? void 0 : _moderated$querySelec.textContent - }; - } - } - } else { - const tombstone = muc_parsers_sizzle(`> moderated[xmlns="${muc_parsers_Strophe.NS.MODERATE}"]`, stanza).pop(); - - if (tombstone) { - const retracted = muc_parsers_sizzle(`retracted[xmlns="${muc_parsers_Strophe.NS.RETRACT}"]`, tombstone).pop(); - - if (retracted) { - var _tombstone$querySelec; - - return { - 'editable': false, - 'is_tombstone': true, - 'moderated_by': tombstone.getAttribute('by'), - 'retracted': tombstone.getAttribute('stamp'), - 'moderation_reason': (_tombstone$querySelec = tombstone.querySelector('reason')) === null || _tombstone$querySelec === void 0 ? void 0 : _tombstone$querySelec.textContent - }; - } - } - } - - return {}; -} -/** - * Parses a passed in message stanza and returns an object of attributes. - * @param { XMLElement } stanza - The message stanza - * @param { XMLElement } original_stanza - The original stanza, that contains the - * message stanza, if it was contained, otherwise it's the message stanza itself. - * @param { _converse.ChatRoom } chatbox - * @param { _converse } _converse - * @returns { Promise } - */ - - -async function parseMUCMessage(stanza, chatbox, _converse) { - var _stanza, _stanza$querySelector, _stanza$querySelector2, _chatbox$occupants$fi, _stanza$querySelector3, _stanza$querySelector4; - - throwErrorIfInvalidForward(stanza); - const selector = `[xmlns="${parsers_NS.MAM}"] > forwarded[xmlns="${parsers_NS.FORWARD}"] > message`; - const original_stanza = stanza; - stanza = muc_parsers_sizzle(selector, stanza).pop() || stanza; - - if (muc_parsers_sizzle(`message > forwarded[xmlns="${muc_parsers_Strophe.NS.FORWARD}"]`, stanza).length) { - return new StanzaParseError(`Invalid Stanza: Forged MAM groupchat message from ${stanza.getAttribute('from')}`, stanza); - } - - const delay = muc_parsers_sizzle(`delay[xmlns="${muc_parsers_Strophe.NS.DELAY}"]`, original_stanza).pop(); - const from = stanza.getAttribute('from'); - const nick = muc_parsers_Strophe.unescapeNode(muc_parsers_Strophe.getResourceFromJid(from)); - const marker = getChatMarker(stanza); - const now = new Date().toISOString(); - /** - * @typedef { Object } MUCMessageAttributes - * The object which {@link parseMUCMessage} returns - * @property { ('me'|'them') } sender - Whether the message was sent by the current user or someone else - * @property { Array } activities - A list of objects representing XEP-0316 MEP notification data - * @property { Array } references - A list of objects representing XEP-0372 references - * @property { Boolean } editable - Is this message editable via XEP-0308? - * @property { Boolean } is_archived - Is this message from a XEP-0313 MAM archive? - * @property { Boolean } is_carbon - Is this message a XEP-0280 Carbon? - * @property { Boolean } is_delayed - Was delivery of this message was delayed as per XEP-0203? - * @property { Boolean } is_encrypted - Is this message XEP-0384 encrypted? - * @property { Boolean } is_error - Whether an error was received for this message - * @property { Boolean } is_headline - Is this a "headline" message? - * @property { Boolean } is_markable - Can this message be marked with a XEP-0333 chat marker? - * @property { Boolean } is_marker - Is this message a XEP-0333 Chat Marker? - * @property { Boolean } is_only_emojis - Does the message body contain only emojis? - * @property { Boolean } is_spoiler - Is this a XEP-0382 spoiler message? - * @property { Boolean } is_tombstone - Is this a XEP-0424 tombstone? - * @property { Boolean } is_unstyled - Whether XEP-0393 styling hints should be ignored - * @property { Boolean } is_valid_receipt_request - Does this message request a XEP-0184 receipt (and is not from us or a carbon or archived message) - * @property { Object } encrypted - XEP-0384 encryption payload attributes - * @property { String } body - The contents of the tag of the message stanza - * @property { String } chat_state - The XEP-0085 chat state notification contained in this message - * @property { String } edited - An ISO8601 string recording the time that the message was edited per XEP-0308 - * @property { String } error_condition - The defined error condition - * @property { String } error_text - The error text received from the server - * @property { String } error_type - The type of error received from the server - * @property { String } from - The sender JID (${muc_jid}/${nick}) - * @property { String } from_muc - The JID of the MUC from which this message was sent - * @property { String } from_real_jid - The real JID of the sender, if available - * @property { String } fullname - The full name of the sender - * @property { String } marker - The XEP-0333 Chat Marker value - * @property { String } marker_id - The `id` attribute of a XEP-0333 chat marker - * @property { String } moderated - The type of XEP-0425 moderation (if any) that was applied - * @property { String } moderated_by - The JID of the user that moderated this message - * @property { String } moderated_id - The XEP-0359 Stanza ID of the message that this one moderates - * @property { String } moderation_reason - The reason provided why this message moderates another - * @property { String } msgid - The root `id` attribute of the stanza - * @property { String } nick - The MUC nickname of the sender - * @property { String } oob_desc - The description of the XEP-0066 out of band data - * @property { String } oob_url - The URL of the XEP-0066 out of band data - * @property { String } origin_id - The XEP-0359 Origin ID - * @property { String } receipt_id - The `id` attribute of a XEP-0184 element - * @property { String } received - An ISO8601 string recording the time that the message was received - * @property { String } replace_id - The `id` attribute of a XEP-0308 element - * @property { String } retracted - An ISO8601 string recording the time that the message was retracted - * @property { String } retracted_id - The `id` attribute of a XEP-424 element - * @property { String } spoiler_hint The XEP-0382 spoiler hint - * @property { String } stanza_id - The XEP-0359 Stanza ID. Note: the key is actualy `stanza_id ${by_jid}` and there can be multiple. - * @property { String } subject - The element value - * @property { String } thread - The element value - * @property { String } time - The time (in ISO8601 format), either given by the XEP-0203 element, or of receipt. - * @property { String } to - The recipient JID - * @property { String } type - The type of message - */ - - let attrs = Object.assign({ - from, - nick, - 'is_forwarded': !!((_stanza = stanza) !== null && _stanza !== void 0 && _stanza.querySelector('forwarded')), - 'activities': getMEPActivities(stanza), - 'body': (_stanza$querySelector = stanza.querySelector('body')) === null || _stanza$querySelector === void 0 ? void 0 : (_stanza$querySelector2 = _stanza$querySelector.textContent) === null || _stanza$querySelector2 === void 0 ? void 0 : _stanza$querySelector2.trim(), - 'chat_state': getChatState(stanza), - 'from_muc': muc_parsers_Strophe.getBareJidFromJid(from), - 'from_real_jid': (_chatbox$occupants$fi = chatbox.occupants.findOccupant({ - nick - })) === null || _chatbox$occupants$fi === void 0 ? void 0 : _chatbox$occupants$fi.get('jid'), - 'is_archived': isArchived(original_stanza), - 'is_carbon': isCarbon(original_stanza), - 'is_delayed': !!delay, - 'is_headline': isHeadline(stanza), - 'is_markable': !!muc_parsers_sizzle(`markable[xmlns="${muc_parsers_Strophe.NS.MARKERS}"]`, stanza).length, - 'is_marker': !!marker, - 'is_unstyled': !!muc_parsers_sizzle(`unstyled[xmlns="${muc_parsers_Strophe.NS.STYLING}"]`, stanza).length, - 'marker_id': marker && marker.getAttribute('id'), - 'msgid': stanza.getAttribute('id') || original_stanza.getAttribute('id'), - 'receipt_id': getReceiptId(stanza), - 'received': new Date().toISOString(), - 'references': getReferences(stanza), - 'subject': (_stanza$querySelector3 = stanza.querySelector('subject')) === null || _stanza$querySelector3 === void 0 ? void 0 : _stanza$querySelector3.textContent, - 'thread': (_stanza$querySelector4 = stanza.querySelector('thread')) === null || _stanza$querySelector4 === void 0 ? void 0 : _stanza$querySelector4.textContent, - 'time': delay ? dayjs_min_default()(delay.getAttribute('stamp')).toISOString() : now, - 'to': stanza.getAttribute('to'), - 'type': stanza.getAttribute('type') - }, getErrorAttributes(stanza), getOutOfBandAttributes(stanza), getSpoilerAttributes(stanza), getCorrectionAttributes(stanza, original_stanza), getStanzaIDs(stanza, original_stanza), getOpenGraphMetadata(stanza), getRetractionAttributes(stanza, original_stanza), getModerationAttributes(stanza), getEncryptionAttributes(stanza, _converse)); - await api.emojis.initialize(); - attrs = Object.assign({ - 'is_only_emojis': attrs.body ? parsers_u.isOnlyEmojis(attrs.body) : false, - 'is_valid_receipt_request': isValidReceiptRequest(stanza, attrs), - 'message': attrs.body || attrs.error, - // TODO: Remove and use body and error attributes instead - 'sender': attrs.nick === chatbox.get('nick') ? 'me' : 'them' - }, attrs); - - if (attrs.is_archived && original_stanza.getAttribute('from') !== attrs.from_muc) { - return new StanzaParseError(`Invalid Stanza: Forged MAM message from ${original_stanza.getAttribute('from')}`, stanza); - } else if (attrs.is_archived && original_stanza.getAttribute('from') !== chatbox.get('jid')) { - return new StanzaParseError(`Invalid Stanza: Forged MAM groupchat message from ${stanza.getAttribute('from')}`, stanza); - } else if (attrs.is_carbon) { - return new StanzaParseError('Invalid Stanza: MUC messages SHOULD NOT be XEP-0280 carbon copied', stanza); - } // We prefer to use one of the XEP-0359 unique and stable stanza IDs as the Model id, to avoid duplicates. - - - attrs['id'] = attrs['origin_id'] || attrs[`stanza_id ${attrs.from_muc || attrs.from}`] || parsers_u.getUniqueId(); - /** - * *Hook* which allows plugins to add additional parsing - * @event _converse#parseMUCMessage - */ - - attrs = await api.hook('parseMUCMessage', stanza, attrs); // We call this after the hook, to allow plugins to decrypt encrypted - // messages, since we need to parse the message text to determine whether - // there are media urls. - - return Object.assign(attrs, getMediaURLs(attrs.is_encrypted ? attrs.plaintext : attrs.body)); -} -/** - * Given an IQ stanza with a member list, create an array of objects containing - * known member data (e.g. jid, nick, role, affiliation). - * @private - * @method muc_utils#parseMemberListIQ - * @returns { MemberListItem[] } - */ - -function parseMemberListIQ(iq) { - return muc_parsers_sizzle(`query[xmlns="${muc_parsers_Strophe.NS.MUC_ADMIN}"] item`, iq).map(item => { - /** - * @typedef {Object} MemberListItem - * Either the JID or the nickname (or both) will be available. - * @property {string} affiliation - * @property {string} [role] - * @property {string} [jid] - * @property {string} [nick] - */ - const data = { - 'affiliation': item.getAttribute('affiliation') - }; - const jid = item.getAttribute('jid'); - - if (parsers_u.isValidJID(jid)) { - data['jid'] = jid; - } else { - // XXX: Prosody sends nick for the jid attribute value - // Perhaps for anonymous room? - data['nick'] = jid; - } - - const nick = item.getAttribute('nick'); - - if (nick) { - data['nick'] = nick; - } - - const role = item.getAttribute('role'); - - if (role) { - data['role'] = nick; - } - - return data; - }); -} -/** - * Parses a passed in MUC presence stanza and returns an object of attributes. - * @method parseMUCPresence - * @param { XMLElement } stanza - The presence stanza - * @returns { Object } - */ - -function parseMUCPresence(stanza) { - const from = stanza.getAttribute('from'); - const type = stanza.getAttribute('type'); - const data = { - 'from': from, - 'nick': muc_parsers_Strophe.getResourceFromJid(from), - 'type': type, - 'states': [], - 'hats': [], - 'show': type !== 'unavailable' ? 'online' : 'offline' - }; - Array.from(stanza.children).forEach(child => { - if (child.matches('status')) { - data.status = child.textContent || null; - } else if (child.matches('show')) { - data.show = child.textContent || 'online'; - } else if (child.matches('x') && child.getAttribute('xmlns') === muc_parsers_Strophe.NS.MUC_USER) { - Array.from(child.children).forEach(item => { - if (item.nodeName === 'item') { - data.affiliation = item.getAttribute('affiliation'); - data.role = item.getAttribute('role'); - data.jid = item.getAttribute('jid'); - data.nick = item.getAttribute('nick') || data.nick; - } else if (item.nodeName == 'status' && item.getAttribute('code')) { - data.states.push(item.getAttribute('code')); - } - }); - } else if (child.matches('x') && child.getAttribute('xmlns') === muc_parsers_Strophe.NS.VCARDUPDATE) { - var _child$querySelector; - - data.image_hash = (_child$querySelector = child.querySelector('photo')) === null || _child$querySelector === void 0 ? void 0 : _child$querySelector.textContent; - } else if (child.matches('hats') && child.getAttribute('xmlns') === muc_parsers_Strophe.NS.MUC_HATS) { - data['hats'] = Array.from(child.children).map(c => c.matches('hat') && { - 'title': c.getAttribute('title'), - 'uri': c.getAttribute('uri') - }); - } - }); - return data; -} -;// CONCATENATED MODULE: ./src/headless/plugins/muc/affiliations/utils.js -/** - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - -const { - Strophe: affiliations_utils_Strophe, - $iq: affiliations_utils_$iq, - u: affiliations_utils_u -} = core_converse.env; -/** - * Sends an IQ stanza to the server, asking it for the relevant affiliation list . - * Returns an array of {@link MemberListItem} objects, representing occupants - * that have the given affiliation. - * See: https://xmpp.org/extensions/xep-0045.html#modifymember - * @param { ("admin"|"owner"|"member") } affiliation - * @param { String } muc_jid - The JID of the MUC for which the affiliation list should be fetched - * @returns { Promise } - */ - -async function getAffiliationList(affiliation, muc_jid) { - const { - __ - } = shared_converse; - const iq = affiliations_utils_$iq({ - 'to': muc_jid, - 'type': 'get' - }).c('query', { - xmlns: affiliations_utils_Strophe.NS.MUC_ADMIN - }).c('item', { - 'affiliation': affiliation - }); - const result = await api.sendIQ(iq, null, false); - - if (result === null) { - const err_msg = __('Error: timeout while fetching %1s list for MUC %2s', affiliation, muc_jid); - - const err = new Error(err_msg); - headless_log.warn(err_msg); - headless_log.warn(result); - return err; - } - - if (affiliations_utils_u.isErrorStanza(result)) { - const err_msg = __('Error: not allowed to fetch %1s list for MUC %2s', affiliation, muc_jid); - - const err = new Error(err_msg); - headless_log.warn(err_msg); - headless_log.warn(result); - return err; - } - - return parseMemberListIQ(result).filter(p => p).sort((a, b) => a.nick < b.nick ? -1 : a.nick > b.nick ? 1 : 0); -} -/** - * Given an occupant model, see which affiliations may be assigned to that user. - * @param { Model } occupant - * @returns { ('owner', 'admin', 'member', 'outcast', 'none')[] } - An array of assignable affiliations - */ - -function getAssignableAffiliations(occupant) { - let disabled = api.settings.get('modtools_disable_assign'); - - if (!Array.isArray(disabled)) { - disabled = disabled ? AFFILIATIONS : []; - } - - if (occupant.get('affiliation') === 'owner') { - return AFFILIATIONS.filter(a => !disabled.includes(a)); - } else if (occupant.get('affiliation') === 'admin') { - return AFFILIATIONS.filter(a => !['owner', 'admin', ...disabled].includes(a)); - } else { - return []; - } -} // Necessary for tests - -shared_converse.getAssignableAffiliations = getAssignableAffiliations; -/** - * Send IQ stanzas to the server to modify affiliations for users in this groupchat. - * See: https://xmpp.org/extensions/xep-0045.html#modifymember - * @param { Object[] } users - * @param { string } users[].jid - The JID of the user whose affiliation will change - * @param { Array } users[].affiliation - The new affiliation for this user - * @param { string } [users[].reason] - An optional reason for the affiliation change - * @returns { Promise } - */ - -function setAffiliations(muc_jid, users) { - const affiliations = [...new Set(users.map(u => u.affiliation))]; - return Promise.all(affiliations.map(a => setAffiliation(a, muc_jid, users))); -} -/** - * Send IQ stanzas to the server to set an affiliation for - * the provided JIDs. - * See: https://xmpp.org/extensions/xep-0045.html#modifymember - * - * Prosody doesn't accept multiple JIDs' affiliations - * being set in one IQ stanza, so as a workaround we send - * a separate stanza for each JID. - * Related ticket: https://issues.prosody.im/345 - * - * @param { ('outcast'|'member'|'admin'|'owner') } affiliation - The affiliation to be set - * @param { String|Array } jids - The JID(s) of the MUCs in which the - * affiliations need to be set. - * @param { object } members - A map of jids, affiliations and - * optionally reasons. Only those entries with the - * same affiliation as being currently set will be considered. - * @returns { Promise } A promise which resolves and fails depending on the XMPP server response. - */ - -function setAffiliation(affiliation, muc_jids, members) { - if (!Array.isArray(muc_jids)) { - muc_jids = [muc_jids]; - } - - members = members.filter(m => [undefined, affiliation].includes(m.affiliation)); - return Promise.all(muc_jids.reduce((acc, jid) => [...acc, ...members.map(m => sendAffiliationIQ(affiliation, jid, m))], [])); -} -/** - * Send an IQ stanza specifying an affiliation change. - * @private - * @param { String } affiliation: affiliation (could also be stored on the member object). - * @param { String } muc_jid: The JID of the MUC in which the affiliation should be set. - * @param { Object } member: Map containing the member's jid and optionally a reason and affiliation. - */ - -function sendAffiliationIQ(affiliation, muc_jid, member) { - const iq = affiliations_utils_$iq({ - to: muc_jid, - type: 'set' - }).c('query', { - xmlns: affiliations_utils_Strophe.NS.MUC_ADMIN - }).c('item', { - 'affiliation': member.affiliation || affiliation, - 'nick': member.nick, - 'jid': member.jid - }); - - if (member.reason !== undefined) { - iq.c('reason', member.reason); - } - - return api.sendIQ(iq); -} -/** - * Given two lists of objects with 'jid', 'affiliation' and - * 'reason' properties, return a new list containing - * those objects that are new, changed or removed - * (depending on the 'remove_absentees' boolean). - * - * The affiliations for new and changed members stay the - * same, for removed members, the affiliation is set to 'none'. - * - * The 'reason' property is not taken into account when - * comparing whether affiliations have been changed. - * @param { boolean } exclude_existing - Indicates whether JIDs from - * the new list which are also in the old list - * (regardless of affiliation) should be excluded - * from the delta. One reason to do this - * would be when you want to add a JID only if it - * doesn't have *any* existing affiliation at all. - * @param { boolean } remove_absentees - Indicates whether JIDs - * from the old list which are not in the new list - * should be considered removed and therefore be - * included in the delta with affiliation set - * to 'none'. - * @param { array } new_list - Array containing the new affiliations - * @param { array } old_list - Array containing the old affiliations - * @returns { array } - */ - - -function computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list) { - const new_jids = new_list.map(o => o.jid); - const old_jids = old_list.map(o => o.jid); // Get the new affiliations - - let delta = lodash_es_difference(new_jids, old_jids).map(jid => new_list[lodash_es_indexOf(new_jids, jid)]); - - if (!exclude_existing) { - // Get the changed affiliations - delta = delta.concat(new_list.filter(item => { - const idx = lodash_es_indexOf(old_jids, item.jid); - return idx >= 0 ? item.affiliation !== old_list[idx].affiliation : false; - })); - } - - if (remove_absentees) { - // Get the removed affiliations - delta = delta.concat(lodash_es_difference(old_jids, new_jids).map(jid => ({ - 'jid': jid, - 'affiliation': 'none' - }))); - } - - return delta; -} -;// CONCATENATED MODULE: ./src/headless/plugins/muc/muc.js - - - - - - - - - - - - - - - - - - -const OWNER_COMMANDS = ['owner']; -const ADMIN_COMMANDS = ['admin', 'ban', 'deop', 'destroy', 'member', 'op', 'revoke']; -const MODERATOR_COMMANDS = ['kick', 'mute', 'voice', 'modtools']; -const VISITOR_COMMANDS = ['nick']; -const METADATA_ATTRIBUTES = ["og:article:author", "og:article:published_time", "og:description", "og:image", "og:image:height", "og:image:width", "og:site_name", "og:title", "og:type", "og:url", "og:video:height", "og:video:secure_url", "og:video:tag", "og:video:type", "og:video:url", "og:video:width"]; -const ACTION_INFO_CODES = ['301', '303', '333', '307', '321', '322']; -const MUCSession = Model.extend({ - defaults() { - return { - 'connection_status': core_converse.ROOMSTATUS.DISCONNECTED - }; - } - -}); -/** - * Represents an open/ongoing groupchat conversation. - * @mixin - * @namespace _converse.ChatRoom - * @memberOf _converse - */ - -const ChatRoomMixin = { - defaults() { - return { - 'bookmarked': false, - 'chat_state': undefined, - 'has_activity': false, - // XEP-437 - 'hidden': shared_converse.isUniView() && !api.settings.get('singleton'), - 'hidden_occupants': !!api.settings.get('hide_muc_participants'), - 'message_type': 'groupchat', - 'name': '', - // For group chats, we distinguish between generally unread - // messages and those ones that specifically mention the - // user. - // - // To keep things simple, we reuse `num_unread` from - // _converse.ChatBox to indicate unread messages which - // mention the user and `num_unread_general` to indicate - // generally unread messages (which *includes* mentions!). - 'num_unread_general': 0, - 'num_unread': 0, - 'roomconfig': {}, - 'time_opened': this.get('time_opened') || new Date().getTime(), - 'time_sent': new Date(0).toISOString(), - 'type': shared_converse.CHATROOMS_TYPE - }; - }, - - async initialize() { - this.initialized = getOpenPromise(); - this.debouncedRejoin = lodash_es_debounce(this.rejoin, 250); - this.set('box_id', `box-${this.get('jid')}`); - this.initNotifications(); - this.initMessages(); - this.initUI(); - this.initOccupants(); - this.initDiscoModels(); // sendChatState depends on this.features - - this.registerHandlers(); - this.on('change:chat_state', this.sendChatState, this); - this.on('change:hidden', this.onHiddenChange, this); - this.on('destroy', this.removeHandlers, this); - this.ui.on('change:scrolled', this.onScrolledChanged, this); - await this.restoreSession(); - this.session.on('change:connection_status', this.onConnectionStatusChanged, this); - this.listenTo(this.occupants, 'add', this.onOccupantAdded); - this.listenTo(this.occupants, 'remove', this.onOccupantRemoved); - this.listenTo(this.occupants, 'change:show', this.onOccupantShowChanged); - this.listenTo(this.occupants, 'change:affiliation', this.createAffiliationChangeMessage); - this.listenTo(this.occupants, 'change:role', this.createRoleChangeMessage); - const restored = await this.restoreFromCache(); - - if (!restored) { - this.join(); - } - /** - * Triggered once a {@link _converse.ChatRoom} has been created and initialized. - * @event _converse#chatRoomInitialized - * @type { _converse.ChatRoom } - * @example _converse.api.listen.on('chatRoomInitialized', model => { ... }); - */ - - - await api.trigger('chatRoomInitialized', this, { - 'Synchronous': true - }); - this.initialized.resolve(); - }, - - /** - * Checks whether we're still joined and if so, restores the MUC state from cache. - * @private - * @method _converse.ChatRoom#restoreFromCache - * @returns { Boolean } Returns `true` if we're still joined, otherwise returns `false`. - */ - async restoreFromCache() { - if (this.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED && (await this.isJoined())) { - // We've restored the room from cache and we're still joined. - await new Promise(resolve => this.features.fetch({ - 'success': resolve, - 'error': resolve - })); - await this.fetchOccupants().catch(e => headless_log.error(e)); - await this.fetchMessages().catch(e => headless_log.error(e)); - return true; - } else { - this.session.save('connection_status', core_converse.ROOMSTATUS.DISCONNECTED); - this.clearOccupantsCache(); - return false; - } - }, - - /** - * Join the MUC - * @private - * @method _converse.ChatRoom#join - * @param { String } nick - The user's nickname - * @param { String } [password] - Optional password, if required by the groupchat. - * Will fall back to the `password` value stored in the room - * model (if available). - */ - async join(nick, password) { - if (this.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED) { - // We have restored a groupchat from session storage, - // so we don't send out a presence stanza again. - return this; - } // Set this early, so we don't rejoin in onHiddenChange - - - this.session.save('connection_status', core_converse.ROOMSTATUS.CONNECTING); - await this.refreshDiscoInfo(); - nick = await this.getAndPersistNickname(nick); - - if (!nick) { - utils_form.safeSave(this.session, { - 'connection_status': core_converse.ROOMSTATUS.NICKNAME_REQUIRED - }); - - if (api.settings.get('muc_show_logs_before_join')) { - await this.fetchMessages(); - } - - return this; - } - - api.send(await this.constructPresence(password)); - return this; - }, - - /** - * Clear stale cache and re-join a MUC we've been in before. - * @private - * @method _converse.ChatRoom#rejoin - */ - rejoin() { - this.session.save('connection_status', core_converse.ROOMSTATUS.DISCONNECTED); - this.registerHandlers(); - this.clearOccupantsCache(); - return this.join(); - }, - - async constructPresence(password) { - let stanza = $pres({ - 'from': shared_converse.connection.jid, - 'to': this.getRoomJIDAndNick() - }).c('x', { - 'xmlns': Strophe.NS.MUC - }).c('history', { - 'maxstanzas': this.features.get('mam_enabled') ? 0 : api.settings.get('muc_history_max_stanzas') - }).up(); - password = password || this.get('password'); - - if (password) { - stanza.cnode(Strophe.xmlElement('password', [], password)); - } - - stanza = await api.hook('constructedMUCPresence', null, stanza); - return stanza; - }, - - clearOccupantsCache() { - if (this.occupants.length) { - // Remove non-members when reconnecting - this.occupants.filter(o => !o.isMember()).forEach(o => o.destroy()); - } else { - // Looks like we haven't restored occupants from cache, so we clear it. - this.occupants.clearStore(); - } - }, - - /** - * Given the passed in MUC message, send a XEP-0333 chat marker. - * @param { _converse.MUCMessage } msg - * @param { ('received'|'displayed'|'acknowledged') } [type='displayed'] - * @param { Boolean } force - Whether a marker should be sent for the - * message, even if it didn't include a `markable` element. - */ - sendMarkerForMessage(msg, type = 'displayed', force = false) { - if (!msg || !api.settings.get('send_chat_markers').includes(type)) { - return; - } - - if (msg !== null && msg !== void 0 && msg.get('is_markable') || force) { - const key = `stanza_id ${this.get('jid')}`; - const id = msg.get(key); - - if (!id) { - headless_log.error(`Can't send marker for message without stanza ID: ${key}`); - return; - } - - const from_jid = Strophe.getBareJidFromJid(msg.get('from')); - sendMarker(from_jid, id, type, msg.get('type')); - } - }, - - /** - * Ensures that the user is subscribed to XEP-0437 Room Activity Indicators - * if `muc_subscribe_to_rai` is set to `true`. - * Only affiliated users can subscribe to RAI, but this method doesn't - * check whether the current user is affiliated because it's intended to be - * called after the MUC has been left and we don't have that information - * anymore. - * @private - * @method _converse.ChatRoom#enableRAI - */ - enableRAI() { - if (api.settings.get('muc_subscribe_to_rai')) { - const muc_domain = Strophe.getDomainFromJid(this.get('jid')); - api.user.presence.send(null, muc_domain, null, $build('rai', { - 'xmlns': Strophe.NS.RAI - })); - } - }, - - /** - * Handler that gets called when the 'hidden' flag is toggled. - * @private - * @method _converse.ChatRoom#onHiddenChange - */ - async onHiddenChange() { - const conn_status = this.session.get('connection_status'); - - if (this.get('hidden')) { - if (conn_status === core_converse.ROOMSTATUS.ENTERED && api.settings.get('muc_subscribe_to_rai') && this.getOwnAffiliation() !== 'none') { - if (conn_status !== core_converse.ROOMSTATUS.DISCONNECTED) { - this.sendMarkerForLastMessage('received', true); - await this.leave(); - } - - this.enableRAI(); - } - } else { - if (conn_status === core_converse.ROOMSTATUS.DISCONNECTED) { - this.rejoin(); - } - - this.clearUnreadMsgCounter(); - } - }, - - onOccupantAdded(occupant) { - if (shared_converse.isInfoVisible(core_converse.MUC_TRAFFIC_STATES.ENTERED) && this.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED && occupant.get('show') === 'online') { - this.updateNotifications(occupant.get('nick'), core_converse.MUC_TRAFFIC_STATES.ENTERED); - } - }, - - onOccupantRemoved(occupant) { - if (shared_converse.isInfoVisible(core_converse.MUC_TRAFFIC_STATES.EXITED) && this.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED && occupant.get('show') === 'online') { - this.updateNotifications(occupant.get('nick'), core_converse.MUC_TRAFFIC_STATES.EXITED); - } - }, - - onOccupantShowChanged(occupant) { - if (occupant.get('states').includes('303')) { - return; - } - - if (occupant.get('show') === 'offline' && shared_converse.isInfoVisible(core_converse.MUC_TRAFFIC_STATES.EXITED)) { - this.updateNotifications(occupant.get('nick'), core_converse.MUC_TRAFFIC_STATES.EXITED); - } else if (occupant.get('show') === 'online' && shared_converse.isInfoVisible(core_converse.MUC_TRAFFIC_STATES.ENTERED)) { - this.updateNotifications(occupant.get('nick'), core_converse.MUC_TRAFFIC_STATES.ENTERED); - } - }, - - async onRoomEntered() { - await this.occupants.fetchMembers(); - - if (api.settings.get('clear_messages_on_reconnection')) { - // Don't call this.clearMessages because we don't want to - // recreate promises, since that will cause some existing - // awaiters to never proceed. - await this.messages.clearStore(); // A bit hacky. No need to fetch messages after clearing - - this.messages.fetched.resolve(); - } else { - await this.fetchMessages(); - } - /** - * Triggered when the user has entered a new MUC - * @event _converse#enteredNewRoom - * @type { _converse.ChatRoom} - * @example _converse.api.listen.on('enteredNewRoom', model => { ... }); - */ - - - api.trigger('enteredNewRoom', this); - - if (api.settings.get('auto_register_muc_nickname') && (await api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid')))) { - this.registerNickname(); - } - }, - - async onConnectionStatusChanged() { - if (this.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED) { - if (this.get('hidden') && api.settings.get('muc_subscribe_to_rai') && this.getOwnAffiliation() !== 'none') { - await this.leave(); - this.enableRAI(); - } else { - await this.onRoomEntered(); - } - } - }, - - async onReconnection() { - await this.rejoin(); - this.announceReconnection(); - }, - - getMessagesCollection() { - return new shared_converse.ChatRoomMessages(); - }, - - restoreSession() { - const id = `muc.session-${shared_converse.bare_jid}-${this.get('jid')}`; - this.session = new MUCSession({ - id - }); - initStorage(this.session, id, 'session'); - return new Promise(r => this.session.fetch({ - 'success': r, - 'error': r - })); - }, - - initDiscoModels() { - let id = `converse.muc-features-${shared_converse.bare_jid}-${this.get('jid')}`; - this.features = new Model(Object.assign({ - id - }, lodash_es_zipObject(core_converse.ROOM_FEATURES, core_converse.ROOM_FEATURES.map(() => false)))); - this.features.browserStorage = shared_converse.createStore(id, 'session'); - this.features.listenTo(shared_converse, 'beforeLogout', () => this.features.browserStorage.flush()); - id = `converse.muc-config-{_converse.bare_jid}-${this.get('jid')}`; - this.config = new Model(); - this.config.browserStorage = shared_converse.createStore(id, 'session'); - this.config.listenTo(shared_converse, 'beforeLogout', () => this.config.browserStorage.flush()); - }, - - initOccupants() { - this.occupants = new shared_converse.ChatRoomOccupants(); - const id = `converse.occupants-${shared_converse.bare_jid}${this.get('jid')}`; - this.occupants.browserStorage = shared_converse.createStore(id, 'session'); - this.occupants.chatroom = this; - this.occupants.listenTo(shared_converse, 'beforeLogout', () => this.occupants.browserStorage.flush()); - }, - - fetchOccupants() { - this.occupants.fetched = new Promise(resolve => { - this.occupants.fetch({ - 'add': true, - 'silent': true, - 'success': resolve, - 'error': resolve - }); - }); - return this.occupants.fetched; - }, - - handleAffiliationChangedMessage(stanza) { - const item = sizzle_default()(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, stanza).pop(); - - if (item) { - const from = stanza.getAttribute('from'); - const type = stanza.getAttribute('type'); - const affiliation = item.getAttribute('affiliation'); - const jid = item.getAttribute('jid'); - const data = { - from, - type, - affiliation, - 'states': [], - 'show': type == 'unavailable' ? 'offline' : 'online', - 'role': item.getAttribute('role'), - 'jid': Strophe.getBareJidFromJid(jid), - 'resource': Strophe.getResourceFromJid(jid) - }; - const occupant = this.occupants.findOccupant({ - 'jid': data.jid - }); - - if (occupant) { - occupant.save(data); - } else { - this.occupants.create(data); - } - } - }, - - async handleErrorMessageStanza(stanza) { - const { - __ - } = shared_converse; - const attrs = await parseMUCMessage(stanza, this, shared_converse); - - if (!(await this.shouldShowErrorMessage(attrs))) { - return; - } - - const message = this.getMessageReferencedByError(attrs); - - if (message) { - const new_attrs = { - 'error': attrs.error, - 'error_condition': attrs.error_condition, - 'error_text': attrs.error_text, - 'error_type': attrs.error_type, - 'editable': false - }; - - if (attrs.msgid === message.get('retraction_id')) { - // The error message refers to a retraction - new_attrs.retracted = undefined; - new_attrs.retraction_id = undefined; - new_attrs.retracted_id = undefined; - - if (!attrs.error) { - if (attrs.error_condition === 'forbidden') { - new_attrs.error = __("You're not allowed to retract your message."); - } else if (attrs.error_condition === 'not-acceptable') { - new_attrs.error = __("Your retraction was not delivered because you're not present in the groupchat."); - } else { - new_attrs.error = __('Sorry, an error occurred while trying to retract your message.'); - } - } - } else if (!attrs.error) { - if (attrs.error_condition === 'forbidden') { - new_attrs.error = __("Your message was not delivered because you weren't allowed to send it."); - } else if (attrs.error_condition === 'not-acceptable') { - new_attrs.error = __("Your message was not delivered because you're not present in the groupchat."); - } else { - new_attrs.error = __('Sorry, an error occurred while trying to send your message.'); - } - } - - message.save(new_attrs); - } else { - this.createMessage(attrs); - } - }, - - /** - * Handles incoming message stanzas from the service that hosts this MUC - * @private - * @method _converse.ChatRoom#handleMessageFromMUCHost - * @param { XMLElement } stanza - */ - handleMessageFromMUCHost(stanza) { - const conn_status = this.session.get('connection_status'); - - if (conn_status === core_converse.ROOMSTATUS.ENTERED) { - // We're not interested in activity indicators when already joined to the room - return; - } - - const rai = sizzle_default()(`rai[xmlns="${Strophe.NS.RAI}"]`, stanza).pop(); - const active_mucs = Array.from((rai === null || rai === void 0 ? void 0 : rai.querySelectorAll('activity')) || []).map(m => m.textContent); - - if (active_mucs.includes(this.get('jid'))) { - this.save({ - 'has_activity': true, - 'num_unread_general': 0 // Either/or between activity and unreads - - }); - } - }, - - /** - * Handles XEP-0452 MUC Mention Notification messages - * @private - * @method _converse.ChatRoom#handleForwardedMentions - * @param { XMLElement } stanza - */ - handleForwardedMentions(stanza) { - if (this.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED) { - // Avoid counting mentions twice - return; - } - - const msgs = sizzle_default()(`mentions[xmlns="${Strophe.NS.MENTIONS}"] forwarded[xmlns="${Strophe.NS.FORWARD}"] message[type="groupchat"]`, stanza); - const muc_jid = this.get('jid'); - const mentions = msgs.filter(m => Strophe.getBareJidFromJid(m.getAttribute('from')) === muc_jid); - - if (mentions.length) { - this.save({ - 'has_activity': true, - 'num_unread': this.get('num_unread') + mentions.length - }); - mentions.forEach(async stanza => { - const attrs = await parseMUCMessage(stanza, this, shared_converse); - const data = { - stanza, - attrs, - 'chatbox': this - }; - api.trigger('message', data); - }); - } - }, - - /** - * Parses an incoming message stanza and queues it for processing. - * @private - * @method _converse.ChatRoom#handleMessageStanza - * @param { XMLElement } stanza - */ - async handleMessageStanza(stanza) { - const type = stanza.getAttribute('type'); - - if (type === 'error') { - return this.handleErrorMessageStanza(stanza); - } - - if (type === 'groupchat') { - if (isArchived(stanza)) { - // MAM messages are handled in converse-mam. - // We shouldn't get MAM messages here because - // they shouldn't have a `type` attribute. - return headless_log.warn(`Received a MAM message with type "groupchat"`); - } - - this.createInfoMessages(stanza); - this.fetchFeaturesIfConfigurationChanged(stanza); - } else if (!type) { - return this.handleForwardedMentions(stanza); - } - /** - * @typedef { Object } MUCMessageData - * An object containing the parsed { @link MUCMessageAttributes } and - * current { @link ChatRoom }. - * @property { MUCMessageAttributes } attrs - * @property { ChatRoom } chatbox - */ - - - let attrs; - - try { - attrs = await parseMUCMessage(stanza, this, shared_converse); - } catch (e) { - return headless_log.error(e.message); - } - - const data = { - stanza, - attrs, - 'chatbox': this - }; - /** - * Triggered when a groupchat message stanza has been received and parsed. - * @event _converse#message - * @type { object } - * @property { module:converse-muc~MUCMessageData } data - */ - - api.trigger('message', data); - return attrs && this.queueMessage(attrs); - }, - - /** - * Register presence and message handlers relevant to this groupchat - * @private - * @method _converse.ChatRoom#registerHandlers - */ - registerHandlers() { - const muc_jid = this.get('jid'); - const muc_domain = Strophe.getDomainFromJid(muc_jid); - this.removeHandlers(); - this.presence_handler = shared_converse.connection.addHandler(stanza => this.onPresence(stanza) || true, null, 'presence', null, null, muc_jid, { - 'ignoreNamespaceFragment': true, - 'matchBareFromJid': true - }); - this.domain_presence_handler = shared_converse.connection.addHandler(stanza => this.onPresenceFromMUCHost(stanza) || true, null, 'presence', null, null, muc_domain); - this.message_handler = shared_converse.connection.addHandler(stanza => !!this.handleMessageStanza(stanza) || true, null, 'message', null, null, muc_jid, { - 'matchBareFromJid': true - }); - this.domain_message_handler = shared_converse.connection.addHandler(stanza => this.handleMessageFromMUCHost(stanza) || true, null, 'message', null, null, muc_domain); - this.affiliation_message_handler = shared_converse.connection.addHandler(stanza => this.handleAffiliationChangedMessage(stanza) || true, Strophe.NS.MUC_USER, 'message', null, null, muc_jid); - }, - - removeHandlers() { - // Remove the presence and message handlers that were - // registered for this groupchat. - if (this.message_handler) { - shared_converse.connection && shared_converse.connection.deleteHandler(this.message_handler); - delete this.message_handler; - } - - if (this.domain_message_handler) { - shared_converse.connection && shared_converse.connection.deleteHandler(this.domain_message_handler); - delete this.domain_message_handler; - } - - if (this.presence_handler) { - shared_converse.connection && shared_converse.connection.deleteHandler(this.presence_handler); - delete this.presence_handler; - } - - if (this.domain_presence_handler) { - shared_converse.connection && shared_converse.connection.deleteHandler(this.domain_presence_handler); - delete this.domain_presence_handler; - } - - if (this.affiliation_message_handler) { - shared_converse.connection && shared_converse.connection.deleteHandler(this.affiliation_message_handler); - delete this.affiliation_message_handler; - } - - return this; - }, - - invitesAllowed() { - return api.settings.get('allow_muc_invitations') && (this.features.get('open') || this.getOwnAffiliation() === 'owner'); - }, - - getDisplayName() { - const name = this.get('name'); - - if (name) { - return name; - } else if (api.settings.get('locked_muc_domain') === 'hidden') { - return Strophe.getNodeFromJid(this.get('jid')); - } else { - return this.get('jid'); - } - }, - - /** - * Sends a message stanza to the XMPP server and expects a reflection - * or error message within a specific timeout period. - * @private - * @method _converse.ChatRoom#sendTimedMessage - * @param { _converse.Message|XMLElement } message - * @returns { Promise|Promise<_converse.TimeoutError> } Returns a promise - * which resolves with the reflected message stanza or with an error stanza or {@link _converse.TimeoutError}. - */ - sendTimedMessage(el) { - if (typeof el.tree === 'function') { - el = el.tree(); - } - - let id = el.getAttribute('id'); - - if (!id) { - // inject id if not found - id = this.getUniqueId('sendIQ'); - el.setAttribute('id', id); - } - - const promise = getOpenPromise(); - - const timeoutHandler = shared_converse.connection.addTimedHandler(shared_converse.STANZA_TIMEOUT, () => { - shared_converse.connection.deleteHandler(handler); - - const err = new shared_converse.TimeoutError('Timeout Error: No response from server'); - promise.resolve(err); - return false; - }); - - const handler = shared_converse.connection.addHandler(stanza => { - timeoutHandler && shared_converse.connection.deleteTimedHandler(timeoutHandler); - promise.resolve(stanza); - }, null, 'message', ['error', 'groupchat'], id); - - api.send(el); - return promise; - }, - - /** - * Retract one of your messages in this groupchat - * @private - * @method _converse.ChatRoom#retractOwnMessage - * @param { _converse.Message } message - The message which we're retracting. - */ - async retractOwnMessage(message) { - const __ = shared_converse.__; - const origin_id = message.get('origin_id'); - - if (!origin_id) { - throw new Error("Can't retract message without a XEP-0359 Origin ID"); - } - - const editable = message.get('editable'); - const stanza = $msg({ - 'id': utils_form.getUniqueId(), - 'to': this.get('jid'), - 'type': 'groupchat' - }).c('store', { - xmlns: Strophe.NS.HINTS - }).up().c('apply-to', { - 'id': origin_id, - 'xmlns': Strophe.NS.FASTEN - }).c('retract', { - xmlns: Strophe.NS.RETRACT - }); // Optimistic save - - message.set({ - 'retracted': new Date().toISOString(), - 'retracted_id': origin_id, - 'retraction_id': stanza.nodeTree.getAttribute('id'), - 'editable': false - }); - const result = await this.sendTimedMessage(stanza); - - if (utils_form.isErrorStanza(result)) { - headless_log.error(result); - } else if (result instanceof shared_converse.TimeoutError) { - headless_log.error(result); - message.save({ - editable, - 'error_type': 'timeout', - 'error': __('A timeout happened while while trying to retract your message.'), - 'retracted': undefined, - 'retracted_id': undefined, - 'retraction_id': undefined - }); - } - }, - - /** - * Retract someone else's message in this groupchat. - * @private - * @method _converse.ChatRoom#retractOtherMessage - * @param { _converse.Message } message - The message which we're retracting. - * @param { string } [reason] - The reason for retracting the message. - * @example - * const room = await api.rooms.get(jid); - * const message = room.messages.findWhere({'body': 'Get rich quick!'}); - * room.retractOtherMessage(message, 'spam'); - */ - async retractOtherMessage(message, reason) { - const editable = message.get('editable'); // Optimistic save - - message.save({ - 'moderated': 'retracted', - 'moderated_by': shared_converse.bare_jid, - 'moderated_id': message.get('msgid'), - 'moderation_reason': reason, - 'editable': false - }); - const result = await this.sendRetractionIQ(message, reason); - - if (result === null || utils_form.isErrorStanza(result)) { - // Undo the save if something went wrong - message.save({ - editable, - 'moderated': undefined, - 'moderated_by': undefined, - 'moderated_id': undefined, - 'moderation_reason': undefined - }); - } - - return result; - }, - - /** - * Sends an IQ stanza to the XMPP server to retract a message in this groupchat. - * @private - * @method _converse.ChatRoom#sendRetractionIQ - * @param { _converse.Message } message - The message which we're retracting. - * @param { string } [reason] - The reason for retracting the message. - */ - sendRetractionIQ(message, reason) { - const iq = $iq({ - 'to': this.get('jid'), - 'type': 'set' - }).c('apply-to', { - 'id': message.get(`stanza_id ${this.get('jid')}`), - 'xmlns': Strophe.NS.FASTEN - }).c('moderate', { - xmlns: Strophe.NS.MODERATE - }).c('retract', { - xmlns: Strophe.NS.RETRACT - }).up().c('reason').t(reason || ''); - return api.sendIQ(iq, null, false); - }, - - /** - * Sends an IQ stanza to the XMPP server to destroy this groupchat. Not - * to be confused with the {@link _converse.ChatRoom#destroy} - * method, which simply removes the room from the local browser storage cache. - * @private - * @method _converse.ChatRoom#sendDestroyIQ - * @param { string } [reason] - The reason for destroying the groupchat. - * @param { string } [new_jid] - The JID of the new groupchat which replaces this one. - */ - sendDestroyIQ(reason, new_jid) { - const destroy = $build('destroy'); - - if (new_jid) { - destroy.attrs({ - 'jid': new_jid - }); - } - - const iq = $iq({ - 'to': this.get('jid'), - 'type': 'set' - }).c('query', { - 'xmlns': Strophe.NS.MUC_OWNER - }).cnode(destroy.node); - - if (reason && reason.length > 0) { - iq.c('reason', reason); - } - - return api.sendIQ(iq); - }, - - /** - * Leave the groupchat. - * @private - * @method _converse.ChatRoom#leave - * @param { string } [exit_msg] - Message to indicate your reason for leaving - */ - async leave(exit_msg) { - var _converse$disco_entit; - - this.features.destroy(); - const disco_entity = (_converse$disco_entit = shared_converse.disco_entities) === null || _converse$disco_entit === void 0 ? void 0 : _converse$disco_entit.get(this.get('jid')); - - if (disco_entity) { - await new Promise((success, error) => disco_entity.destroy({ - success, - error - })); - } - - if (api.connection.connected()) { - api.user.presence.send('unavailable', this.getRoomJIDAndNick(), exit_msg); - } - - utils_form.safeSave(this.session, { - 'connection_status': core_converse.ROOMSTATUS.DISCONNECTED - }); - }, - - async close(ev) { - await this.leave(); - - if (api.settings.get('auto_register_muc_nickname') === 'unregister' && (await api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid')))) { - this.unregisterNickname(); - } - - this.occupants.clearStore(); - - if ((ev === null || ev === void 0 ? void 0 : ev.name) !== 'closeAllChatBoxes' && api.settings.get('muc_clear_messages_on_leave')) { - this.clearMessages(); - } // Delete the session model - - - await new Promise(resolve => this.session.destroy({ - 'success': resolve, - 'error': (m, e) => { - headless_log.error(e); - resolve(); - } - })); // Delete the features model - - await new Promise(resolve => this.features.destroy({ - 'success': resolve, - 'error': (m, e) => { - headless_log.error(e); - resolve(); - } - })); - return shared_converse.ChatBox.prototype.close.call(this); - }, - - canModerateMessages() { - const self = this.getOwnOccupant(); - return self && self.isModerator() && api.disco.supports(Strophe.NS.MODERATE, this.get('jid')); - }, - - /** - * Return an array of unique nicknames based on all occupants and messages in this MUC. - * @private - * @method _converse.ChatRoom#getAllKnownNicknames - * @returns { String[] } - */ - getAllKnownNicknames() { - return [...new Set([...this.occupants.map(o => o.get('nick')), ...this.messages.map(m => m.get('nick'))])].filter(n => n); - }, - - getAllKnownNicknamesRegex() { - const longNickString = this.getAllKnownNicknames().map(n => parse_helpers.escapeRegexString(n)).join('|'); - return RegExp(`(?:\\p{P}|\\p{Z}|^)@(${longNickString})(?![\\w@-])`, 'uig'); - }, - - getOccupantByJID(jid) { - return this.occupants.findOccupant({ - jid - }); - }, - - getOccupantByNickname(nick) { - return this.occupants.findOccupant({ - nick - }); - }, - - /** - * Given a text message, look for `@` mentions and turn them into - * XEP-0372 references - * @param { String } text - */ - parseTextForReferences(text) { - const mentions_regex = /(\p{P}|\p{Z}|^)([@][\w_-]+(?:\.\w+)*)/giu; - - if (!text || !mentions_regex.test(text)) { - return [text, []]; - } - - const getMatchingNickname = parse_helpers.findFirstMatchInArray(this.getAllKnownNicknames()); - - const uriFromNickname = nickname => { - const jid = this.get('jid'); - const occupant = this.getOccupant(nickname) || this.getOccupant(jid); - const uri = this.features.get('nonanonymous') && (occupant === null || occupant === void 0 ? void 0 : occupant.get('jid')) || `${jid}/${nickname}`; - return encodeURI(`xmpp:${uri}`); - }; - - const matchToReference = match => { - let at_sign_index = match[0].indexOf('@'); - - if (match[0][at_sign_index + 1] === '@') { - // edge-case - at_sign_index += 1; - } - - const begin = match.index + at_sign_index; - const end = begin + match[0].length - at_sign_index; - const value = getMatchingNickname(match[1]); - const type = 'mention'; - const uri = uriFromNickname(value); - return { - begin, - end, - value, - type, - uri - }; - }; - - const regex = this.getAllKnownNicknamesRegex(); - const mentions = [...text.matchAll(regex)].filter(m => !m[0].startsWith('/')); - const references = mentions.map(matchToReference); - const [updated_message, updated_references] = parse_helpers.reduceTextFromReferences(text, references); - return [updated_message, updated_references]; - }, - - getOutgoingMessageAttributes(attrs) { - const is_spoiler = this.get('composing_spoiler'); - let text = '', - references; - - if (attrs !== null && attrs !== void 0 && attrs.body) { - [text, references] = this.parseTextForReferences(attrs.body); - } - - const origin_id = utils_form.getUniqueId(); - const body = text ? utils_form.httpToGeoUri(utils_form.shortnamesToUnicode(text), shared_converse) : undefined; - return Object.assign({}, attrs, { - body, - is_spoiler, - origin_id, - references, - 'id': origin_id, - 'msgid': origin_id, - 'from': `${this.get('jid')}/${this.get('nick')}`, - 'fullname': this.get('nick'), - 'is_only_emojis': text ? utils_form.isOnlyEmojis(text) : false, - 'message': body, - 'nick': this.get('nick'), - 'sender': 'me', - 'type': 'groupchat' - }, getMediaURLs(text)); - }, - - /** - * Utility method to construct the JID for the current user as occupant of the groupchat. - * @private - * @method _converse.ChatRoom#getRoomJIDAndNick - * @returns {string} - The groupchat JID with the user's nickname added at the end. - * @example groupchat@conference.example.org/nickname - */ - getRoomJIDAndNick() { - const nick = this.get('nick'); - const jid = Strophe.getBareJidFromJid(this.get('jid')); - return jid + (nick !== null ? `/${nick}` : ''); - }, - - /** - * Sends a message with the current XEP-0085 chat state of the user - * as taken from the `chat_state` attribute of the {@link _converse.ChatRoom}. - * @private - * @method _converse.ChatRoom#sendChatState - */ - sendChatState() { - if (!api.settings.get('send_chat_state_notifications') || !this.get('chat_state') || this.session.get('connection_status') !== core_converse.ROOMSTATUS.ENTERED || this.features.get('moderated') && this.getOwnRole() === 'visitor') { - return; - } - - const allowed = api.settings.get('send_chat_state_notifications'); - - if (Array.isArray(allowed) && !allowed.includes(this.get('chat_state'))) { - return; - } - - const chat_state = this.get('chat_state'); - - if (chat_state === shared_converse.GONE) { - // is not applicable within MUC context - return; - } - - api.send($msg({ - 'to': this.get('jid'), - 'type': 'groupchat' - }).c(chat_state, { - 'xmlns': Strophe.NS.CHATSTATES - }).up().c('no-store', { - 'xmlns': Strophe.NS.HINTS - }).up().c('no-permanent-store', { - 'xmlns': Strophe.NS.HINTS - })); - }, - - /** - * Send a direct invitation as per XEP-0249 - * @private - * @method _converse.ChatRoom#directInvite - * @param { String } recipient - JID of the person being invited - * @param { String } [reason] - Reason for the invitation - */ - directInvite(recipient, reason) { - if (this.features.get('membersonly')) { - // When inviting to a members-only groupchat, we first add - // the person to the member list by giving them an - // affiliation of 'member' otherwise they won't be able to join. - this.updateMemberLists([{ - 'jid': recipient, - 'affiliation': 'member', - 'reason': reason - }]); - } - - const attrs = { - 'xmlns': 'jabber:x:conference', - 'jid': this.get('jid') - }; - - if (reason !== null) { - attrs.reason = reason; - } - - if (this.get('password')) { - attrs.password = this.get('password'); - } - - const invitation = $msg({ - 'from': shared_converse.connection.jid, - 'to': recipient, - 'id': utils_form.getUniqueId() - }).c('x', attrs); - api.send(invitation); - /** - * After the user has sent out a direct invitation (as per XEP-0249), - * to a roster contact, asking them to join a room. - * @event _converse#chatBoxMaximized - * @type {object} - * @property {_converse.ChatRoom} room - * @property {string} recipient - The JID of the person being invited - * @property {string} reason - The original reason for the invitation - * @example _converse.api.listen.on('chatBoxMaximized', view => { ... }); - */ - - api.trigger('roomInviteSent', { - 'room': this, - 'recipient': recipient, - 'reason': reason - }); - }, - - /** - * Refresh the disco identity, features and fields for this {@link _converse.ChatRoom}. - * *features* are stored on the features {@link Model} attribute on this {@link _converse.ChatRoom}. - * *fields* are stored on the config {@link Model} attribute on this {@link _converse.ChatRoom}. - * @private - * @returns {Promise} - */ - refreshDiscoInfo() { - return api.disco.refresh(this.get('jid')).then(() => this.getDiscoInfo()).catch(e => headless_log.error(e)); - }, - - /** - * Fetch the *extended* MUC info from the server and cache it locally - * https://xmpp.org/extensions/xep-0045.html#disco-roominfo - * @private - * @method _converse.ChatRoom#getDiscoInfo - * @returns {Promise} - */ - getDiscoInfo() { - return api.disco.getIdentity('conference', 'text', this.get('jid')).then(identity => this.save({ - 'name': identity === null || identity === void 0 ? void 0 : identity.get('name') - })).then(() => this.getDiscoInfoFields()).then(() => this.getDiscoInfoFeatures()).catch(e => headless_log.error(e)); - }, - - /** - * Fetch the *extended* MUC info fields from the server and store them locally - * in the `config` {@link Model} attribute. - * See: https://xmpp.org/extensions/xep-0045.html#disco-roominfo - * @private - * @method _converse.ChatRoom#getDiscoInfoFields - * @returns {Promise} - */ - async getDiscoInfoFields() { - const fields = await api.disco.getFields(this.get('jid')); - const config = fields.reduce((config, f) => { - const name = f.get('var'); - - if (name && name.startsWith('muc#roominfo_')) { - config[name.replace('muc#roominfo_', '')] = f.get('value'); - } - - return config; - }, {}); - this.config.save(config); - }, - - /** - * Use converse-disco to populate the features {@link Model} which - * is stored as an attibute on this {@link _converse.ChatRoom}. - * The results may be cached. If you want to force fetching the features from the - * server, call {@link _converse.ChatRoom#refreshDiscoInfo} instead. - * @private - * @returns {Promise} - */ - async getDiscoInfoFeatures() { - const features = await api.disco.getFeatures(this.get('jid')); - const attrs = Object.assign(lodash_es_zipObject(core_converse.ROOM_FEATURES, core_converse.ROOM_FEATURES.map(() => false)), { - 'fetched': new Date().toISOString() - }); - features.each(feature => { - const fieldname = feature.get('var'); - - if (!fieldname.startsWith('muc_')) { - if (fieldname === Strophe.NS.MAM) { - attrs.mam_enabled = true; - } - - return; - } - - attrs[fieldname.replace('muc_', '')] = true; - }); - this.features.save(attrs); - }, - - /** - * Given a element, return a copy with a child if - * we can find a value for it in this rooms config. - * @private - * @method _converse.ChatRoom#addFieldValue - * @returns { Element } - */ - addFieldValue(field) { - const type = field.getAttribute('type'); - - if (type === 'fixed') { - return field; - } - - const fieldname = field.getAttribute('var').replace('muc#roomconfig_', ''); - const config = this.get('roomconfig'); - - if (fieldname in config) { - let values; - - switch (type) { - case 'boolean': - values = [config[fieldname] ? 1 : 0]; - break; - - case 'list-multi': - values = config[fieldname]; - break; - - default: - values = [config[fieldname]]; - } - - field.innerHTML = values.map(v => $build('value').t(v)).join(''); - } - - return field; - }, - - /** - * Automatically configure the groupchat based on this model's - * 'roomconfig' data. - * @private - * @method _converse.ChatRoom#autoConfigureChatRoom - * @returns { Promise } - * Returns a promise which resolves once a response IQ has - * been received. - */ - async autoConfigureChatRoom() { - const stanza = await this.fetchRoomConfiguration(); - const fields = sizzle_default()('field', stanza); - const configArray = fields.map(f => this.addFieldValue(f)); - - if (configArray.length) { - return this.sendConfiguration(configArray); - } - }, - - /** - * Send an IQ stanza to fetch the groupchat configuration data. - * Returns a promise which resolves once the response IQ - * has been received. - * @private - * @method _converse.ChatRoom#fetchRoomConfiguration - * @returns { Promise } - */ - fetchRoomConfiguration() { - return api.sendIQ($iq({ - 'to': this.get('jid'), - 'type': 'get' - }).c('query', { - xmlns: Strophe.NS.MUC_OWNER - })); - }, - - /** - * Sends an IQ stanza with the groupchat configuration. - * @private - * @method _converse.ChatRoom#sendConfiguration - * @param { Array } config - The groupchat configuration - * @returns { Promise } - A promise which resolves with - * the `result` stanza received from the XMPP server. - */ - sendConfiguration(config = []) { - const iq = $iq({ - to: this.get('jid'), - type: 'set' - }).c('query', { - xmlns: Strophe.NS.MUC_OWNER - }).c('x', { - xmlns: Strophe.NS.XFORM, - type: 'submit' - }); - config.forEach(node => iq.cnode(node).up()); - return api.sendIQ(iq); - }, - - onCommandError(err) { - const { - __ - } = shared_converse; - headless_log.fatal(err); - - const message = __('Sorry, an error happened while running the command.') + ' ' + __("Check your browser's developer console for details."); - - this.createMessage({ - message, - 'type': 'error' - }); - }, - - getNickOrJIDFromCommandArgs(args) { - const { - __ - } = shared_converse; - - if (utils_form.isValidJID(args.trim())) { - return args.trim(); - } - - if (!args.startsWith('@')) { - args = '@' + args; - } - - const [text, references] = this.parseTextForReferences(args); // eslint-disable-line no-unused-vars - - if (!references.length) { - const message = __("Error: couldn't find a groupchat participant based on your arguments"); - - this.createMessage({ - message, - 'type': 'error' - }); - return; - } - - if (references.length > 1) { - const message = __('Error: found multiple groupchat participant based on your arguments'); - - this.createMessage({ - message, - 'type': 'error' - }); - return; - } - - const nick_or_jid = references.pop().value; - const reason = args.split(nick_or_jid, 2)[1]; - - if (reason && !reason.startsWith(' ')) { - const message = __("Error: couldn't find a groupchat participant based on your arguments"); - - this.createMessage({ - message, - 'type': 'error' - }); - return; - } - - return nick_or_jid; - }, - - validateRoleOrAffiliationChangeArgs(command, args) { - const { - __ - } = shared_converse; - - if (!args) { - const message = __('Error: the "%1$s" command takes two arguments, the user\'s nickname and optionally a reason.', command); - - this.createMessage({ - message, - 'type': 'error' - }); - return false; - } - - return true; - }, - - getAllowedCommands() { - let allowed_commands = ['clear', 'help', 'me', 'nick', 'register']; - - if (this.config.get('changesubject') || ['owner', 'admin'].includes(this.getOwnAffiliation())) { - allowed_commands = [...allowed_commands, ...['subject', 'topic']]; - } - - const occupant = this.occupants.findWhere({ - 'jid': shared_converse.bare_jid - }); - - if (this.verifyAffiliations(['owner'], occupant, false)) { - allowed_commands = allowed_commands.concat(OWNER_COMMANDS).concat(ADMIN_COMMANDS); - } else if (this.verifyAffiliations(['admin'], occupant, false)) { - allowed_commands = allowed_commands.concat(ADMIN_COMMANDS); - } - - if (this.verifyRoles(['moderator'], occupant, false)) { - allowed_commands = allowed_commands.concat(MODERATOR_COMMANDS).concat(VISITOR_COMMANDS); - } else if (!this.verifyRoles(['visitor', 'participant', 'moderator'], occupant, false)) { - allowed_commands = allowed_commands.concat(VISITOR_COMMANDS); - } - - allowed_commands.sort(); - - if (Array.isArray(api.settings.get('muc_disable_slash_commands'))) { - return allowed_commands.filter(c => !api.settings.get('muc_disable_slash_commands').includes(c)); - } else { - return allowed_commands; - } - }, - - verifyAffiliations(affiliations, occupant, show_error = true) { - const { - __ - } = shared_converse; - - if (!Array.isArray(affiliations)) { - throw new TypeError('affiliations must be an Array'); - } - - if (!affiliations.length) { - return true; - } - - occupant = occupant || this.occupants.findWhere({ - 'jid': shared_converse.bare_jid - }); - - if (occupant) { - const a = occupant.get('affiliation'); - - if (affiliations.includes(a)) { - return true; - } - } - - if (show_error) { - const message = __('Forbidden: you do not have the necessary affiliation in order to do that.'); - - this.createMessage({ - message, - 'type': 'error' - }); - } - - return false; - }, - - verifyRoles(roles, occupant, show_error = true) { - const { - __ - } = shared_converse; - - if (!Array.isArray(roles)) { - throw new TypeError('roles must be an Array'); - } - - if (!roles.length) { - return true; - } - - occupant = occupant || this.occupants.findWhere({ - 'jid': shared_converse.bare_jid - }); - - if (occupant) { - const role = occupant.get('role'); - - if (roles.includes(role)) { - return true; - } - } - - if (show_error) { - const message = __('Forbidden: you do not have the necessary role in order to do that.'); - - this.createMessage({ - message, - 'type': 'error' - }); - } - - return false; - }, - - /** - * Returns the `role` which the current user has in this MUC - * @private - * @method _converse.ChatRoom#getOwnRole - * @returns { ('none'|'visitor'|'participant'|'moderator') } - */ - getOwnRole() { - var _this$getOwnOccupant, _this$getOwnOccupant$; - - return (_this$getOwnOccupant = this.getOwnOccupant()) === null || _this$getOwnOccupant === void 0 ? void 0 : (_this$getOwnOccupant$ = _this$getOwnOccupant.attributes) === null || _this$getOwnOccupant$ === void 0 ? void 0 : _this$getOwnOccupant$.role; - }, - - /** - * Returns the `affiliation` which the current user has in this MUC - * @private - * @method _converse.ChatRoom#getOwnAffiliation - * @returns { ('none'|'outcast'|'member'|'admin'|'owner') } - */ - getOwnAffiliation() { - var _this$getOwnOccupant2, _this$getOwnOccupant3; - - return ((_this$getOwnOccupant2 = this.getOwnOccupant()) === null || _this$getOwnOccupant2 === void 0 ? void 0 : (_this$getOwnOccupant3 = _this$getOwnOccupant2.attributes) === null || _this$getOwnOccupant3 === void 0 ? void 0 : _this$getOwnOccupant3.affiliation) || 'none'; - }, - - /** - * Get the {@link _converse.ChatRoomOccupant} instance which - * represents the current user. - * @private - * @method _converse.ChatRoom#getOwnOccupant - * @returns { _converse.ChatRoomOccupant } - */ - getOwnOccupant() { - return this.occupants.findWhere({ - 'jid': shared_converse.bare_jid - }); - }, - - /** - * Send an IQ stanza to modify an occupant's role - * @private - * @method _converse.ChatRoom#setRole - * @param { _converse.ChatRoomOccupant } occupant - * @param { String } role - * @param { String } reason - * @param { function } onSuccess - callback for a succesful response - * @param { function } onError - callback for an error response - */ - setRole(occupant, role, reason, onSuccess, onError) { - const item = $build('item', { - 'nick': occupant.get('nick'), - role - }); - const iq = $iq({ - 'to': this.get('jid'), - 'type': 'set' - }).c('query', { - xmlns: Strophe.NS.MUC_ADMIN - }).cnode(item.node); - - if (reason !== null) { - iq.c('reason', reason); - } - - return api.sendIQ(iq).then(onSuccess).catch(onError); - }, - - /** - * @private - * @method _converse.ChatRoom#getOccupant - * @param { String } nickname_or_jid - The nickname or JID of the occupant to be returned - * @returns { _converse.ChatRoomOccupant } - */ - getOccupant(nickname_or_jid) { - return utils_form.isValidJID(nickname_or_jid) ? this.getOccupantByJID(nickname_or_jid) : this.getOccupantByNickname(nickname_or_jid); - }, - - /** - * Return an array of occupant models that have the required role - * @private - * @method _converse.ChatRoom#getOccupantsWithRole - * @param { String } role - * @returns { _converse.ChatRoomOccupant[] } - */ - getOccupantsWithRole(role) { - return this.getOccupantsSortedBy('nick').filter(o => o.get('role') === role).map(item => { - return { - 'jid': item.get('jid'), - 'nick': item.get('nick'), - 'role': item.get('role') - }; - }); - }, - - /** - * Return an array of occupant models that have the required affiliation - * @private - * @method _converse.ChatRoom#getOccupantsWithAffiliation - * @param { String } affiliation - * @returns { _converse.ChatRoomOccupant[] } - */ - getOccupantsWithAffiliation(affiliation) { - return this.getOccupantsSortedBy('nick').filter(o => o.get('affiliation') === affiliation).map(item => { - return { - 'jid': item.get('jid'), - 'nick': item.get('nick'), - 'affiliation': item.get('affiliation') - }; - }); - }, - - /** - * Return an array of occupant models, sorted according to the passed-in attribute. - * @private - * @method _converse.ChatRoom#getOccupantsSortedBy - * @param { String } attr - The attribute to sort the returned array by - * @returns { _converse.ChatRoomOccupant[] } - */ - getOccupantsSortedBy(attr) { - return Array.from(this.occupants.models).sort((a, b) => a.get(attr) < b.get(attr) ? -1 : a.get(attr) > b.get(attr) ? 1 : 0); - }, - - /** - * Fetch the lists of users with the given affiliations. - * Then compute the delta between those users and - * the passed in members, and if it exists, send the delta - * to the XMPP server to update the member list. - * @private - * @method _converse.ChatRoom#updateMemberLists - * @param { object } members - Map of member jids and affiliations. - * @returns { Promise } - * A promise which is resolved once the list has been - * updated or once it's been established there's no need - * to update the list. - */ - async updateMemberLists(members) { - const muc_jid = this.get('jid'); - const all_affiliations = ['member', 'admin', 'owner']; - const aff_lists = await Promise.all(all_affiliations.map(a => getAffiliationList(a, muc_jid))); - const old_members = aff_lists.reduce((acc, val) => utils_form.isErrorObject(val) ? acc : [...val, ...acc], []); - await setAffiliations(muc_jid, computeAffiliationsDelta(true, false, members, old_members)); - await this.occupants.fetchMembers(); - }, - - /** - * Given a nick name, save it to the model state, otherwise, look - * for a server-side reserved nickname or default configured - * nickname and if found, persist that to the model state. - * @private - * @method _converse.ChatRoom#getAndPersistNickname - * @returns { Promise } A promise which resolves with the nickname - */ - async getAndPersistNickname(nick) { - nick = nick || this.get('nick') || (await this.getReservedNick()) || shared_converse.getDefaultMUCNickname(); - - if (nick) { - this.save({ - nick - }, { - 'silent': true - }); - } - - return nick; - }, - - /** - * Use service-discovery to ask the XMPP server whether - * this user has a reserved nickname for this groupchat. - * If so, we'll use that, otherwise we render the nickname form. - * @private - * @method _converse.ChatRoom#getReservedNick - * @returns { Promise } A promise which resolves with the reserved nick or null - */ - async getReservedNick() { - const stanza = $iq({ - 'to': this.get('jid'), - 'from': shared_converse.connection.jid, - 'type': 'get' - }).c('query', { - 'xmlns': Strophe.NS.DISCO_INFO, - 'node': 'x-roomuser-item' - }); - const result = await api.sendIQ(stanza, null, false); - - if (utils_form.isErrorObject(result)) { - throw result; - } // Result might be undefined due to a timeout - - - const identity_el = result === null || result === void 0 ? void 0 : result.querySelector('query[node="x-roomuser-item"] identity'); - return identity_el ? identity_el.getAttribute('name') : null; - }, - - /** - * Send an IQ stanza to the MUC to register this user's nickname. - * This sets the user's affiliation to 'member' (if they weren't affiliated - * before) and reserves the nickname for this user, thereby preventing other - * users from using it in this MUC. - * See https://xmpp.org/extensions/xep-0045.html#register - * @private - * @method _converse.ChatRoom#registerNickname - */ - async registerNickname() { - const { - __ - } = shared_converse; - const nick = this.get('nick'); - const jid = this.get('jid'); - let iq, err_msg; - - try { - iq = await api.sendIQ($iq({ - 'to': jid, - 'type': 'get' - }).c('query', { - 'xmlns': Strophe.NS.MUC_REGISTER - })); - } catch (e) { - if (sizzle_default()(`not-allowed[xmlns="${Strophe.NS.STANZAS}"]`, e).length) { - err_msg = __("You're not allowed to register yourself in this groupchat."); - } else if (sizzle_default()(`registration-required[xmlns="${Strophe.NS.STANZAS}"]`, e).length) { - err_msg = __("You're not allowed to register in this groupchat because it's members-only."); - } - - headless_log.error(e); - return err_msg; - } - - const required_fields = sizzle_default()('field required', iq).map(f => f.parentElement); - - if (required_fields.length > 1 && required_fields[0].getAttribute('var') !== 'muc#register_roomnick') { - return headless_log.error(`Can't register the user register in the groupchat ${jid} due to the required fields`); - } - - try { - await api.sendIQ($iq({ - 'to': jid, - 'type': 'set' - }).c('query', { - 'xmlns': Strophe.NS.MUC_REGISTER - }).c('x', { - 'xmlns': Strophe.NS.XFORM, - 'type': 'submit' - }).c('field', { - 'var': 'FORM_TYPE' - }).c('value').t('http://jabber.org/protocol/muc#register').up().up().c('field', { - 'var': 'muc#register_roomnick' - }).c('value').t(nick)); - } catch (e) { - if (sizzle_default()(`service-unavailable[xmlns="${Strophe.NS.STANZAS}"]`, e).length) { - err_msg = __("Can't register your nickname in this groupchat, it doesn't support registration."); - } else if (sizzle_default()(`bad-request[xmlns="${Strophe.NS.STANZAS}"]`, e).length) { - err_msg = __("Can't register your nickname in this groupchat, invalid data form supplied."); - } - - headless_log.error(err_msg); - headless_log.error(e); - return err_msg; - } - }, - - /** - * Send an IQ stanza to the MUC to unregister this user's nickname. - * If the user had a 'member' affiliation, it'll be removed and their - * nickname will no longer be reserved and can instead be used (and - * registered) by other users. - * @private - * @method _converse.ChatRoom#unregisterNickname - */ - unregisterNickname() { - const iq = $iq({ - 'to': this.get('jid'), - 'type': 'set' - }).c('query', { - 'xmlns': Strophe.NS.MUC_REGISTER - }).c('remove'); - return api.sendIQ(iq).catch(e => headless_log.error(e)); - }, - - /** - * Given a presence stanza, update the occupant model based on its contents. - * @private - * @method _converse.ChatRoom#updateOccupantsOnPresence - * @param { XMLElement } pres - The presence stanza - */ - updateOccupantsOnPresence(pres) { - var _occupant$attributes, _occupant$attributes2; - - const data = parseMUCPresence(pres); - - if (data.type === 'error' || !data.jid && !data.nick) { - return true; - } - - const occupant = this.occupants.findOccupant(data); // Destroy an unavailable occupant if this isn't a nick change operation and if they're not affiliated - - if (data.type === 'unavailable' && occupant && !data.states.includes(core_converse.MUC_NICK_CHANGED_CODE) && !['admin', 'owner', 'member'].includes(data['affiliation'])) { - // Before destroying we set the new data, so that we can show the disconnection message - occupant.set(data); - occupant.destroy(); - return; - } - - const jid = data.jid || ''; - const attributes = Object.assign(data, { - 'jid': Strophe.getBareJidFromJid(jid) || (occupant === null || occupant === void 0 ? void 0 : (_occupant$attributes = occupant.attributes) === null || _occupant$attributes === void 0 ? void 0 : _occupant$attributes.jid), - 'resource': Strophe.getResourceFromJid(jid) || (occupant === null || occupant === void 0 ? void 0 : (_occupant$attributes2 = occupant.attributes) === null || _occupant$attributes2 === void 0 ? void 0 : _occupant$attributes2.resource) - }); - - if (occupant) { - occupant.save(attributes); - } else { - this.occupants.create(attributes); - } - }, - - fetchFeaturesIfConfigurationChanged(stanza) { - // 104: configuration change - // 170: logging enabled - // 171: logging disabled - // 172: room no longer anonymous - // 173: room now semi-anonymous - // 174: room now fully anonymous - const codes = ['104', '170', '171', '172', '173', '174']; - - if (sizzle_default()('status', stanza).filter(e => codes.includes(e.getAttribute('status'))).length) { - this.refreshDiscoInfo(); - } - }, - - /** - * Given two JIDs, which can be either user JIDs or MUC occupant JIDs, - * determine whether they belong to the same user. - * @private - * @method _converse.ChatRoom#isSameUser - * @param { String } jid1 - * @param { String } jid2 - * @returns { Boolean } - */ - isSameUser(jid1, jid2) { - const bare_jid1 = Strophe.getBareJidFromJid(jid1); - const bare_jid2 = Strophe.getBareJidFromJid(jid2); - const resource1 = Strophe.getResourceFromJid(jid1); - const resource2 = Strophe.getResourceFromJid(jid2); - - if (utils_form.isSameBareJID(jid1, jid2)) { - if (bare_jid1 === this.get('jid')) { - // MUC JIDs - return resource1 === resource2; - } else { - return true; - } - } else { - const occupant1 = bare_jid1 === this.get('jid') ? this.occupants.findOccupant({ - 'nick': resource1 - }) : this.occupants.findOccupant({ - 'jid': bare_jid1 - }); - const occupant2 = bare_jid2 === this.get('jid') ? this.occupants.findOccupant({ - 'nick': resource2 - }) : this.occupants.findOccupant({ - 'jid': bare_jid2 - }); - return occupant1 === occupant2; - } - }, - - async isSubjectHidden() { - const jids = await api.user.settings.get('mucs_with_hidden_subject', []); - return jids.includes(this.get('jid')); - }, - - async toggleSubjectHiddenState() { - const muc_jid = this.get('jid'); - const jids = await api.user.settings.get('mucs_with_hidden_subject', []); - - if (jids.includes(this.get('jid'))) { - api.user.settings.set('mucs_with_hidden_subject', jids.filter(jid => jid !== muc_jid)); - } else { - api.user.settings.set('mucs_with_hidden_subject', [...jids, muc_jid]); - } - }, - - /** - * Handle a possible subject change and return `true` if so. - * @private - * @method _converse.ChatRoom#handleSubjectChange - * @param { object } attrs - Attributes representing a received - * message, as returned by {@link parseMUCMessage} - */ - async handleSubjectChange(attrs) { - const __ = shared_converse.__; - - if (typeof attrs.subject === 'string' && !attrs.thread && !attrs.message) { - // https://xmpp.org/extensions/xep-0045.html#subject-mod - // ----------------------------------------------------- - // The subject is changed by sending a message of type "groupchat" to the , - // where the MUST contain a element that specifies the new subject but - // MUST NOT contain a element (or a element). - const subject = attrs.subject; - const author = attrs.nick; - utils_form.safeSave(this, { - 'subject': { - author, - 'text': attrs.subject || '' - } - }); - - if (!attrs.is_delayed && author) { - const message = subject ? __('Topic set by %1$s', author) : __('Topic cleared by %1$s', author); - const prev_msg = this.messages.last(); - - if ((prev_msg === null || prev_msg === void 0 ? void 0 : prev_msg.get('nick')) !== attrs.nick || (prev_msg === null || prev_msg === void 0 ? void 0 : prev_msg.get('type')) !== 'info' || (prev_msg === null || prev_msg === void 0 ? void 0 : prev_msg.get('message')) !== message) { - this.createMessage({ - message, - 'nick': attrs.nick, - 'type': 'info' - }); - } - - if (await this.isSubjectHidden()) { - this.toggleSubjectHiddenState(); - } - } - - return true; - } - - return false; - }, - - /** - * Set the subject for this {@link _converse.ChatRoom} - * @private - * @method _converse.ChatRoom#setSubject - * @param { String } value - */ - setSubject(value = '') { - api.send($msg({ - to: this.get('jid'), - from: shared_converse.connection.jid, - type: 'groupchat' - }).c('subject', { - xmlns: 'jabber:client' - }).t(value).tree()); - }, - - /** - * Is this a chat state notification that can be ignored, - * because it's old or because it's from us. - * @private - * @method _converse.ChatRoom#ignorableCSN - * @param { Object } attrs - The message attributes - */ - ignorableCSN(attrs) { - return attrs.chat_state && !attrs.body && (attrs.is_delayed || this.isOwnMessage(attrs)); - }, - - /** - * Determines whether the message is from ourselves by checking - * the `from` attribute. Doesn't check the `type` attribute. - * @private - * @method _converse.ChatRoom#isOwnMessage - * @param { Object|XMLElement|_converse.Message } msg - * @returns { boolean } - */ - isOwnMessage(msg) { - let from; - - if (lodash_es_isElement(msg)) { - from = msg.getAttribute('from'); - } else if (msg instanceof shared_converse.Message) { - from = msg.get('from'); - } else { - from = msg.from; - } - - return Strophe.getResourceFromJid(from) == this.get('nick'); - }, - - getUpdatedMessageAttributes(message, attrs) { - const new_attrs = shared_converse.ChatBox.prototype.getUpdatedMessageAttributes.call(this, message, attrs); - - if (this.isOwnMessage(attrs)) { - const stanza_id_keys = Object.keys(attrs).filter(k => k.startsWith('stanza_id')); - Object.assign(new_attrs, lodash_es_pick(attrs, stanza_id_keys)); - - if (!message.get('received')) { - new_attrs.received = new Date().toISOString(); - } - } - - return new_attrs; - }, - - /** - * Send a MUC-0410 MUC Self-Ping stanza to room to determine - * whether we're still joined. - * @async - * @private - * @method _converse.ChatRoom#isJoined - * @returns {Promise} - */ - async isJoined() { - const jid = this.get('jid'); - const ping = $iq({ - 'to': `${jid}/${this.get('nick')}`, - 'type': 'get' - }).c('ping', { - 'xmlns': Strophe.NS.PING - }); - - try { - await api.sendIQ(ping); - } catch (e) { - if (e === null) { - headless_log.warn(`isJoined: Timeout error while checking whether we're joined to MUC: ${jid}`); - } else { - headless_log.warn(`isJoined: Apparently we're no longer connected to MUC: ${jid}`); - } - - return false; - } - - return true; - }, - - /** - * Check whether we're still joined and re-join if not - * @async - * @private - * @method _converse.ChatRoom#rejoinIfNecessary - */ - async rejoinIfNecessary() { - if (!(await this.isJoined())) { - this.rejoin(); - return true; - } - }, - - /** - * @private - * @method _converse.ChatRoom#shouldShowErrorMessage - * @returns {Promise} - */ - async shouldShowErrorMessage(attrs) { - if (attrs['error_condition'] === 'not-acceptable' && (await this.rejoinIfNecessary())) { - return false; - } - - return shared_converse.ChatBox.prototype.shouldShowErrorMessage.call(this, attrs); - }, - - /** - * Looks whether we already have a moderation message for this - * incoming message. If so, it's considered "dangling" because - * it probably hasn't been applied to anything yet, given that - * the relevant message is only coming in now. - * @private - * @method _converse.ChatRoom#findDanglingModeration - * @param { object } attrs - Attributes representing a received - * message, as returned by {@link parseMUCMessage} - * @returns { _converse.ChatRoomMessage } - */ - findDanglingModeration(attrs) { - if (!this.messages.length) { - return null; - } // Only look for dangling moderation if there are newer - // messages than this one, since moderation come after. - - - if (this.messages.last().get('time') > attrs.time) { - // Search from latest backwards - const messages = Array.from(this.messages.models); - const stanza_id = attrs[`stanza_id ${this.get('jid')}`]; - - if (!stanza_id) { - return null; - } - - messages.reverse(); - return messages.find(({ - attributes - }) => attributes.moderated === 'retracted' && attributes.moderated_id === stanza_id && attributes.moderated_by); - } - }, - - /** - * Handles message moderation based on the passed in attributes. - * @private - * @method _converse.ChatRoom#handleModeration - * @param { object } attrs - Attributes representing a received - * message, as returned by {@link parseMUCMessage} - * @returns { Boolean } Returns `true` or `false` depending on - * whether a message was moderated or not. - */ - async handleModeration(attrs) { - const MODERATION_ATTRIBUTES = ['editable', 'moderated', 'moderated_by', 'moderated_id', 'moderation_reason']; - - if (attrs.moderated === 'retracted') { - const query = {}; - const key = `stanza_id ${this.get('jid')}`; - query[key] = attrs.moderated_id; - const message = this.messages.findWhere(query); - - if (!message) { - attrs['dangling_moderation'] = true; - await this.createMessage(attrs); - return true; - } - - message.save(lodash_es_pick(attrs, MODERATION_ATTRIBUTES)); - return true; - } else { - // Check if we have dangling moderation message - const message = this.findDanglingModeration(attrs); - - if (message) { - const moderation_attrs = lodash_es_pick(message.attributes, MODERATION_ATTRIBUTES); - const new_attrs = Object.assign({ - 'dangling_moderation': false - }, attrs, moderation_attrs); - delete new_attrs['id']; // Delete id, otherwise a new cache entry gets created - - message.save(new_attrs); - return true; - } - } - - return false; - }, - - getNotificationsText() { - const { - __ - } = shared_converse; - const actors_per_state = this.notifications.toJSON(); - const role_changes = api.settings.get('muc_show_info_messages').filter(role_change => core_converse.MUC_ROLE_CHANGES_LIST.includes(role_change)); - const join_leave_events = api.settings.get('muc_show_info_messages').filter(join_leave_event => core_converse.MUC_TRAFFIC_STATES_LIST.includes(join_leave_event)); - const states = [...core_converse.CHAT_STATES, ...join_leave_events, ...role_changes]; - return states.reduce((result, state) => { - const existing_actors = actors_per_state[state]; - - if (!(existing_actors !== null && existing_actors !== void 0 && existing_actors.length)) { - return result; - } - - const actors = existing_actors.map(a => { - var _this$getOccupant; - - return ((_this$getOccupant = this.getOccupant(a)) === null || _this$getOccupant === void 0 ? void 0 : _this$getOccupant.getDisplayName()) || a; - }); - - if (actors.length === 1) { - if (state === 'composing') { - return `${result}${__('%1$s is typing', actors[0])}\n`; - } else if (state === 'paused') { - return `${result}${__('%1$s has stopped typing', actors[0])}\n`; - } else if (state === shared_converse.GONE) { - return `${result}${__('%1$s has gone away', actors[0])}\n`; - } else if (state === 'entered') { - return `${result}${__('%1$s has entered the groupchat', actors[0])}\n`; - } else if (state === 'exited') { - return `${result}${__('%1$s has left the groupchat', actors[0])}\n`; - } else if (state === 'op') { - return `${result}${__('%1$s is now a moderator', actors[0])}\n`; - } else if (state === 'deop') { - return `${result}${__('%1$s is no longer a moderator', actors[0])}\n`; - } else if (state === 'voice') { - return `${result}${__('%1$s has been given a voice', actors[0])}\n`; - } else if (state === 'mute') { - return `${result}${__('%1$s has been muted', actors[0])}\n`; - } - } else if (actors.length > 1) { - let actors_str; - - if (actors.length > 3) { - actors_str = `${Array.from(actors).slice(0, 2).join(', ')} and others`; - } else { - const last_actor = actors.pop(); - actors_str = __('%1$s and %2$s', actors.join(', '), last_actor); - } - - if (state === 'composing') { - return `${result}${__('%1$s are typing', actors_str)}\n`; - } else if (state === 'paused') { - return `${result}${__('%1$s have stopped typing', actors_str)}\n`; - } else if (state === shared_converse.GONE) { - return `${result}${__('%1$s have gone away', actors_str)}\n`; - } else if (state === 'entered') { - return `${result}${__('%1$s have entered the groupchat', actors_str)}\n`; - } else if (state === 'exited') { - return `${result}${__('%1$s have left the groupchat', actors_str)}\n`; - } else if (state === 'op') { - return `${result}${__('%1$s are now moderators', actors[0])}\n`; - } else if (state === 'deop') { - return `${result}${__('%1$s are no longer moderators', actors[0])}\n`; - } else if (state === 'voice') { - return `${result}${__('%1$s have been given voices', actors[0])}\n`; - } else if (state === 'mute') { - return `${result}${__('%1$s have been muted', actors[0])}\n`; - } - } - - return result; - }, ''); - }, - - /** - * @param {String} actor - The nickname of the actor that caused the notification - * @param {String|Array} states - The state or states representing the type of notificcation - */ - removeNotification(actor, states) { - const actors_per_state = this.notifications.toJSON(); - states = Array.isArray(states) ? states : [states]; - states.forEach(state => { - const existing_actors = Array.from(actors_per_state[state] || []); - - if (existing_actors.includes(actor)) { - const idx = existing_actors.indexOf(actor); - existing_actors.splice(idx, 1); - this.notifications.set(state, Array.from(existing_actors)); - } - }); - }, - - /** - * Update the notifications model by adding the passed in nickname - * to the array of nicknames that all match a particular state. - * - * Removes the nickname from any other states it might be associated with. - * - * The state can be a XEP-0085 Chat State or a XEP-0045 join/leave - * state. - * @param {String} actor - The nickname of the actor that causes the notification - * @param {String} state - The state representing the type of notificcation - */ - updateNotifications(actor, state) { - const actors_per_state = this.notifications.toJSON(); - const existing_actors = actors_per_state[state] || []; - - if (existing_actors.includes(actor)) { - return; - } - - const reducer = (out, s) => { - if (s === state) { - out[s] = [...existing_actors, actor]; - } else { - out[s] = (actors_per_state[s] || []).filter(a => a !== actor); - } - - return out; - }; - - const actors_per_chat_state = core_converse.CHAT_STATES.reduce(reducer, {}); - const actors_per_traffic_state = core_converse.MUC_TRAFFIC_STATES_LIST.reduce(reducer, {}); - const actors_per_role_change = core_converse.MUC_ROLE_CHANGES_LIST.reduce(reducer, {}); - this.notifications.set(Object.assign(actors_per_chat_state, actors_per_traffic_state, actors_per_role_change)); - window.setTimeout(() => this.removeNotification(actor, state), 10000); - }, - - handleMetadataFastening(attrs) { - if (!api.settings.get('muc_show_ogp_unfurls')) { - return false; - } - - if (attrs.ogp_for_id) { - if (attrs.from !== this.get('jid')) { - // For now we only allow metadata from the MUC itself and not - // from individual users who are deemed less trustworthy. - return false; - } - - const message = this.messages.findWhere({ - 'origin_id': attrs.ogp_for_id - }); - - if (message) { - const old_list = message.get('ogp_metadata') || []; - - if (old_list.filter(m => m['og:url'] === attrs['og:url']).length) { - // Don't add metadata for the same URL again - return false; - } - - const list = [...old_list, lodash_es_pick(attrs, METADATA_ATTRIBUTES)]; - message.save('ogp_metadata', list); - return true; - } - } - - return false; - }, - - /** - * Given { @link MessageAttributes } look for XEP-0316 Room Notifications and create info - * messages for them. - * @param { XMLElement } stanza - */ - handleMEPNotification(attrs) { - var _attrs$activities; - - if (attrs.from !== this.get('jid') || !attrs.activities) { - return false; - } - - (_attrs$activities = attrs.activities) === null || _attrs$activities === void 0 ? void 0 : _attrs$activities.forEach(activity_attrs => { - const data = Object.assign({ - 'msgid': attrs.msgid, - 'from_muc': attrs.from - }, activity_attrs); - this.createMessage(data); // Trigger so that notifications are shown - - api.trigger('message', { - 'attrs': data, - 'chatbox': this - }); - }); - return !!attrs.activities.length; - }, - - /** - * Returns an already cached message (if it exists) based on the - * passed in attributes map. - * @method _converse.ChatRoom#getDuplicateMessage - * @param { object } attrs - Attributes representing a received - * message, as returned by { @link parseMUCMessage } - * @returns {Promise<_converse.Message>} - */ - getDuplicateMessage(attrs) { - var _attrs$activities2; - - if ((_attrs$activities2 = attrs.activities) !== null && _attrs$activities2 !== void 0 && _attrs$activities2.length) { - return this.messages.findWhere({ - 'type': 'info', - 'msgid': attrs.msgid - }); - } else { - return shared_converse.ChatBox.prototype.getDuplicateMessage.call(this, attrs); - } - }, - - /** - * Handler for all MUC messages sent to this groupchat. This method - * shouldn't be called directly, instead {@link _converse.ChatRoom#queueMessage} - * should be called. - * @method _converse.ChatRoom#onMessage - * @param { MessageAttributes } attrs - A promise which resolves to the message attributes. - */ - async onMessage(attrs) { - attrs = await attrs; - - if (utils_form.isErrorObject(attrs)) { - attrs.stanza && headless_log.error(attrs.stanza); - return headless_log.error(attrs.message); - } - - const message = this.getDuplicateMessage(attrs); - - if (message) { - message.get('type') === 'groupchat' && this.updateMessage(message, attrs); - return; - } else if (attrs.is_valid_receipt_request || attrs.is_marker || this.ignorableCSN(attrs)) { - return; - } - - if (this.handleMetadataFastening(attrs) || this.handleMEPNotification(attrs) || (await this.handleRetraction(attrs)) || (await this.handleModeration(attrs)) || (await this.handleSubjectChange(attrs))) { - attrs.nick && this.removeNotification(attrs.nick, ['composing', 'paused']); - return; - } - - this.setEditable(attrs, attrs.time); - - if (attrs['chat_state']) { - this.updateNotifications(attrs.nick, attrs.chat_state); - } - - if (utils_form.shouldCreateGroupchatMessage(attrs)) { - const msg = this.handleCorrection(attrs) || (await this.createMessage(attrs)); - this.removeNotification(attrs.nick, ['composing', 'paused']); - this.handleUnreadMessage(msg); - } - }, - - handleModifyError(pres) { - var _pres$querySelector; - - const text = (_pres$querySelector = pres.querySelector('error text')) === null || _pres$querySelector === void 0 ? void 0 : _pres$querySelector.textContent; - - if (text) { - if (this.session.get('connection_status') === core_converse.ROOMSTATUS.CONNECTING) { - this.setDisconnectionState(text); - } else { - const attrs = { - 'type': 'error', - 'message': text, - 'is_ephemeral': true - }; - this.createMessage(attrs); - } - } - }, - - /** - * Handle a presence stanza that disconnects the user from the MUC - * @param { XMLElement } stanza - */ - handleDisconnection(stanza) { - var _item$querySelector; - - const is_self = stanza.querySelector("status[code='110']") !== null; - const x = sizzle_default()(`x[xmlns="${Strophe.NS.MUC_USER}"]`, stanza).pop(); - - if (!x) { - return; - } - - const disconnection_codes = Object.keys(shared_converse.muc.disconnect_messages); - const codes = sizzle_default()('status', x).map(s => s.getAttribute('code')).filter(c => disconnection_codes.includes(c)); - const disconnected = is_self && codes.length > 0; - - if (!disconnected) { - return; - } // By using querySelector we assume here there is - // one per - // element. This appears to be a safe assumption, since - // each element pertains to a single user. - - - const item = x.querySelector('item'); - const reason = item ? (_item$querySelector = item.querySelector('reason')) === null || _item$querySelector === void 0 ? void 0 : _item$querySelector.textContent : undefined; - const actor = item ? lodash_es_invoke(item.querySelector('actor'), 'getAttribute', 'nick') : undefined; - const message = shared_converse.muc.disconnect_messages[codes[0]]; - const status = codes.includes('301') ? core_converse.ROOMSTATUS.BANNED : core_converse.ROOMSTATUS.DISCONNECTED; - this.setDisconnectionState(message, reason, actor, status); - }, - - getActionInfoMessage(code, nick, actor) { - const __ = shared_converse.__; - - if (code === '301') { - return actor ? __('%1$s has been banned by %2$s', nick, actor) : __('%1$s has been banned', nick); - } else if (code === '303') { - return __("%1$s's nickname has changed", nick); - } else if (code === '307') { - return actor ? __('%1$s has been kicked out by %2$s', nick, actor) : __('%1$s has been kicked out', nick); - } else if (code === '321') { - return __('%1$s has been removed because of an affiliation change', nick); - } else if (code === '322') { - return __('%1$s has been removed for not being a member', nick); - } - }, - - createAffiliationChangeMessage(occupant) { - const __ = shared_converse.__; - const previous_affiliation = occupant._previousAttributes.affiliation; - - if (!previous_affiliation) { - // If no previous affiliation was set, then we don't - // interpret this as an affiliation change. - // For example, if muc_send_probes is true, then occupants - // are created based on incoming messages, in which case - // we don't yet know the affiliation - return; - } - - const current_affiliation = occupant.get('affiliation'); - - if (previous_affiliation === 'admin' && shared_converse.isInfoVisible(core_converse.AFFILIATION_CHANGES.EXADMIN)) { - this.createMessage({ - 'type': 'info', - 'message': __('%1$s is no longer an admin of this groupchat', occupant.get('nick')) - }); - } else if (previous_affiliation === 'owner' && shared_converse.isInfoVisible(core_converse.AFFILIATION_CHANGES.EXOWNER)) { - this.createMessage({ - 'type': 'info', - 'message': __('%1$s is no longer an owner of this groupchat', occupant.get('nick')) - }); - } else if (previous_affiliation === 'outcast' && shared_converse.isInfoVisible(core_converse.AFFILIATION_CHANGES.EXOUTCAST)) { - this.createMessage({ - 'type': 'info', - 'message': __('%1$s is no longer banned from this groupchat', occupant.get('nick')) - }); - } - - if (current_affiliation === 'none' && previous_affiliation === 'member' && shared_converse.isInfoVisible(core_converse.AFFILIATION_CHANGES.EXMEMBER)) { - this.createMessage({ - 'type': 'info', - 'message': __('%1$s is no longer a member of this groupchat', occupant.get('nick')) - }); - } - - if (current_affiliation === 'member' && shared_converse.isInfoVisible(core_converse.AFFILIATION_CHANGES.MEMBER)) { - this.createMessage({ - 'type': 'info', - 'message': __('%1$s is now a member of this groupchat', occupant.get('nick')) - }); - } else if (current_affiliation === 'admin' && shared_converse.isInfoVisible(core_converse.AFFILIATION_CHANGES.ADMIN) || current_affiliation == 'owner' && shared_converse.isInfoVisible(core_converse.AFFILIATION_CHANGES.OWNER)) { - // For example: AppleJack is now an (admin|owner) of this groupchat - this.createMessage({ - 'type': 'info', - 'message': __('%1$s is now an %2$s of this groupchat', occupant.get('nick'), current_affiliation) - }); - } - }, - - createRoleChangeMessage(occupant, changed) { - if (changed === 'none' || occupant.changed.affiliation) { - // We don't inform of role changes if they accompany affiliation changes. - return; - } - - const previous_role = occupant._previousAttributes.role; - - if (previous_role === 'moderator' && shared_converse.isInfoVisible(core_converse.MUC_ROLE_CHANGES.DEOP)) { - this.updateNotifications(occupant.get('nick'), core_converse.MUC_ROLE_CHANGES.DEOP); - } else if (previous_role === 'visitor' && shared_converse.isInfoVisible(core_converse.MUC_ROLE_CHANGES.VOICE)) { - this.updateNotifications(occupant.get('nick'), core_converse.MUC_ROLE_CHANGES.VOICE); - } - - if (occupant.get('role') === 'visitor' && shared_converse.isInfoVisible(core_converse.MUC_ROLE_CHANGES.MUTE)) { - this.updateNotifications(occupant.get('nick'), core_converse.MUC_ROLE_CHANGES.MUTE); - } else if (occupant.get('role') === 'moderator') { - if (!['owner', 'admin'].includes(occupant.get('affiliation')) && shared_converse.isInfoVisible(core_converse.MUC_ROLE_CHANGES.OP)) { - // Oly show this message if the user isn't already - // an admin or owner, otherwise this isn't new information. - this.updateNotifications(occupant.get('nick'), core_converse.MUC_ROLE_CHANGES.OP); - } - } - }, - - /** - * Create an info message based on a received MUC status code - * @private - * @method _converse.ChatRoom#createInfoMessage - * @param { string } code - The MUC status code - * @param { XMLElement } stanza - The original stanza that contains the code - * @param { Boolean } is_self - Whether this stanza refers to our own presence - */ - createInfoMessage(code, stanza, is_self) { - const __ = shared_converse.__; - const data = { - 'type': 'info' - }; - - if (!shared_converse.isInfoVisible(code)) { - return; - } - - if (code === '110' || code === '100' && !is_self) { - return; - } else if (code in shared_converse.muc.info_messages) { - data.message = shared_converse.muc.info_messages[code]; - } else if (!is_self && ACTION_INFO_CODES.includes(code)) { - var _item$querySelector2, _item$querySelector3; - - const nick = Strophe.getResourceFromJid(stanza.getAttribute('from')); - const item = sizzle_default()(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, stanza).pop(); - data.actor = item ? (_item$querySelector2 = item.querySelector('actor')) === null || _item$querySelector2 === void 0 ? void 0 : _item$querySelector2.getAttribute('nick') : undefined; - data.reason = item ? (_item$querySelector3 = item.querySelector('reason')) === null || _item$querySelector3 === void 0 ? void 0 : _item$querySelector3.textContent : undefined; - data.message = this.getActionInfoMessage(code, nick, data.actor); - } else if (is_self && code in shared_converse.muc.new_nickname_messages) { - // XXX: Side-effect of setting the nick. Should ideally be refactored out of this method - let nick; - - if (is_self && code === '210') { - nick = Strophe.getResourceFromJid(stanza.getAttribute('from')); - } else if (is_self && code === '303') { - nick = sizzle_default()(`x[xmlns="${Strophe.NS.MUC_USER}"] item`, stanza).pop().getAttribute('nick'); - } - - this.save('nick', nick); - data.message = __(shared_converse.muc.new_nickname_messages[code], nick); - } - - if (data.message) { - if (code === '201' && this.messages.findWhere(data)) { - return; - } else if (code in shared_converse.muc.info_messages && this.messages.length && this.messages.pop().get('message') === data.message) { - // XXX: very naive duplication checking - return; - } - - this.createMessage(data); - } - }, - - /** - * Create info messages based on a received presence or message stanza - * @private - * @method _converse.ChatRoom#createInfoMessages - * @param { XMLElement } stanza - */ - createInfoMessages(stanza) { - const codes = sizzle_default()(`x[xmlns="${Strophe.NS.MUC_USER}"] status`, stanza).map(s => s.getAttribute('code')); - - if (codes.includes('333') && codes.includes('307')) { - // See: https://github.com/xsf/xeps/pull/969/files#diff-ac5113766e59219806793c1f7d967f1bR4966 - codes.splice(codes.indexOf('307'), 1); - } - - const is_self = codes.includes('110'); - codes.forEach(code => this.createInfoMessage(code, stanza, is_self)); - }, - - /** - * Set parameters regarding disconnection from this room. This helps to - * communicate to the user why they were disconnected. - * @param { String } message - The disconnection message, as received from (or - * implied by) the server. - * @param { String } reason - The reason provided for the disconnection - * @param { String } actor - The person (if any) responsible for this disconnection - * @param { Integer } status - The status code (see `converse.ROOMSTATUS`) - */ - setDisconnectionState(message, reason, actor, status = core_converse.ROOMSTATUS.DISCONNECTED) { - this.session.save({ - 'connection_status': status, - 'disconnection_actor': actor, - 'disconnection_message': message, - 'disconnection_reason': reason - }); - }, - - onNicknameClash(presence) { - const __ = shared_converse.__; - - if (api.settings.get('muc_nickname_from_jid')) { - const nick = presence.getAttribute('from').split('/')[1]; - - if (nick === shared_converse.getDefaultMUCNickname()) { - this.join(nick + '-2'); - } else { - const del = nick.lastIndexOf('-'); - const num = nick.substring(del + 1, nick.length); - this.join(nick.substring(0, del + 1) + String(Number(num) + 1)); - } - } else { - this.save({ - 'nickname_validation_message': __('The nickname you chose is reserved or ' + 'currently in use, please choose a different one.') - }); - this.session.save({ - 'connection_status': core_converse.ROOMSTATUS.NICKNAME_REQUIRED - }); - } - }, - - /** - * Parses a stanza with type "error" and sets the proper - * `connection_status` value for this {@link _converse.ChatRoom} as - * well as any additional output that can be shown to the user. - * @private - * @param { XMLElement } stanza - The presence stanza - */ - onErrorPresence(stanza) { - var _sizzle$pop; - - const __ = shared_converse.__; - const error = stanza.querySelector('error'); - const error_type = error.getAttribute('type'); - const reason = (_sizzle$pop = sizzle_default()(`text[xmlns="${Strophe.NS.STANZAS}"]`, error).pop()) === null || _sizzle$pop === void 0 ? void 0 : _sizzle$pop.textContent; - - if (error_type === 'modify') { - this.handleModifyError(stanza); - } else if (error_type === 'auth') { - if (sizzle_default()(`not-authorized[xmlns="${Strophe.NS.STANZAS}"]`, error).length) { - this.save({ - 'password_validation_message': reason || __('Password incorrect') - }); - this.session.save({ - 'connection_status': core_converse.ROOMSTATUS.PASSWORD_REQUIRED - }); - } - - if (error.querySelector('registration-required')) { - const message = __('You are not on the member list of this groupchat.'); - - this.setDisconnectionState(message, reason); - } else if (error.querySelector('forbidden')) { - this.setDisconnectionState(shared_converse.muc.disconnect_messages[301], reason, null, core_converse.ROOMSTATUS.BANNED); - } - } else if (error_type === 'cancel') { - if (error.querySelector('not-allowed')) { - const message = __('You are not allowed to create new groupchats.'); - - this.setDisconnectionState(message, reason); - } else if (error.querySelector('not-acceptable')) { - const message = __("Your nickname doesn't conform to this groupchat's policies."); - - this.setDisconnectionState(message, reason); - } else if (sizzle_default()(`gone[xmlns="${Strophe.NS.STANZAS}"]`, error).length) { - var _sizzle$pop2; - - const moved_jid = (_sizzle$pop2 = sizzle_default()(`gone[xmlns="${Strophe.NS.STANZAS}"]`, error).pop()) === null || _sizzle$pop2 === void 0 ? void 0 : _sizzle$pop2.textContent.replace(/^xmpp:/, '').replace(/\?join$/, ''); - this.save({ - moved_jid, - 'destroyed_reason': reason - }); - this.session.save({ - 'connection_status': core_converse.ROOMSTATUS.DESTROYED - }); - } else if (error.querySelector('conflict')) { - this.onNicknameClash(stanza); - } else if (error.querySelector('item-not-found')) { - const message = __('This groupchat does not (yet) exist.'); - - this.setDisconnectionState(message, reason); - } else if (error.querySelector('service-unavailable')) { - const message = __('This groupchat has reached its maximum number of participants.'); - - this.setDisconnectionState(message, reason); - } else if (error.querySelector('remote-server-not-found')) { - const message = __('Remote server not found'); - - const feedback = reason ? __('The explanation given is: "%1$s".', reason) : undefined; - this.setDisconnectionState(message, feedback); - } - } - }, - - /** - * Listens for incoming presence stanzas from the service that hosts this MUC - * @private - * @method _converse.ChatRoom#onPresenceFromMUCHost - * @param { XMLElement } stanza - The presence stanza - */ - onPresenceFromMUCHost(stanza) { - if (stanza.getAttribute('type') === 'error') { - const error = stanza.querySelector('error'); - - if ((error === null || error === void 0 ? void 0 : error.getAttribute('type')) === 'wait' && error !== null && error !== void 0 && error.querySelector('resource-constraint')) { - // If we get a error, we assume it's in context of XEP-0437 RAI. - // We remove this MUC's host from the list of enabled domains and rejoin the MUC. - if (this.session.get('connection_status') === core_converse.ROOMSTATUS.DISCONNECTED) { - this.rejoin(); - } - } - } - }, - - /** - * Handles incoming presence stanzas coming from the MUC - * @private - * @method _converse.ChatRoom#onPresence - * @param { XMLElement } stanza - */ - onPresence(stanza) { - if (stanza.getAttribute('type') === 'error') { - return this.onErrorPresence(stanza); - } - - this.createInfoMessages(stanza); - - if (stanza.querySelector("status[code='110']")) { - this.onOwnPresence(stanza); - - if (this.getOwnRole() !== 'none' && this.session.get('connection_status') === core_converse.ROOMSTATUS.CONNECTING) { - this.session.save('connection_status', core_converse.ROOMSTATUS.CONNECTED); - } - } else { - this.updateOccupantsOnPresence(stanza); - } - }, - - /** - * Handles a received presence relating to the current user. - * - * For locked groupchats (which are by definition "new"), the - * groupchat will either be auto-configured or created instantly - * (with default config) or a configuration groupchat will be - * rendered. - * - * If the groupchat is not locked, then the groupchat will be - * auto-configured only if applicable and if the current - * user is the groupchat's owner. - * @private - * @method _converse.ChatRoom#onOwnPresence - * @param { XMLElement } pres - The stanza - */ - async onOwnPresence(stanza) { - await this.occupants.fetched; - const old_status = this.session.get('connection_status'); - - if (stanza.getAttribute('type') !== 'unavailable' && old_status !== core_converse.ROOMSTATUS.ENTERED) { - // Set connection_status before creating the occupant, but - // only trigger afterwards, so that plugins can access the - // occupant in their event handlers. - this.session.save('connection_status', core_converse.ROOMSTATUS.ENTERED, { - 'silent': true - }); - this.updateOccupantsOnPresence(stanza); - this.session.trigger('change:connection_status', this.session, old_status); - } else { - this.updateOccupantsOnPresence(stanza); - } - - if (stanza.getAttribute('type') === 'unavailable') { - this.handleDisconnection(stanza); - return; - } else { - const locked_room = stanza.querySelector("status[code='201']"); - - if (locked_room) { - if (this.get('auto_configure')) { - this.autoConfigureChatRoom().then(() => this.refreshDiscoInfo()); - } else if (api.settings.get('muc_instant_rooms')) { - // Accept default configuration - this.sendConfiguration().then(() => this.refreshDiscoInfo()); - } else { - this.session.save({ - 'view': core_converse.MUC.VIEWS.CONFIG - }); - return; - } - } else if (!this.features.get('fetched')) { - // The features for this groupchat weren't fetched. - // That must mean it's a new groupchat without locking - // (in which case Prosody doesn't send a 201 status), - // otherwise the features would have been fetched in - // the "initialize" method already. - if (this.getOwnAffiliation() === 'owner' && this.get('auto_configure')) { - this.autoConfigureChatRoom().then(() => this.refreshDiscoInfo()); - } else { - this.getDiscoInfo(); - } - } - } - - this.session.save({ - 'connection_status': core_converse.ROOMSTATUS.ENTERED - }); - }, - - /** - * Returns a boolean to indicate whether the current user - * was mentioned in a message. - * @private - * @method _converse.ChatRoom#isUserMentioned - * @param { String } - The text message - */ - isUserMentioned(message) { - const nick = this.get('nick'); - - if (message.get('references').length) { - const mentions = message.get('references').filter(ref => ref.type === 'mention').map(ref => ref.value); - return mentions.includes(nick); - } else { - return new RegExp(`\\b${nick}\\b`).test(message.get('message')); - } - }, - - incrementUnreadMsgsCounter(message) { - const settings = { - 'num_unread_general': this.get('num_unread_general') + 1 - }; - - if (this.get('num_unread_general') === 0) { - settings['first_unread_id'] = message.get('id'); - } - - if (this.isUserMentioned(message)) { - settings.num_unread = this.get('num_unread') + 1; - } - - this.save(settings); - }, - - clearUnreadMsgCounter() { - if (this.get('num_unread_general') > 0 || this.get('num_unread') > 0 || this.get('has_activity')) { - this.sendMarkerForMessage(this.messages.last()); - } - - utils_form.safeSave(this, { - 'has_activity': false, - 'num_unread': 0, - 'num_unread_general': 0 - }); - } - -}; -/* harmony default export */ const muc = (ChatRoomMixin); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/occupant.js - - - -/** - * Represents a participant in a MUC - * @class - * @namespace _converse.ChatRoomOccupant - * @memberOf _converse - */ - -const ChatRoomOccupant = Model.extend({ - defaults: { - 'hats': [], - 'show': 'offline', - 'states': [] - }, - - initialize(attributes) { - this.set(Object.assign({ - 'id': utils_form.getUniqueId() - }, attributes)); - this.on('change:image_hash', this.onAvatarChanged, this); - }, - - onAvatarChanged() { - const hash = this.get('image_hash'); - const vcards = []; - - if (this.get('jid')) { - vcards.push(shared_converse.vcards.findWhere({ - 'jid': this.get('jid') - })); - } - - vcards.push(shared_converse.vcards.findWhere({ - 'jid': this.get('from') - })); - vcards.filter(v => v).forEach(vcard => { - if (hash && vcard.get('image_hash') !== hash) { - api.vcard.update(vcard, true); - } - }); - }, - - getDisplayName() { - return this.get('nick') || this.get('jid'); - }, - - isMember() { - return ['admin', 'owner', 'member'].includes(this.get('affiliation')); - }, - - isModerator() { - return ['admin', 'owner'].includes(this.get('affiliation')) || this.get('role') === 'moderator'; - }, - - isSelf() { - return this.get('states').includes('110'); - } - -}); -/* harmony default export */ const occupant = (ChatRoomOccupant); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/occupants.js - - - - - - -const MUC_ROLE_WEIGHTS = { - 'moderator': 1, - 'participant': 2, - 'visitor': 3, - 'none': 2 -}; -/** - * A list of {@link _converse.ChatRoomOccupant} instances, representing participants in a MUC. - * @class - * @namespace _converse.ChatRoomOccupants - * @memberOf _converse - */ - -const ChatRoomOccupants = Collection.extend({ - model: occupant, - - comparator(occupant1, occupant2) { - const role1 = occupant1.get('role') || 'none'; - const role2 = occupant2.get('role') || 'none'; - - if (MUC_ROLE_WEIGHTS[role1] === MUC_ROLE_WEIGHTS[role2]) { - const nick1 = occupant1.getDisplayName().toLowerCase(); - const nick2 = occupant2.getDisplayName().toLowerCase(); - return nick1 < nick2 ? -1 : nick1 > nick2 ? 1 : 0; - } else { - return MUC_ROLE_WEIGHTS[role1] < MUC_ROLE_WEIGHTS[role2] ? -1 : 1; - } - }, - - getAutoFetchedAffiliationLists() { - const affs = api.settings.get('muc_fetch_members'); - return Array.isArray(affs) ? affs : affs ? ['member', 'admin', 'owner'] : []; - }, - - async fetchMembers() { - const affiliations = this.getAutoFetchedAffiliationLists(); - - if (affiliations.length === 0) { - return; - } - - const muc_jid = this.chatroom.get('jid'); - const aff_lists = await Promise.all(affiliations.map(a => getAffiliationList(a, muc_jid))); - const new_members = aff_lists.reduce((acc, val) => utils_form.isErrorObject(val) ? acc : [...val, ...acc], []); - const known_affiliations = affiliations.filter(a => !utils_form.isErrorObject(aff_lists[affiliations.indexOf(a)])); - const new_jids = new_members.map(m => m.jid).filter(m => m !== undefined); - const new_nicks = new_members.map(m => !m.jid && m.nick || undefined).filter(m => m !== undefined); - const removed_members = this.filter(m => { - return known_affiliations.includes(m.get('affiliation')) && !new_nicks.includes(m.get('nick')) && !new_jids.includes(m.get('jid')); - }); - removed_members.forEach(occupant => { - if (occupant.get('jid') === shared_converse.bare_jid) { - return; - } - - if (occupant.get('show') === 'offline') { - occupant.destroy(); - } else { - occupant.save('affiliation', null); - } - }); - new_members.forEach(attrs => { - const occupant = attrs.jid ? this.findOccupant({ - 'jid': attrs.jid - }) : this.findOccupant({ - 'nick': attrs.nick - }); - - if (occupant) { - occupant.save(attrs); - } else { - this.create(attrs); - } - }); - /** - * Triggered once the member lists for this MUC have been fetched and processed. - * @event _converse#membersFetched - * @example _converse.api.listen.on('membersFetched', () => { ... }); - */ - - api.trigger('membersFetched'); - }, - - /** - * @typedef { Object} OccupantData - * @property { String } [jid] - * @property { String } [nick] - */ - - /** - * Try to find an existing occupant based on the passed in - * data object. - * - * If we have a JID, we use that as lookup variable, - * otherwise we use the nick. We don't always have both, - * but should have at least one or the other. - * @private - * @method _converse.ChatRoomOccupants#findOccupant - * @param { OccupantData } data - */ - findOccupant(data) { - const jid = Strophe.getBareJidFromJid(data.jid); - return jid && this.findWhere({ - jid - }) || this.findWhere({ - 'nick': data.nick - }); - } - -}); -/* harmony default export */ const occupants = (ChatRoomOccupants); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/affiliations/api.js - -/* harmony default export */ const affiliations_api = ({ - /** - * The "affiliations" namespace groups methods relevant to setting and - * getting MUC affiliations. - * - * @namespace api.rooms.affiliations - * @memberOf api.rooms - */ - affiliations: { - /** - * Set the given affliation for the given JIDs in the specified MUCs - * - * @param { String|Array } muc_jids - The JIDs of the MUCs in - * which the affiliation should be set. - * @param { Object[] } users - An array of objects representing users - * for whom the affiliation is to be set. - * @param { String } users[].jid - The JID of the user whose affiliation will change - * @param { ('outcast'|'member'|'admin'|'owner') } users[].affiliation - The new affiliation for this user - * @param { String } [users[].reason] - An optional reason for the affiliation change - */ - set(muc_jids, users) { - users = !Array.isArray(users) ? [users] : users; - muc_jids = !Array.isArray(muc_jids) ? [muc_jids] : muc_jids; - return setAffiliations(muc_jids, users); - } - - } -}); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/api.js - - - - -/* harmony default export */ const muc_api = ({ - /** - * The "rooms" namespace groups methods relevant to chatrooms - * (aka groupchats). - * - * @namespace api.rooms - * @memberOf api - */ - rooms: { - /** - * Creates a new MUC chatroom (aka groupchat) - * - * Similar to {@link api.rooms.open}, but creates - * the chatroom in the background (i.e. doesn't cause a view to open). - * - * @method api.rooms.create - * @param {(string[]|string)} jid|jids The JID or array of - * JIDs of the chatroom(s) to create - * @param {object} [attrs] attrs The room attributes - * @returns {Promise} Promise which resolves with the Model representing the chat. - */ - create(jids, attrs = {}) { - attrs = typeof attrs === 'string' ? { - 'nick': attrs - } : attrs || {}; - - if (!attrs.nick && api.settings.get('muc_nickname_from_jid')) { - attrs.nick = Strophe.getNodeFromJid(shared_converse.bare_jid); - } - - if (jids === undefined) { - throw new TypeError('rooms.create: You need to provide at least one JID'); - } else if (typeof jids === 'string') { - return api.rooms.get(utils_form.getJIDFromURI(jids), attrs, true); - } - - return jids.map(jid => api.rooms.get(utils_form.getJIDFromURI(jid), attrs, true)); - }, - - /** - * Opens a MUC chatroom (aka groupchat) - * - * Similar to {@link api.chats.open}, but for groupchats. - * - * @method api.rooms.open - * @param {string} jid The room JID or JIDs (if not specified, all - * currently open rooms will be returned). - * @param {string} attrs A map containing any extra room attributes. - * @param {string} [attrs.nick] The current user's nickname for the MUC - * @param {boolean} [attrs.auto_configure] A boolean, indicating - * whether the room should be configured automatically or not. - * If set to `true`, then it makes sense to pass in configuration settings. - * @param {object} [attrs.roomconfig] A map of configuration settings to be used when the room gets - * configured automatically. Currently it doesn't make sense to specify - * `roomconfig` values if `auto_configure` is set to `false`. - * For a list of configuration values that can be passed in, refer to these values - * in the [XEP-0045 MUC specification](https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner). - * The values should be named without the `muc#roomconfig_` prefix. - * @param {boolean} [attrs.minimized] A boolean, indicating whether the room should be opened minimized or not. - * @param {boolean} [attrs.bring_to_foreground] A boolean indicating whether the room should be - * brought to the foreground and therefore replace the currently shown chat. - * If there is no chat currently open, then this option is ineffective. - * @param {Boolean} [force=false] - By default, a minimized - * room won't be maximized (in `overlayed` view mode) and in - * `fullscreen` view mode a newly opened room won't replace - * another chat already in the foreground. - * Set `force` to `true` if you want to force the room to be - * maximized or shown. - * @returns {Promise} Promise which resolves with the Model representing the chat. - * - * @example - * this.api.rooms.open('group@muc.example.com') - * - * @example - * // To return an array of rooms, provide an array of room JIDs: - * api.rooms.open(['group1@muc.example.com', 'group2@muc.example.com']) - * - * @example - * // To setup a custom nickname when joining the room, provide the optional nick argument: - * api.rooms.open('group@muc.example.com', {'nick': 'mycustomnick'}) - * - * @example - * // For example, opening a room with a specific default configuration: - * api.rooms.open( - * 'myroom@conference.example.org', - * { 'nick': 'coolguy69', - * 'auto_configure': true, - * 'roomconfig': { - * 'changesubject': false, - * 'membersonly': true, - * 'persistentroom': true, - * 'publicroom': true, - * 'roomdesc': 'Comfy room for hanging out', - * 'whois': 'anyone' - * } - * } - * ); - */ - async open(jids, attrs = {}, force = false) { - await api.waitUntil('chatBoxesFetched'); - - if (jids === undefined) { - const err_msg = 'rooms.open: You need to provide at least one JID'; - headless_log.error(err_msg); - throw new TypeError(err_msg); - } else if (typeof jids === 'string') { - const room = await api.rooms.get(jids, attrs, true); - !attrs.hidden && (room === null || room === void 0 ? void 0 : room.maybeShow(force)); - return room; - } else { - const rooms = await Promise.all(jids.map(jid => api.rooms.get(jid, attrs, true))); - rooms.forEach(r => !attrs.hidden && r.maybeShow(force)); - return rooms; - } - }, - - /** - * Fetches the object representing a MUC chatroom (aka groupchat) - * - * @method api.rooms.get - * @param { String } [jid] The room JID (if not specified, all rooms will be returned). - * @param { Object } [attrs] A map containing any extra room attributes - * to be set if `create` is set to `true` - * @param { String } [attrs.nick] Specify the nickname - * @param { String } [attrs.password ] Specify a password if needed to enter a new room - * @param { Boolean } create A boolean indicating whether the room should be created - * if not found (default: `false`) - * @returns { Promise<_converse.ChatRoom> } - * @example - * api.waitUntil('roomsAutoJoined').then(() => { - * const create_if_not_found = true; - * api.rooms.get( - * 'group@muc.example.com', - * {'nick': 'dread-pirate-roberts', 'password': 'secret'}, - * create_if_not_found - * ) - * }); - */ - async get(jids, attrs = {}, create = false) { - await api.waitUntil('chatBoxesFetched'); - - async function _get(jid) { - jid = utils_form.getJIDFromURI(jid); - let model = await api.chatboxes.get(jid); - - if (!model && create) { - model = await api.chatboxes.create(jid, attrs, shared_converse.ChatRoom); - } else { - model = model && model.get('type') === shared_converse.CHATROOMS_TYPE ? model : null; - - if (model && Object.keys(attrs).length) { - model.save(attrs); - } - } - - return model; - } - - if (jids === undefined) { - const chats = await api.chatboxes.get(); - return chats.filter(c => c.get('type') === shared_converse.CHATROOMS_TYPE); - } else if (typeof jids === 'string') { - return _get(jids); - } - - return Promise.all(jids.map(jid => _get(jid))); - } - - } -}); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/utils.js - - - - - -const { - Strophe: muc_utils_Strophe, - sizzle: muc_utils_sizzle, - u: muc_utils_u -} = core_converse.env; -/** - * Given an occupant model, see which roles may be assigned to that user. - * @param { Model } occupant - * @returns { ('moderator', 'participant', 'visitor')[] } - An array of assignable roles - */ - -function getAssignableRoles(occupant) { - let disabled = api.settings.get('modtools_disable_assign'); - - if (!Array.isArray(disabled)) { - disabled = disabled ? ROLES : []; - } - - if (occupant.get('role') === 'moderator') { - return ROLES.filter(r => !disabled.includes(r)); - } else { - return []; - } -} -function registerDirectInvitationHandler() { - shared_converse.connection.addHandler(message => { - shared_converse.onDirectMUCInvitation(message); - - return true; - }, 'jabber:x:conference', 'message'); -} -function disconnectChatRooms() { - /* When disconnecting, mark all groupchats as - * disconnected, so that they will be properly entered again - * when fetched from session storage. - */ - return shared_converse.chatboxes.filter(m => m.get('type') === shared_converse.CHATROOMS_TYPE).forEach(m => m.session.save({ - 'connection_status': core_converse.ROOMSTATUS.DISCONNECTED - })); -} -async function onWindowStateChanged(data) { - if (data.state === 'visible' && api.connection.connected()) { - const rooms = await api.rooms.get(); - rooms.forEach(room => room.rejoinIfNecessary()); - } -} -async function routeToRoom(jid) { - if (!muc_utils_u.isValidMUCJID(jid)) { - return headless_log.warn(`invalid jid "${jid}" provided in url fragment`); - } - - await api.waitUntil('roomsAutoJoined'); - - if (api.settings.get('allow_bookmarks')) { - await api.waitUntil('bookmarksInitialized'); - } - - api.rooms.open(jid); -} -/* Opens a groupchat, making sure that certain attributes - * are correct, for example that the "type" is set to - * "chatroom". - */ - -async function openChatRoom(jid, settings) { - settings.type = shared_converse.CHATROOMS_TYPE; - settings.id = jid; - const chatbox = await api.rooms.get(jid, settings, true); - chatbox.maybeShow(true); - return chatbox; -} -/** - * A direct MUC invitation to join a groupchat has been received - * See XEP-0249: Direct MUC invitations. - * @private - * @method _converse.ChatRoom#onDirectMUCInvitation - * @param { XMLElement } message - The message stanza containing the invitation. - */ - -async function onDirectMUCInvitation(message) { - const { - __ - } = shared_converse; - const x_el = muc_utils_sizzle('x[xmlns="jabber:x:conference"]', message).pop(), - from = muc_utils_Strophe.getBareJidFromJid(message.getAttribute('from')), - room_jid = x_el.getAttribute('jid'), - reason = x_el.getAttribute('reason'); - let result; - - if (api.settings.get('auto_join_on_invite')) { - result = true; - } else { - // Invite request might come from someone not your roster list - let contact = shared_converse.roster.get(from); - - contact = contact ? contact.getDisplayName() : from; - - if (!reason) { - result = confirm(__('%1$s has invited you to join a groupchat: %2$s', contact, room_jid)); - } else { - result = confirm(__('%1$s has invited you to join a groupchat: %2$s, and left the following reason: "%3$s"', contact, room_jid, reason)); - } - } - - if (result === true) { - const chatroom = await openChatRoom(room_jid, { - 'password': x_el.getAttribute('password') - }); - - if (chatroom.session.get('connection_status') === core_converse.ROOMSTATUS.DISCONNECTED) { - shared_converse.chatboxes.get(room_jid).rejoin(); - } - } -} -function getDefaultMUCNickname() { - // XXX: if anything changes here, update the docs for the - // locked_muc_nickname setting. - if (!shared_converse.xmppstatus) { - throw new Error("Can't call _converse.getDefaultMUCNickname before the statusInitialized has been fired."); - } - - const nick = shared_converse.xmppstatus.getNickname(); - - if (nick) { - return nick; - } else if (api.settings.get('muc_nickname_from_jid')) { - return muc_utils_Strophe.unescapeNode(muc_utils_Strophe.getNodeFromJid(shared_converse.bare_jid)); - } -} -/** - * Determines info message visibility based on - * muc_show_info_messages configuration setting - * @param {*} code - * @memberOf _converse - */ - -function isInfoVisible(code) { - const info_messages = api.settings.get('muc_show_info_messages'); - - if (info_messages.includes(code)) { - return true; - } - - return false; -} -/* Automatically join groupchats, based on the - * "auto_join_rooms" configuration setting, which is an array - * of strings (groupchat JIDs) or objects (with groupchat JID and other settings). - */ - -async function autoJoinRooms() { - await Promise.all(api.settings.get('auto_join_rooms').map(muc => { - if (typeof muc === 'string') { - if (shared_converse.chatboxes.where({ - 'jid': muc - }).length) { - return Promise.resolve(); - } - - return api.rooms.open(muc); - } else if (lodash_es_isObject(muc)) { - return api.rooms.open(muc.jid, { ...muc - }); - } else { - headless_log.error('Invalid muc criteria specified for "auto_join_rooms"'); - return Promise.resolve(); - } - })); - /** - * Triggered once any rooms that have been configured to be automatically joined, - * specified via the _`auto_join_rooms` setting, have been entered. - * @event _converse#roomsAutoJoined - * @example _converse.api.listen.on('roomsAutoJoined', () => { ... }); - * @example _converse.api.waitUntil('roomsAutoJoined').then(() => { ... }); - */ - - api.trigger('roomsAutoJoined'); -} -function onAddClientFeatures() { - if (api.settings.get('allow_muc')) { - api.disco.own.features.add(muc_utils_Strophe.NS.MUC); - } - - if (api.settings.get('allow_muc_invitations')) { - api.disco.own.features.add('jabber:x:conference'); // Invites - } -} -function onBeforeTearDown() { - shared_converse.chatboxes.where({ - 'type': shared_converse.CHATROOMS_TYPE - }).forEach(muc => safeSave(muc.session, { - 'connection_status': core_converse.ROOMSTATUS.DISCONNECTED - })); -} -function onStatusInitialized() { - window.addEventListener(shared_converse.unloadevent, () => { - const using_websocket = api.connection.isType('websocket'); - - if (using_websocket && (!api.settings.get('enable_smacks') || !shared_converse.session.get('smacks_stream_id'))) { - // For non-SMACKS websocket connections, or non-resumeable - // connections, we disconnect all chatrooms when the page unloads. - // See issue #1111 - disconnectChatRooms(); - } - }); -} -function onBeforeResourceBinding() { - shared_converse.connection.addHandler(stanza => { - const muc_jid = muc_utils_Strophe.getBareJidFromJid(stanza.getAttribute('from')); - - if (!shared_converse.chatboxes.get(muc_jid)) { - api.waitUntil('chatBoxesFetched').then(async () => { - const muc = shared_converse.chatboxes.get(muc_jid); - - if (muc) { - await muc.initialized; - muc.message_handler.run(stanza); - } - }); - } - - return true; - }, null, 'message', 'groupchat'); -} -Object.assign(shared_converse, { - getAssignableRoles -}); -;// CONCATENATED MODULE: ./src/headless/plugins/muc/index.js -/** - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description Implements the non-view logic for XEP-0045 Multi-User Chat - */ - - - - - - - - - - - - - -const ROLES = ['moderator', 'participant', 'visitor']; -const AFFILIATIONS = ['owner', 'admin', 'member', 'outcast', 'none']; -core_converse.AFFILIATION_CHANGES = { - OWNER: 'owner', - ADMIN: 'admin', - MEMBER: 'member', - EXADMIN: 'exadmin', - EXOWNER: 'exowner', - EXOUTCAST: 'exoutcast', - EXMEMBER: 'exmember' -}; -core_converse.AFFILIATION_CHANGES_LIST = Object.values(core_converse.AFFILIATION_CHANGES); -core_converse.MUC_TRAFFIC_STATES = { - ENTERED: 'entered', - EXITED: 'exited' -}; -core_converse.MUC_TRAFFIC_STATES_LIST = Object.values(core_converse.MUC_TRAFFIC_STATES); -core_converse.MUC_ROLE_CHANGES = { - OP: 'op', - DEOP: 'deop', - VOICE: 'voice', - MUTE: 'mute' -}; -core_converse.MUC_ROLE_CHANGES_LIST = Object.values(core_converse.MUC_ROLE_CHANGES); -core_converse.MUC = {}; -core_converse.MUC.INFO_CODES = { - 'visibility_changes': ['100', '102', '103', '172', '173', '174'], - 'self': ['110'], - 'non_privacy_changes': ['104', '201'], - 'muc_logging_changes': ['170', '171'], - 'nickname_changes': ['210', '303'], - 'disconnected': ['301', '307', '321', '322', '332', '333'], - 'affiliation_changes': [...core_converse.AFFILIATION_CHANGES_LIST], - 'join_leave_events': [...core_converse.MUC_TRAFFIC_STATES_LIST], - 'role_changes': [...core_converse.MUC_ROLE_CHANGES_LIST] -}; -const { - Strophe: muc_Strophe -} = core_converse.env; // Add Strophe Namespaces - -muc_Strophe.addNamespace('MUC_ADMIN', muc_Strophe.NS.MUC + '#admin'); -muc_Strophe.addNamespace('MUC_OWNER', muc_Strophe.NS.MUC + '#owner'); -muc_Strophe.addNamespace('MUC_REGISTER', 'jabber:iq:register'); -muc_Strophe.addNamespace('MUC_ROOMCONF', muc_Strophe.NS.MUC + '#roomconfig'); -muc_Strophe.addNamespace('MUC_USER', muc_Strophe.NS.MUC + '#user'); -muc_Strophe.addNamespace('MUC_HATS', 'xmpp:prosody.im/protocol/hats:1'); -muc_Strophe.addNamespace('CONFINFO', 'urn:ietf:params:xml:ns:conference-info'); -core_converse.MUC_NICK_CHANGED_CODE = '303'; -core_converse.ROOM_FEATURES = ['passwordprotected', 'unsecured', 'hidden', 'publicroom', 'membersonly', 'open', 'persistent', 'temporary', 'nonanonymous', 'semianonymous', 'moderated', 'unmoderated', 'mam_enabled']; // No longer used in code, but useful as reference. -// -// const ROOM_FEATURES_MAP = { -// 'passwordprotected': 'unsecured', -// 'unsecured': 'passwordprotected', -// 'hidden': 'publicroom', -// 'publicroom': 'hidden', -// 'membersonly': 'open', -// 'open': 'membersonly', -// 'persistent': 'temporary', -// 'temporary': 'persistent', -// 'nonanonymous': 'semianonymous', -// 'semianonymous': 'nonanonymous', -// 'moderated': 'unmoderated', -// 'unmoderated': 'moderated' -// }; - -core_converse.ROOMSTATUS = { - CONNECTED: 0, - CONNECTING: 1, - NICKNAME_REQUIRED: 2, - PASSWORD_REQUIRED: 3, - DISCONNECTED: 4, - ENTERED: 5, - DESTROYED: 6, - BANNED: 7 -}; -core_converse.plugins.add('converse-muc', { - /* Optional dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. They are called "optional" because they might not be - * available, in which case any overrides applicable to them will be - * ignored. - * - * It's possible however to make optional dependencies non-optional. - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ['converse-chatboxes', 'converse-chat', 'converse-disco', 'converse-controlbox'], - overrides: { - ChatBoxes: { - model(attrs, options) { - const { - _converse - } = this.__super__; - - if (attrs && attrs.type == _converse.CHATROOMS_TYPE) { - return new _converse.ChatRoom(attrs, options); - } else { - return this.__super__.model.apply(this, arguments); - } - } - - } - }, - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - const { - __, - ___ - } = shared_converse; // Configuration values for this plugin - // ==================================== - // Refer to docs/source/configuration.rst for explanations of these - // configuration settings. - - api.settings.extend({ - 'allow_muc': true, - 'allow_muc_invitations': true, - 'auto_join_on_invite': false, - 'auto_join_rooms': [], - 'auto_register_muc_nickname': false, - 'hide_muc_participants': false, - 'locked_muc_domain': false, - 'modtools_disable_assign': false, - 'muc_clear_messages_on_leave': true, - 'muc_domain': undefined, - 'muc_fetch_members': true, - 'muc_history_max_stanzas': undefined, - 'muc_instant_rooms': true, - 'muc_nickname_from_jid': false, - 'muc_send_probes': false, - 'muc_show_info_messages': [...core_converse.MUC.INFO_CODES.visibility_changes, ...core_converse.MUC.INFO_CODES.self, ...core_converse.MUC.INFO_CODES.non_privacy_changes, ...core_converse.MUC.INFO_CODES.muc_logging_changes, ...core_converse.MUC.INFO_CODES.nickname_changes, ...core_converse.MUC.INFO_CODES.disconnected, ...core_converse.MUC.INFO_CODES.affiliation_changes, ...core_converse.MUC.INFO_CODES.join_leave_events, ...core_converse.MUC.INFO_CODES.role_changes], - 'muc_show_logs_before_join': false, - 'muc_show_ogp_unfurls': true, - 'muc_subscribe_to_rai': false - }); - api.promises.add(['roomsAutoJoined']); - - if (api.settings.get('locked_muc_domain') && typeof api.settings.get('muc_domain') !== 'string') { - throw new Error('Config Error: it makes no sense to set locked_muc_domain ' + 'to true when muc_domain is not set'); - } // This is for tests (at least until we can import modules inside tests) - - - core_converse.env.muc_utils = { - computeAffiliationsDelta: computeAffiliationsDelta - }; - Object.assign(api, muc_api); - Object.assign(api.rooms, affiliations_api); - /* https://xmpp.org/extensions/xep-0045.html - * ---------------------------------------- - * 100 message Entering a groupchat Inform user that any occupant is allowed to see the user's full JID - * 101 message (out of band) Affiliation change Inform user that his or her affiliation changed while not in the groupchat - * 102 message Configuration change Inform occupants that groupchat now shows unavailable members - * 103 message Configuration change Inform occupants that groupchat now does not show unavailable members - * 104 message Configuration change Inform occupants that a non-privacy-related groupchat configuration change has occurred - * 110 presence Any groupchat presence Inform user that presence refers to one of its own groupchat occupants - * 170 message or initial presence Configuration change Inform occupants that groupchat logging is now enabled - * 171 message Configuration change Inform occupants that groupchat logging is now disabled - * 172 message Configuration change Inform occupants that the groupchat is now non-anonymous - * 173 message Configuration change Inform occupants that the groupchat is now semi-anonymous - * 174 message Configuration change Inform occupants that the groupchat is now fully-anonymous - * 201 presence Entering a groupchat Inform user that a new groupchat has been created - * 210 presence Entering a groupchat Inform user that the service has assigned or modified the occupant's roomnick - * 301 presence Removal from groupchat Inform user that he or she has been banned from the groupchat - * 303 presence Exiting a groupchat Inform all occupants of new groupchat nickname - * 307 presence Removal from groupchat Inform user that he or she has been kicked from the groupchat - * 321 presence Removal from groupchat Inform user that he or she is being removed from the groupchat because of an affiliation change - * 322 presence Removal from groupchat Inform user that he or she is being removed from the groupchat because the groupchat has been changed to members-only and the user is not a member - * 332 presence Removal from groupchat Inform user that he or she is being removed from the groupchat because of a system shutdown - */ - - shared_converse.muc = { - info_messages: { - 100: __('This groupchat is not anonymous'), - 102: __('This groupchat now shows unavailable members'), - 103: __('This groupchat does not show unavailable members'), - 104: __('The groupchat configuration has changed'), - 170: __('Groupchat logging is now enabled'), - 171: __('Groupchat logging is now disabled'), - 172: __('This groupchat is now no longer anonymous'), - 173: __('This groupchat is now semi-anonymous'), - 174: __('This groupchat is now fully-anonymous'), - 201: __('A new groupchat has been created') - }, - new_nickname_messages: { - // XXX: Note the triple underscore function and not double underscore. - 210: ___('Your nickname has been automatically set to %1$s'), - 303: ___('Your nickname has been changed to %1$s') - }, - disconnect_messages: { - 301: __('You have been banned from this groupchat'), - 333: __('You have exited this groupchat due to a technical problem'), - 307: __('You have been kicked from this groupchat'), - 321: __('You have been removed from this groupchat because of an affiliation change'), - 322: __("You have been removed from this groupchat because the groupchat has changed to members-only and you're not a member"), - 332: __('You have been removed from this groupchat because the service hosting it is being shut down') - } - }; - - shared_converse.router.route('converse/room?jid=:jid', routeToRoom); - - shared_converse.ChatRoom = shared_converse.ChatBox.extend(muc); - shared_converse.ChatRoomMessage = shared_converse.Message.extend(muc_message); - shared_converse.ChatRoomOccupants = occupants; - shared_converse.ChatRoomOccupant = occupant; - /** - * Collection which stores MUC messages - * @class - * @namespace _converse.ChatRoomMessages - * @memberOf _converse - */ - - shared_converse.ChatRoomMessages = Collection.extend({ - model: shared_converse.ChatRoomMessage, - comparator: 'time' - }); - Object.assign(shared_converse, { - getDefaultMUCNickname: getDefaultMUCNickname, - isInfoVisible: isInfoVisible, - onDirectMUCInvitation: onDirectMUCInvitation - }); - /************************ BEGIN Event Handlers ************************/ - - if (api.settings.get('allow_muc_invitations')) { - api.listen.on('connected', registerDirectInvitationHandler); - api.listen.on('reconnected', registerDirectInvitationHandler); - } - - api.listen.on('addClientFeatures', () => api.disco.own.features.add(`${muc_Strophe.NS.CONFINFO}+notify`)); - api.listen.on('addClientFeatures', onAddClientFeatures); - api.listen.on('beforeResourceBinding', onBeforeResourceBinding); - api.listen.on('beforeTearDown', onBeforeTearDown); - api.listen.on('chatBoxesFetched', autoJoinRooms); - api.listen.on('disconnected', disconnectChatRooms); - api.listen.on('statusInitialized', onStatusInitialized); - api.listen.on('windowStateChanged', onWindowStateChanged); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/bookmarks/model.js - - -const { - Strophe: bookmarks_model_Strophe -} = core_converse.env; -const Bookmark = Model.extend({ - idAttribute: 'jid', - - getDisplayName() { - return bookmarks_model_Strophe.xmlunescape(this.get('name')); - } - -}); -/* harmony default export */ const bookmarks_model = (Bookmark); -// EXTERNAL MODULE: ./node_modules/jed/jed.js -var jed = __webpack_require__(6336); -var jed_default = /*#__PURE__*/__webpack_require__.n(jed); -;// CONCATENATED MODULE: ./src/i18n/index.js -/** - * @module i18n - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description This is the internationalization module - */ - - - -const { - dayjs -} = core_converse.env; - -function detectLocale(library_check) { - /* Determine which locale is supported by the user's system as well - * as by the relevant library (e.g. converse.js or dayjs). - * @param { Function } library_check - Returns a boolean indicating whether - * the locale is supported. - */ - let locale; - - if (window.navigator.userLanguage) { - locale = isLocaleAvailable(window.navigator.userLanguage, library_check); - } - - if (window.navigator.languages && !locale) { - for (let i = 0; i < window.navigator.languages.length && !locale; i++) { - locale = isLocaleAvailable(window.navigator.languages[i], library_check); - } - } - - if (window.navigator.browserLanguage && !locale) { - locale = isLocaleAvailable(window.navigator.browserLanguage, library_check); - } - - if (window.navigator.language && !locale) { - locale = isLocaleAvailable(window.navigator.language, library_check); - } - - if (window.navigator.systemLanguage && !locale) { - locale = isLocaleAvailable(window.navigator.systemLanguage, library_check); - } - - return locale || 'en'; -} - -function isConverseLocale(locale, supported_locales) { - return typeof locale === 'string' && supported_locales.includes(locale); -} - -function getLocale(preferred_locale, isSupportedByLibrary) { - if (typeof preferred_locale === 'string') { - if (preferred_locale === 'en' || isSupportedByLibrary(preferred_locale)) { - return preferred_locale; - } - } - - return detectLocale(isSupportedByLibrary) || 'en'; -} -/* Check whether the locale or sub locale (e.g. en-US, en) is supported. - * @param { String } locale - The locale to check for - * @param { Function } available - Returns a boolean indicating whether the locale is supported - */ - - -function isLocaleAvailable(locale, available) { - if (available(locale)) { - return locale; - } else { - var sublocale = locale.split("-")[0]; - - if (sublocale !== locale && available(sublocale)) { - return sublocale; - } - } -} -/* Fetch the translations for the given local at the given URL. - * @private - * @method i18n#fetchTranslations - * @param { _converse } - */ - - -async function fetchTranslations(_converse) { - const { - api, - locale - } = _converse; - const dayjs_locale = locale.toLowerCase().replace('_', '-'); - - if (!isConverseLocale(locale, api.settings.get("locales")) || locale === 'en') { - return; - } - - const { - default: data - } = await __webpack_require__(7521)(`./${locale}/LC_MESSAGES/converse.po`); - await __webpack_require__(9434)(`./${dayjs_locale}.js`); - dayjs.locale(getLocale(dayjs_locale, l => dayjs.locale(l))); - jed_instance = new (jed_default())(data); -} - -let jed_instance; -/** - * @namespace i18n - */ - -Object.assign(i18n, { - getLocale(preferred_locale, available_locales) { - return getLocale(preferred_locale, preferred => isConverseLocale(preferred, available_locales)); - }, - - translate(str) { - if (!jed_instance) { - return jed_default().sprintf.apply((jed_default()), arguments); - } - - const t = jed_instance.translate(str); - - if (arguments.length > 1) { - return t.fetch.apply(t, [].slice.call(arguments, 1)); - } else { - return t.fetch(); - } - }, - - async initialize() { - if (shared_converse.isTestEnv()) { - shared_converse.locale = 'en'; - } else { - try { - const preferred_locale = api.settings.get('i18n'); - shared_converse.locale = i18n.getLocale(preferred_locale, api.settings.get("locales")); - await fetchTranslations(shared_converse); - } catch (e) { - headless_log.fatal(e.message); - shared_converse.locale = 'en'; - } - } - }, - - __(...args) { - return i18n.translate(...args); - } - -}); -const __ = i18n.__; -;// CONCATENATED MODULE: ./src/headless/plugins/bookmarks/collection.js - - - - - - - -const { - Strophe: collection_Strophe, - $iq: collection_$iq, - sizzle: collection_sizzle -} = core_converse.env; -const Bookmarks = { - model: bookmarks_model, - comparator: item => item.get('name').toLowerCase(), - - initialize() { - this.on('add', bm => this.openBookmarkedRoom(bm).then(bm => this.markRoomAsBookmarked(bm)).catch(e => headless_log.fatal(e))); - this.on('remove', this.markRoomAsUnbookmarked, this); - this.on('remove', this.sendBookmarkStanza, this); - const cache_key = `converse.room-bookmarks${shared_converse.bare_jid}`; - this.fetched_flag = cache_key + 'fetched'; - initStorage(this, cache_key); - }, - - async openBookmarkedRoom(bookmark) { - if (api.settings.get('muc_respect_autojoin') && bookmark.get('autojoin')) { - const groupchat = await api.rooms.create(bookmark.get('jid'), { - 'nick': bookmark.get('nick') - }); - groupchat.maybeShow(); - } - - return bookmark; - }, - - fetchBookmarks() { - const deferred = getOpenPromise(); - - if (window.sessionStorage.getItem(this.fetched_flag)) { - this.fetch({ - 'success': () => deferred.resolve(), - 'error': () => deferred.resolve() - }); - } else { - this.fetchBookmarksFromServer(deferred); - } - - return deferred; - }, - - createBookmark(options) { - this.create(options); - this.sendBookmarkStanza().catch(iq => this.onBookmarkError(iq, options)); - }, - - sendBookmarkStanza() { - const stanza = collection_$iq({ - 'type': 'set', - 'from': shared_converse.connection.jid - }).c('pubsub', { - 'xmlns': collection_Strophe.NS.PUBSUB - }).c('publish', { - 'node': collection_Strophe.NS.BOOKMARKS - }).c('item', { - 'id': 'current' - }).c('storage', { - 'xmlns': collection_Strophe.NS.BOOKMARKS - }); - this.forEach(model => { - stanza.c('conference', { - 'name': model.get('name'), - 'autojoin': model.get('autojoin'), - 'jid': model.get('jid') - }).c('nick').t(model.get('nick')).up().up(); - }); - stanza.up().up().up(); - stanza.c('publish-options').c('x', { - 'xmlns': collection_Strophe.NS.XFORM, - 'type': 'submit' - }).c('field', { - 'var': 'FORM_TYPE', - 'type': 'hidden' - }).c('value').t('http://jabber.org/protocol/pubsub#publish-options').up().up().c('field', { - 'var': 'pubsub#persist_items' - }).c('value').t('true').up().up().c('field', { - 'var': 'pubsub#access_model' - }).c('value').t('whitelist'); - return api.sendIQ(stanza); - }, - - onBookmarkError(iq, options) { - headless_log.error("Error while trying to add bookmark"); - headless_log.error(iq); - api.alert('error', __('Error'), [__("Sorry, something went wrong while trying to save your bookmark.")]); - this.findWhere({ - 'jid': options.jid - }).destroy(); - }, - - fetchBookmarksFromServer(deferred) { - const stanza = collection_$iq({ - 'from': shared_converse.connection.jid, - 'type': 'get' - }).c('pubsub', { - 'xmlns': collection_Strophe.NS.PUBSUB - }).c('items', { - 'node': collection_Strophe.NS.BOOKMARKS - }); - api.sendIQ(stanza).then(iq => this.onBookmarksReceived(deferred, iq)).catch(iq => this.onBookmarksReceivedError(deferred, iq)); - }, - - markRoomAsBookmarked(bookmark) { - const groupchat = shared_converse.chatboxes.get(bookmark.get('jid')); - - if (groupchat !== undefined) { - groupchat.save('bookmarked', true); - } - }, - - markRoomAsUnbookmarked(bookmark) { - const groupchat = shared_converse.chatboxes.get(bookmark.get('jid')); - - if (groupchat !== undefined) { - groupchat.save('bookmarked', false); - } - }, - - createBookmarksFromStanza(stanza) { - const xmlns = collection_Strophe.NS.BOOKMARKS; - const sel = `items[node="${xmlns}"] item storage[xmlns="${xmlns}"] conference`; - collection_sizzle(sel, stanza).forEach(el => { - var _el$querySelector; - - const jid = el.getAttribute('jid'); - const bookmark = this.get(jid); - const attrs = { - 'jid': jid, - 'name': el.getAttribute('name') || jid, - 'autojoin': el.getAttribute('autojoin') === 'true', - 'nick': ((_el$querySelector = el.querySelector('nick')) === null || _el$querySelector === void 0 ? void 0 : _el$querySelector.textContent) || '' - }; - bookmark ? bookmark.save(attrs) : this.create(attrs); - }); - }, - - onBookmarksReceived(deferred, iq) { - this.createBookmarksFromStanza(iq); - window.sessionStorage.setItem(this.fetched_flag, true); - - if (deferred !== undefined) { - return deferred.resolve(); - } - }, - - onBookmarksReceivedError(deferred, iq) { - if (iq === null) { - headless_log.error('Error: timeout while fetching bookmarks'); - api.alert('error', __('Timeout Error'), [__("The server did not return your bookmarks within the allowed time. " + "You can reload the page to request them again.")]); - } else if (deferred) { - if (iq.querySelector('error[type="cancel"] item-not-found')) { - // Not an exception, the user simply doesn't have any bookmarks. - window.sessionStorage.setItem(this.fetched_flag, true); - return deferred.resolve(); - } else { - headless_log.error('Error while fetching bookmarks'); - headless_log.error(iq); - return deferred.reject(new Error("Could not fetch bookmarks")); - } - } else { - headless_log.error('Error while fetching bookmarks'); - headless_log.error(iq); - } - }, - - getUnopenedBookmarks() { - return this.filter(b => !shared_converse.chatboxes.get(b.get('jid'))); - } - -}; -/* harmony default export */ const collection = (Bookmarks); -;// CONCATENATED MODULE: ./src/headless/plugins/bookmarks/utils.js - -const { - Strophe: bookmarks_utils_Strophe -} = core_converse.env; -async function checkBookmarksSupport() { - const identity = await api.disco.getIdentity('pubsub', 'pep', shared_converse.bare_jid); - - if (shared_converse.allow_public_bookmarks) { - return !!identity; - } else { - return api.disco.supports(bookmarks_utils_Strophe.NS.PUBSUB + '#publish-options', shared_converse.bare_jid); - } -} -async function initBookmarks() { - if (!api.settings.get('allow_bookmarks')) { - return; - } - - if (await checkBookmarksSupport()) { - shared_converse.bookmarks = new shared_converse.Bookmarks(); - await shared_converse.bookmarks.fetchBookmarks(); - /** - * Triggered once the _converse.Bookmarks collection - * has been created and cached bookmarks have been fetched. - * @event _converse#bookmarksInitialized - * @example _converse.api.listen.on('bookmarksInitialized', () => { ... }); - */ - - api.trigger('bookmarksInitialized'); - } -} -/** - * Check if the user has a bookmark with a saved nickanme - * for this groupchat and return it. - */ - -function getNicknameFromBookmark(jid) { - if (!shared_converse.bookmarks || !api.settings.get('allow_bookmarks')) { - return null; - } - - const bookmark = shared_converse.bookmarks.findWhere({ - 'jid': jid - }); - - if (bookmark) { - return bookmark.get('nick'); - } -} -;// CONCATENATED MODULE: ./src/headless/plugins/bookmarks/index.js -/** - * @description - * Converse.js plugin which adds views for bookmarks specified in XEP-0048. - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - - -const { - Strophe: bookmarks_Strophe, - sizzle: bookmarks_sizzle -} = core_converse.env; -bookmarks_Strophe.addNamespace('BOOKMARKS', 'storage:bookmarks'); - -function handleBookmarksPush(message) { - if (bookmarks_sizzle(`event[xmlns="${bookmarks_Strophe.NS.PUBSUB}#event"] items[node="${bookmarks_Strophe.NS.BOOKMARKS}"]`, message).length) { - api.waitUntil('bookmarksInitialized').then(() => shared_converse.bookmarks.createBookmarksFromStanza(message)).catch(e => headless_log.fatal(e)); - } - - return true; -} - -core_converse.plugins.add('converse-bookmarks', { - /* Plugin dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. - * - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. By default it's - * false, which means these plugins are only loaded opportunistically. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ["converse-chatboxes", "converse-muc"], - overrides: { - // Overrides mentioned here will be picked up by converse.js's - // plugin architecture they will replace existing methods on the - // relevant objects or classes. - // - // New functions which don't exist yet can also be added. - ChatRoom: { - getDisplayName() { - const { - _converse - } = this.__super__; - - if (this.get('bookmarked') && _converse.bookmarks) { - const bookmark = _converse.bookmarks.findWhere({ - 'jid': this.get('jid') - }); - - if (bookmark) { - return bookmark.get('name'); - } - } - - return this.__super__.getDisplayName.apply(this, arguments); - }, - - getAndPersistNickname(nick) { - nick = nick || getNicknameFromBookmark(this.get('jid')); - return this.__super__.getAndPersistNickname.call(this, nick); - } - - } - }, - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - // Configuration values for this plugin - // ==================================== - // Refer to docs/source/configuration.rst for explanations of these - // configuration settings. - api.settings.extend({ - allow_bookmarks: true, - allow_public_bookmarks: false, - muc_respect_autojoin: true - }); - api.promises.add('bookmarksInitialized'); - shared_converse.Bookmark = bookmarks_model; - shared_converse.Bookmarks = Collection.extend(collection); - shared_converse.BookmarksList = Model.extend({ - defaults: { - "toggle-state": shared_converse.OPENED - } - }); - api.listen.on('addClientFeatures', () => { - if (api.settings.get('allow_bookmarks')) { - api.disco.own.features.add(bookmarks_Strophe.NS.BOOKMARKS + '+notify'); - } - }); - api.listen.on('clearSession', () => { - if (shared_converse.bookmarks !== undefined) { - shared_converse.bookmarks.clearStore({ - 'silent': true - }); - - window.sessionStorage.removeItem(shared_converse.bookmarks.fetched_flag); - delete shared_converse.bookmarks; - } - }); - api.listen.on('connected', async () => { - // Add a handler for bookmarks pushed from other connected clients - const { - connection - } = shared_converse; - connection.addHandler(handleBookmarksPush, null, 'message', 'headline', null, shared_converse.bare_jid); - await Promise.all([api.waitUntil('chatBoxesFetched')]); - initBookmarks(); - }); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/bosh.js -/** - * @module converse-bosh - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description Converse.js plugin which add support for XEP-0206: XMPP Over BOSH - */ - - - - -const { - Strophe: bosh_Strophe -} = core_converse.env; -const BOSH_SESSION_ID = 'converse.bosh-session'; -core_converse.plugins.add('converse-bosh', { - enabled() { - return !shared_converse.api.settings.get("blacklisted_plugins").includes('converse-bosh'); - }, - - initialize() { - api.settings.extend({ - bosh_service_url: undefined, - prebind_url: null - }); - - async function initBOSHSession() { - const id = BOSH_SESSION_ID; - - if (!shared_converse.bosh_session) { - shared_converse.bosh_session = new Model({ - id - }); - shared_converse.bosh_session.browserStorage = shared_converse.createStore(id, "session"); - await new Promise(resolve => shared_converse.bosh_session.fetch({ - 'success': resolve, - 'error': resolve - })); - } - - if (shared_converse.jid) { - if (shared_converse.bosh_session.get('jid') !== shared_converse.jid) { - const jid = await shared_converse.setUserJID(shared_converse.jid); - - shared_converse.bosh_session.clear({ - 'silent': true - }); - - shared_converse.bosh_session.save({ - jid - }); - } - } else { - // Keepalive - const jid = shared_converse.bosh_session.get('jid'); - - jid && (await shared_converse.setUserJID(jid)); - } - - return shared_converse.bosh_session; - } - - shared_converse.startNewPreboundBOSHSession = function () { - if (!api.settings.get('prebind_url')) { - throw new Error("startNewPreboundBOSHSession: If you use prebind then you MUST supply a prebind_url"); - } - - const xhr = new XMLHttpRequest(); - xhr.open('GET', api.settings.get('prebind_url'), true); - xhr.setRequestHeader('Accept', 'application/json, text/javascript'); - - xhr.onload = async function () { - if (xhr.status >= 200 && xhr.status < 400) { - const data = JSON.parse(xhr.responseText); - const jid = await shared_converse.setUserJID(data.jid); - - shared_converse.connection.attach(jid, data.sid, data.rid, shared_converse.connection.onConnectStatusChanged); - } else { - xhr.onerror(); - } - }; - - xhr.onerror = function () { - delete shared_converse.connection; - /** - * Triggered when fetching prebind tokens failed - * @event _converse#noResumeableBOSHSession - * @type { _converse } - * @example _converse.api.listen.on('noResumeableBOSHSession', _converse => { ... }); - */ - - api.trigger('noResumeableBOSHSession', shared_converse); - }; - - xhr.send(); - }; - - shared_converse.restoreBOSHSession = async function () { - const jid = (await initBOSHSession()).get('jid'); - - if (jid && shared_converse.connection._proto instanceof bosh_Strophe.Bosh) { - try { - shared_converse.connection.restore(jid, shared_converse.connection.onConnectStatusChanged); - - return true; - } catch (e) { - !shared_converse.isTestEnv() && headless_log.warn("Could not restore session for jid: " + jid + " Error message: " + e.message); - return false; - } - } - - return false; - }; - /************************ BEGIN Event Handlers ************************/ - - - api.listen.on('clearSession', () => { - if (shared_converse.bosh_session === undefined) { - // Remove manually, even if we don't have the corresponding - // model, to avoid trying to reconnect to a stale BOSH session - const id = BOSH_SESSION_ID; - sessionStorage.removeItem(id); - sessionStorage.removeItem(`${id}-${id}`); - } else { - shared_converse.bosh_session.destroy(); - - delete shared_converse.bosh_session; - } - }); - api.listen.on('setUserJID', () => { - if (shared_converse.bosh_session !== undefined) { - shared_converse.bosh_session.save({ - 'jid': shared_converse.jid - }); - } - }); - api.listen.on('addClientFeatures', () => api.disco.own.features.add(bosh_Strophe.NS.BOSH)); - /************************ END Event Handlers ************************/ - - /************************ BEGIN API ************************/ - - Object.assign(api, { - /** - * This namespace lets you access the BOSH tokens - * - * @namespace api.tokens - * @memberOf api - */ - tokens: { - /** - * @method api.tokens.get - * @param {string} [id] The type of token to return ('rid' or 'sid'). - * @returns 'string' A token, either the RID or SID token depending on what's asked for. - * @example _converse.api.tokens.get('rid'); - */ - get(id) { - if (shared_converse.connection === undefined) { - return null; - } - - if (id.toLowerCase() === 'rid') { - return shared_converse.connection.rid || shared_converse.connection._proto.rid; - } else if (id.toLowerCase() === 'sid') { - return shared_converse.connection.sid || shared_converse.connection._proto.sid; - } - } - - } - }); - /************************ end api ************************/ - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/caps/utils.js - - -const { - Strophe: caps_utils_Strophe, - $build: utils_$build -} = core_converse.env; - -function propertySort(array, property) { - return array.sort((a, b) => { - return a[property] > b[property] ? -1 : 1; - }); -} - -function generateVerificationString() { - const identities = shared_converse.api.disco.own.identities.get(); - - const features = shared_converse.api.disco.own.features.get(); - - if (identities.length > 1) { - propertySort(identities, "category"); - propertySort(identities, "type"); - propertySort(identities, "lang"); - } - - let S = identities.reduce((result, id) => `${result}${id.category}/${id.type}/${(id === null || id === void 0 ? void 0 : id.lang) ?? ''}/${id.name}<`, ""); - features.sort(); - S = features.reduce((result, feature) => `${result}${feature}<`, S); - return SHA1.b64_sha1(S); -} - -function createCapsNode() { - return utils_$build("c", { - 'xmlns': caps_utils_Strophe.NS.CAPS, - 'hash': "sha-1", - 'node': "https://conversejs.org", - 'ver': generateVerificationString() - }).nodeTree; -} -;// CONCATENATED MODULE: ./src/headless/plugins/caps/index.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - -const { - Strophe: caps_Strophe -} = core_converse.env; -caps_Strophe.addNamespace('CAPS', "http://jabber.org/protocol/caps"); -core_converse.plugins.add('converse-caps', { - dependencies: ['converse-status'], - - initialize() { - api.listen.on('constructedPresence', (_, p) => p.root().cnode(createCapsNode()).up() && p); - api.listen.on('constructedMUCPresence', (_, p) => p.root().cnode(createCapsNode()).up() && p); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/carbons.js -/** - * @module converse-carbons - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description Implements support for XEP-0280 Message Carbons - */ - - - -/* Ask the XMPP server to enable Message Carbons - * See XEP-0280 https://xmpp.org/extensions/xep-0280.html#enabling - */ - -function enableCarbons(reconnecting) { - var _converse$session2; - - if (reconnecting) { - var _converse$session; - - (_converse$session = shared_converse.session) === null || _converse$session === void 0 ? void 0 : _converse$session.set({ - 'carbons_enabled': false - }); - } - - if (!api.settings.get("message_carbons") || (_converse$session2 = shared_converse.session) !== null && _converse$session2 !== void 0 && _converse$session2.get('carbons_enabled')) { - return; - } - - const carbons_iq = new Strophe.Builder('iq', { - 'from': shared_converse.connection.jid, - 'id': 'enablecarbons', - 'type': 'set' - }).c('enable', { - xmlns: Strophe.NS.CARBONS - }); - - shared_converse.connection.addHandler(iq => { - if (iq.querySelectorAll('error').length > 0) { - headless_log.warn('An error occurred while trying to enable message carbons.'); - } else { - shared_converse.session.set({ - 'carbons_enabled': true - }); - - headless_log.debug('Message carbons have been enabled.'); - } - - shared_converse.session.save(); // Gather multiple sets into one save - - }, null, "iq", null, "enablecarbons"); - - shared_converse.connection.send(carbons_iq); -} - -core_converse.plugins.add('converse-carbons', { - initialize() { - api.settings.extend({ - message_carbons: true - }); - api.listen.on('afterResourceBinding', enableCarbons); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/chatboxes/chatboxes.js - - - -const ChatBoxes = Collection.extend({ - comparator: 'time_opened', - - model(attrs, options) { - return new shared_converse.ChatBox(attrs, options); - }, - - onChatBoxesFetched(collection) { - collection.filter(c => !c.isValid()).forEach(c => c.destroy()); - /** - * Triggered once all chat boxes have been recreated from the browser cache - * @event _converse#chatBoxesFetched - * @type { object } - * @property { _converse.ChatBox | _converse.ChatRoom } chatbox - * @property { XMLElement } stanza - * @example _converse.api.listen.on('chatBoxesFetched', obj => { ... }); - * @example _converse.api.waitUntil('chatBoxesFetched').then(() => { ... }); - */ - - api.trigger('chatBoxesFetched'); - }, - - onConnected(reconnecting) { - if (reconnecting) { - return; - } - - initStorage(this, `converse.chatboxes-${shared_converse.bare_jid}`); - this.fetch({ - 'add': true, - 'success': c => this.onChatBoxesFetched(c) - }); - } - -}); -/* harmony default export */ const chatboxes = (ChatBoxes); -;// CONCATENATED MODULE: ./src/headless/plugins/chatboxes/utils.js - - -const { - Strophe: chatboxes_utils_Strophe -} = core_converse.env; -async function createChatBox(jid, attrs, Model) { - jid = chatboxes_utils_Strophe.getBareJidFromJid(jid.toLowerCase()); - Object.assign(attrs, { - 'jid': jid, - 'id': jid - }); - let chatbox; - - try { - chatbox = new Model(attrs, { - 'collection': shared_converse.chatboxes - }); - } catch (e) { - headless_log.error(e); - return null; - } - - await chatbox.initialized; - - if (!chatbox.isValid()) { - chatbox.destroy(); - return null; - } - - shared_converse.chatboxes.add(chatbox); - - return chatbox; -} -;// CONCATENATED MODULE: ./src/headless/plugins/chatboxes/api.js - - -/** - * The "chatboxes" namespace. - * - * @namespace api.chatboxes - * @memberOf api - */ - -/* harmony default export */ const chatboxes_api = ({ - /** - * @method api.chats.create - * @param { String|String[] } jids - A JID or array of JIDs - * @param { Object } [attrs] An object containing configuration attributes - * @param { Model } model - The type of chatbox that should be created - */ - async create(jids = [], attrs = {}, model) { - await api.waitUntil('chatBoxesFetched'); - - if (typeof jids === 'string') { - return createChatBox(jids, attrs, model); - } else { - return Promise.all(jids.map(jid => createChatBox(jid, attrs, model))); - } - }, - - /** - * @method api.chats.get - * @param { String|String[] } jids - A JID or array of JIDs - */ - async get(jids) { - await api.waitUntil('chatBoxesFetched'); - - if (jids === undefined) { - return shared_converse.chatboxes.models; - } else if (typeof jids === 'string') { - return shared_converse.chatboxes.get(jids.toLowerCase()); - } else { - jids = jids.map(j => j.toLowerCase()); - return shared_converse.chatboxes.models.filter(m => jids.includes(m.get('jid'))); - } - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/chatboxes/index.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - -const { - Strophe: chatboxes_Strophe -} = core_converse.env; -core_converse.plugins.add('converse-chatboxes', { - dependencies: ["converse-emoji", "converse-roster", "converse-vcard"], - - initialize() { - api.promises.add(['chatBoxesFetched', 'chatBoxesInitialized', 'privateChatsAutoJoined']); - Object.assign(api, { - 'chatboxes': chatboxes_api - }); - shared_converse.ChatBoxes = chatboxes; - api.listen.on('addClientFeatures', () => { - api.disco.own.features.add(chatboxes_Strophe.NS.MESSAGE_CORRECT); - api.disco.own.features.add(chatboxes_Strophe.NS.HTTPUPLOAD); - api.disco.own.features.add(chatboxes_Strophe.NS.OUTOFBAND); - }); - api.listen.on('pluginsInitialized', () => { - shared_converse.chatboxes = new shared_converse.ChatBoxes(); - /** - * Triggered once the _converse.ChatBoxes collection has been initialized. - * @event _converse#chatBoxesInitialized - * @example _converse.api.listen.on('chatBoxesInitialized', () => { ... }); - * @example _converse.api.waitUntil('chatBoxesInitialized').then(() => { ... }); - */ - - api.trigger('chatBoxesInitialized'); - }); - api.listen.on('presencesInitialized', reconnecting => shared_converse.chatboxes.onConnected(reconnecting)); - api.listen.on('reconnected', () => shared_converse.chatboxes.forEach(m => m.onReconnection())); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/headlines.js -/** - * @module converse-headlines - * @copyright 2020, the Converse.js contributors - * @description XEP-0045 Multi-User Chat Views - */ - - - -core_converse.plugins.add('converse-headlines', { - /* Plugin dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. - * - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. By default it's - * false, which means these plugins are only loaded opportunistically. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ["converse-chat"], - overrides: { - // Overrides mentioned here will be picked up by converse.js's - // plugin architecture they will replace existing methods on the - // relevant objects or classes. - // - // New functions which don't exist yet can also be added. - ChatBoxes: { - model(attrs, options) { - const { - _converse - } = this.__super__; - - if (attrs.type == _converse.HEADLINES_TYPE) { - return new _converse.HeadlinesBox(attrs, options); - } else { - return this.__super__.model.apply(this, arguments); - } - } - - } - }, - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - - /** - * Shows headline messages - * @class - * @namespace _converse.HeadlinesBox - * @memberOf _converse - */ - shared_converse.HeadlinesBox = shared_converse.ChatBox.extend({ - defaults() { - return { - 'bookmarked': false, - 'hidden': ['mobile', 'fullscreen'].includes(api.settings.get("view_mode")), - 'message_type': 'headline', - 'num_unread': 0, - 'time_opened': this.get('time_opened') || new Date().getTime(), - 'type': shared_converse.HEADLINES_TYPE - }; - }, - - async initialize() { - this.set({ - 'box_id': `box-${this.get('jid')}` - }); - this.initUI(); - this.initMessages(); - await this.fetchMessages(); - /** - * Triggered once a {@link _converse.HeadlinesBox} has been created and initialized. - * @event _converse#headlinesBoxInitialized - * @type { _converse.HeadlinesBox } - * @example _converse.api.listen.on('headlinesBoxInitialized', model => { ... }); - */ - - api.trigger('headlinesBoxInitialized', this); - } - - }); - - async function onHeadlineMessage(stanza) { - // Handler method for all incoming messages of type "headline". - if (isHeadline(stanza) || isServerMessage(stanza)) { - const from_jid = stanza.getAttribute('from'); - await api.waitUntil('rosterInitialized'); - - if (from_jid.includes('@') && !shared_converse.roster.get(from_jid) && !api.settings.get("allow_non_roster_messaging")) { - return; - } - - if (stanza.querySelector('body') === null) { - // Avoid creating a chat box if we have nothing to show inside it. - return; - } - - const chatbox = shared_converse.chatboxes.create({ - 'id': from_jid, - 'jid': from_jid, - 'type': shared_converse.HEADLINES_TYPE, - 'from': from_jid - }); - - const attrs = await parseMessage(stanza, shared_converse); - await chatbox.createMessage(attrs); - api.trigger('message', { - chatbox, - stanza, - attrs - }); - } - } - /************************ BEGIN Event Handlers ************************/ - - - function registerHeadlineHandler() { - shared_converse.connection.addHandler(message => onHeadlineMessage(message) || true, null, 'message'); - } - - api.listen.on('connected', registerHeadlineHandler); - api.listen.on('reconnected', registerHeadlineHandler); - /************************ END Event Handlers ************************/ - - /************************ BEGIN API ************************/ - - Object.assign(api, { - /** - * The "headlines" namespace, which is used for headline-channels - * which are read-only channels containing messages of type - * "headline". - * - * @namespace api.headlines - * @memberOf api - */ - headlines: { - /** - * Retrieves a headline-channel or all headline-channels. - * - * @method api.headlines.get - * @param {String|String[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com'] - * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model. - * @param {Boolean} [create=false] - Whether the chat should be created if it's not found. - * @returns { Promise<_converse.HeadlinesBox> } - */ - async get(jids, attrs = {}, create = false) { - async function _get(jid) { - let model = await api.chatboxes.get(jid); - - if (!model && create) { - model = await api.chatboxes.create(jid, attrs, shared_converse.HeadlinesBox); - } else { - model = model && model.get('type') === shared_converse.HEADLINES_TYPE ? model : null; - - if (model && Object.keys(attrs).length) { - model.save(attrs); - } - } - - return model; - } - - if (jids === undefined) { - const chats = await api.chatboxes.get(); - return chats.filter(c => c.get('type') === shared_converse.HEADLINES_TYPE); - } else if (typeof jids === 'string') { - return _get(jids); - } - - return Promise.all(jids.map(jid => _get(jid))); - } - - } - }); - /************************ END API ************************/ - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/mam/placeholder.js - - -const placeholder_u = core_converse.env.utils; -class MAMPlaceholderMessage extends Model { - defaults() { - // eslint-disable-line class-methods-use-this - return { - 'msgid': placeholder_u.getUniqueId(), - 'is_ephemeral': false - }; - } - -} -;// CONCATENATED MODULE: ./src/headless/shared/rsm.js -/** - * @module converse-rsm - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description XEP-0059 Result Set Management - * Some code taken from the Strophe RSM plugin, licensed under the MIT License - * Copyright 2006-2017 Strophe (https://github.com/strophe/strophejs) - */ - - -const { - Strophe: rsm_Strophe, - $build: rsm_$build -} = core_converse.env; -rsm_Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm'); -/** - * @typedef { Object } RSMQueryParameters - * [XEP-0059 RSM](https://xmpp.org/extensions/xep-0059.html) Attributes that can be used to filter query results - * @property { String } [after] - The XEP-0359 stanza ID of a message after which messages should be returned. Implies forward paging. - * @property { String } [before] - The XEP-0359 stanza ID of a message before which messages should be returned. Implies backward paging. - * @property { Integer } [index=0] - The index of the results page to return. - * @property { Integer } [max] - The maximum number of items to return. - */ - -const RSM_QUERY_PARAMETERS = ['after', 'before', 'index', 'max']; - -const rsm_toNumber = v => Number(v); - -const rsm_toString = v => v.toString(); - -const RSM_TYPES = { - 'after': rsm_toString, - 'before': rsm_toString, - 'count': rsm_toNumber, - 'first': rsm_toString, - 'index': rsm_toNumber, - 'last': rsm_toString, - 'max': rsm_toNumber -}; - -const isUndefined = x => typeof x === 'undefined'; // This array contains both query attributes and response attributes - - -const RSM_ATTRIBUTES = Object.keys(RSM_TYPES); -/** - * Instances of this class are used to page through query results according to XEP-0059 Result Set Management - * @class RSM - */ - -class RSM { - static getQueryParameters(options = {}) { - return lodash_es_pick(options, RSM_QUERY_PARAMETERS); - } - - static parseXMLResult(set) { - const result = {}; - - for (var i = 0; i < RSM_ATTRIBUTES.length; i++) { - const attr = RSM_ATTRIBUTES[i]; - const elem = set.getElementsByTagName(attr)[0]; - - if (!isUndefined(elem) && elem !== null) { - result[attr] = RSM_TYPES[attr](rsm_Strophe.getText(elem)); - - if (attr == 'first') { - result.index = RSM_TYPES['index'](elem.getAttribute('index')); - } - } - } - - return result; - } - /** - * Create a new RSM instance - * @param { Object } options - Configuration options - * @constructor - */ - - - constructor(options = {}) { - this.query = RSM.getQueryParameters(options); - this.result = options.xml ? RSM.parseXMLResult(options.xml) : {}; - } - /** - * Returns a `` XML element that confirms to XEP-0059 Result Set Management. - * The element is constructed based on the { @link module:converse-rsm~RSMQueryParameters } - * that are set on this RSM instance. - * @returns { XMLElement } - */ - - - toXML() { - const xml = rsm_$build('set', { - xmlns: rsm_Strophe.NS.RSM - }); - - const reducer = (xml, a) => !isUndefined(this.query[a]) ? xml.c(a).t((this.query[a] || '').toString()).up() : xml; - - return RSM_QUERY_PARAMETERS.reduce(reducer, xml).tree(); - } - - next(max, before) { - const options = Object.assign({}, this.query, { - after: this.result.last, - before, - max - }); - return new RSM(options); - } - - previous(max, after) { - const options = Object.assign({}, this.query, { - after, - before: this.result.first, - max - }); - return new RSM(options); - } - -} -shared_converse.RSM_ATTRIBUTES = RSM_ATTRIBUTES; -shared_converse.RSM = RSM; -;// CONCATENATED MODULE: ./src/headless/plugins/mam/api.js - - - - -const { - Strophe: mam_api_Strophe, - $iq: mam_api_$iq, - dayjs: api_dayjs -} = core_converse.env; -const { - NS: api_NS -} = mam_api_Strophe; -const api_u = core_converse.env.utils; -/* harmony default export */ const mam_api = ({ - /** - * The [XEP-0313](https://xmpp.org/extensions/xep-0313.html) Message Archive Management API - * - * Enables you to query an XMPP server for archived messages. - * - * See also the [message-archiving](/docs/html/configuration.html#message-archiving) - * option in the configuration settings section, which you'll - * usually want to use in conjunction with this API. - * - * @namespace _converse.api.archive - * @memberOf _converse.api - */ - archive: { - /** - * @typedef { module:converse-rsm~RSMQueryParameters } MAMFilterParameters - * Filter parameters which can be used to filter a MAM XEP-0313 archive - * @property { String } [end] - A date string in ISO-8601 format, before which messages should be returned. Implies backward paging. - * @property { String } [start] - A date string in ISO-8601 format, after which messages should be returned. Implies forward paging. - * @property { String } [with] - A JID against which to match messages, according to either their `to` or `from` attributes. - * An item in a MUC archive matches if the publisher of the item matches the JID. - * If `with` is omitted, all messages that match the rest of the query will be returned, regardless of to/from - * addresses of each message. - */ - - /** - * The options that can be passed in to the { @link _converse.api.archive.query } method - * @typedef { module:converse-mam~MAMFilterParameters } ArchiveQueryOptions - * @property { Boolean } [groupchat=false] - Whether the MAM archive is for a groupchat. - */ - - /** - * Query for archived messages. - * - * The options parameter can also be an instance of - * RSM to enable easy querying between results pages. - * - * @method _converse.api.archive.query - * @param { module:converse-mam~ArchiveQueryOptions } options - An object containing query parameters - * @throws {Error} An error is thrown if the XMPP server responds with an error. - * @returns { Promise } A promise which resolves - * to a { @link module:converse-mam~MAMQueryResult } object. - * - * @example - * // Requesting all archived messages - * // ================================ - * // - * // The simplest query that can be made is to simply not pass in any parameters. - * // Such a query will return all archived messages for the current user. - * - * let result; - * try { - * result = await api.archive.query(); - * } catch (e) { - * // The query was not successful, perhaps inform the user? - * // The IQ stanza returned by the XMPP server is passed in, so that you - * // may inspect it and determine what the problem was. - * } - * // Do something with the messages, like showing them in your webpage. - * result.messages.forEach(m => this.showMessage(m)); - * - * @example - * // Requesting all archived messages for a particular contact or room - * // ================================================================= - * // - * // To query for messages sent between the current user and another user or room, - * // the query options need to contain the the JID (Jabber ID) of the user or - * // room under the `with` key. - * - * // For a particular user - * let result; - * try { - * result = await api.archive.query({'with': 'john@doe.net'}); - * } catch (e) { - * // The query was not successful - * } - * - * // For a particular room - * let result; - * try { - * result = await api.archive.query({'with': 'discuss@conference.doglovers.net', 'groupchat': true}); - * } catch (e) { - * // The query was not successful - * } - * - * @example - * // Requesting all archived messages before or after a certain date - * // =============================================================== - * // - * // The `start` and `end` parameters are used to query for messages - * // within a certain timeframe. The passed in date values may either be ISO8601 - * // formatted date strings, or JavaScript Date objects. - * - * const options = { - * 'with': 'john@doe.net', - * 'start': '2010-06-07T00:00:00Z', - * 'end': '2010-07-07T13:23:54Z' - * }; - * let result; - * try { - * result = await api.archive.query(options); - * } catch (e) { - * // The query was not successful - * } - * - * @example - * // Limiting the amount of messages returned - * // ======================================== - * // - * // The amount of returned messages may be limited with the `max` parameter. - * // By default, the messages are returned from oldest to newest. - * - * // Return maximum 10 archived messages - * let result; - * try { - * result = await api.archive.query({'with': 'john@doe.net', 'max':10}); - * } catch (e) { - * // The query was not successful - * } - * - * @example - * // Paging forwards through a set of archived messages - * // ================================================== - * // - * // When limiting the amount of messages returned per query, you might want to - * // repeatedly make a further query to fetch the next batch of messages. - * // - * // To simplify this usecase for you, the callback method receives not only an array - * // with the returned archived messages, but also a special RSM (*Result Set Management*) - * // object which contains the query parameters you passed in, as well - * // as two utility methods `next`, and `previous`. - * // - * // When you call one of these utility methods on the returned RSM object, and then - * // pass the result into a new query, you'll receive the next or previous batch of - * // archived messages. Please note, when calling these methods, pass in an integer - * // to limit your results. - * - * const options = {'with': 'john@doe.net', 'max':10}; - * let result; - * try { - * result = await api.archive.query(options); - * } catch (e) { - * // The query was not successful - * } - * // Do something with the messages, like showing them in your webpage. - * result.messages.forEach(m => this.showMessage(m)); - * - * while (!result.complete) { - * try { - * result = await api.archive.query(Object.assign(options, rsm.next(10).query)); - * } catch (e) { - * // The query was not successful - * } - * // Do something with the messages, like showing them in your webpage. - * result.messages.forEach(m => this.showMessage(m)); - * } - * - * @example - * // Paging backwards through a set of archived messages - * // =================================================== - * // - * // To page backwards through the archive, you need to know the UID of the message - * // which you'd like to page backwards from and then pass that as value for the - * // `before` parameter. If you simply want to page backwards from the most recent - * // message, pass in the `before` parameter with an empty string value `''`. - * - * let result; - * const options = {'before': '', 'max':5}; - * try { - * result = await api.archive.query(options); - * } catch (e) { - * // The query was not successful - * } - * // Do something with the messages, like showing them in your webpage. - * result.messages.forEach(m => this.showMessage(m)); - * - * // Now we query again, to get the previous batch. - * try { - * result = await api.archive.query(Object.assign(options, rsm.previous(5).query)); - * } catch (e) { - * // The query was not successful - * } - * // Do something with the messages, like showing them in your webpage. - * result.messages.forEach(m => this.showMessage(m)); - * - */ - async query(options) { - if (!api.connection.connected()) { - throw new Error('Can\'t call `api.archive.query` before having established an XMPP session'); - } - - const attrs = { - 'type': 'set' - }; - - if (options && options.groupchat) { - if (!options['with']) { - throw new Error('You need to specify a "with" value containing ' + 'the chat room JID, when querying groupchat messages.'); - } - - attrs.to = options['with']; - } - - const jid = attrs.to || shared_converse.bare_jid; - const supported = await api.disco.supports(api_NS.MAM, jid); - - if (!supported) { - headless_log.warn(`Did not fetch MAM archive for ${jid} because it doesn't support ${api_NS.MAM}`); - return { - 'messages': [] - }; - } - - const queryid = api_u.getUniqueId(); - const stanza = mam_api_$iq(attrs).c('query', { - 'xmlns': api_NS.MAM, - 'queryid': queryid - }); - - if (options) { - stanza.c('x', { - 'xmlns': api_NS.XFORM, - 'type': 'submit' - }).c('field', { - 'var': 'FORM_TYPE', - 'type': 'hidden' - }).c('value').t(api_NS.MAM).up().up(); - - if (options['with'] && !options.groupchat) { - stanza.c('field', { - 'var': 'with' - }).c('value').t(options['with']).up().up(); - } - - ['start', 'end'].forEach(t => { - if (options[t]) { - const date = api_dayjs(options[t]); - - if (date.isValid()) { - stanza.c('field', { - 'var': t - }).c('value').t(date.toISOString()).up().up(); - } else { - throw new TypeError(`archive.query: invalid date provided for: ${t}`); - } - } - }); - stanza.up(); - const rsm = new RSM(options); - - if (Object.keys(rsm.query).length) { - stanza.cnode(rsm.toXML()); - } - } - - const messages = []; - - const message_handler = shared_converse.connection.addHandler(stanza => { - const result = sizzle_default()(`message > result[xmlns="${api_NS.MAM}"]`, stanza).pop(); - - if (result === undefined || result.getAttribute('queryid') !== queryid) { - return true; - } - - const from = stanza.getAttribute('from') || shared_converse.bare_jid; - - if (options.groupchat) { - if (from !== options['with']) { - headless_log.warn(`Ignoring alleged groupchat MAM message from ${stanza.getAttribute('from')}`); - return true; - } - } else if (from !== shared_converse.bare_jid) { - headless_log.warn(`Ignoring alleged MAM message from ${stanza.getAttribute('from')}`); - return true; - } - - messages.push(stanza); - return true; - }, api_NS.MAM); - - let error; - const iq_result = await api.sendIQ(stanza, api.settings.get('message_archiving_timeout'), false); - - if (iq_result === null) { - const { - __ - } = shared_converse; - - const err_msg = __("Timeout while trying to fetch archived messages."); - - headless_log.error(err_msg); - error = new shared_converse.TimeoutError(err_msg); - return { - messages, - error - }; - } else if (api_u.isErrorStanza(iq_result)) { - const { - __ - } = shared_converse; - - const err_msg = __('An error occurred while querying for archived messages.'); - - headless_log.error(err_msg); - headless_log.error(iq_result); - error = new Error(err_msg); - return { - messages, - error - }; - } - - shared_converse.connection.deleteHandler(message_handler); - - let rsm; - const fin = iq_result && sizzle_default()(`fin[xmlns="${api_NS.MAM}"]`, iq_result).pop(); - const complete = (fin === null || fin === void 0 ? void 0 : fin.getAttribute('complete')) === 'true'; - const set = sizzle_default()(`set[xmlns="${api_NS.RSM}"]`, fin).pop(); - - if (set) { - rsm = new RSM({ ...options, - 'xml': set - }); - } - /** - * @typedef { Object } MAMQueryResult - * @property { Array } messages - * @property { RSM } [rsm] - An instance of { @link RSM }. - * You can call `next()` or `previous()` on this instance, - * to get the RSM query parameters for the next or previous - * page in the result set. - * @property { Boolean } complete - * @property { Error } [error] - */ - - - return { - messages, - rsm, - complete - }; - } - - } -}); -;// CONCATENATED MODULE: ./src/headless/plugins/mam/utils.js - - - - - - -const { - Strophe: mam_utils_Strophe, - $iq: mam_utils_$iq -} = core_converse.env; -const { - NS: utils_NS -} = mam_utils_Strophe; -const mam_utils_u = core_converse.env.utils; -function onMAMError(iq) { - if (iq !== null && iq !== void 0 && iq.querySelectorAll('feature-not-implemented').length) { - headless_log.warn(`Message Archive Management (XEP-0313) not supported by ${iq.getAttribute('from')}`); - } else { - headless_log.error(`Error while trying to set archiving preferences for ${iq.getAttribute('from')}.`); - headless_log.error(iq); - } -} -/** - * Handle returned IQ stanza containing Message Archive - * Management (XEP-0313) preferences. - * - * XXX: For now we only handle the global default preference. - * The XEP also provides for per-JID preferences, which is - * currently not supported in converse.js. - * - * Per JID preferences will be set in chat boxes, so it'll - * probbaly be handled elsewhere in any case. - */ - -function onMAMPreferences(iq, feature) { - const preference = sizzle_default()(`prefs[xmlns="${utils_NS.MAM}"]`, iq).pop(); - const default_pref = preference.getAttribute('default'); - - if (default_pref !== api.settings.get('message_archiving')) { - const stanza = mam_utils_$iq({ - 'type': 'set' - }).c('prefs', { - 'xmlns': utils_NS.MAM, - 'default': api.settings.get('message_archiving') - }); - Array.from(preference.children).forEach(child => stanza.cnode(child).up()); // XXX: Strictly speaking, the server should respond with the updated prefs - // (see example 18: https://xmpp.org/extensions/xep-0313.html#config) - // but Prosody doesn't do this, so we don't rely on it. - - api.sendIQ(stanza).then(() => feature.save({ - 'preferences': { - 'default': api.settings.get('message_archiving') - } - })).catch(shared_converse.onMAMError); - } else { - feature.save({ - 'preferences': { - 'default': api.settings.get('message_archiving') - } - }); - } -} -function getMAMPrefsFromFeature(feature) { - const prefs = feature.get('preferences') || {}; - - if (feature.get('var') !== utils_NS.MAM || api.settings.get('message_archiving') === undefined) { - return; - } - - if (prefs['default'] !== api.settings.get('message_archiving')) { - api.sendIQ(mam_utils_$iq({ - 'type': 'get' - }).c('prefs', { - 'xmlns': utils_NS.MAM - })).then(iq => shared_converse.onMAMPreferences(iq, feature)).catch(shared_converse.onMAMError); - } -} -function preMUCJoinMAMFetch(muc) { - if (!api.settings.get('muc_show_logs_before_join') || !muc.features.get('mam_enabled') || muc.get('prejoin_mam_fetched')) { - return; - } - - fetchNewestMessages(muc); - muc.save({ - 'prejoin_mam_fetched': true - }); -} -async function handleMAMResult(model, result, query, options, should_page) { - await api.emojis.initialize(); - - const is_muc = model.get('type') === shared_converse.CHATROOMS_TYPE; - - result.messages = result.messages.map(s => is_muc ? parseMUCMessage(s, model, shared_converse) : parseMessage(s, shared_converse)); - /** - * Synchronous event which allows listeners to first do some - * work based on the MAM result before calling the handlers here. - * @event _converse#MAMResult - */ - - const data = { - query, - 'chatbox': model, - 'messages': result.messages - }; - await api.trigger('MAMResult', data, { - 'synchronous': true - }); - result.messages.forEach(m => model.queueMessage(m)); - - if (result.error) { - const event_id = result.error.retry_event_id = mam_utils_u.getUniqueId(); - api.listen.once(event_id, () => fetchArchivedMessages(model, options, should_page)); - model.createMessageFromError(result.error); - } -} -/** - * @typedef { Object } MAMOptions - * A map of MAM related options that may be passed to fetchArchivedMessages - * @param { integer } [options.max] - The maximum number of items to return. - * Defaults to "archived_messages_page_size" - * @param { string } [options.after] - The XEP-0359 stanza ID of a message - * after which messages should be returned. Implies forward paging. - * @param { string } [options.before] - The XEP-0359 stanza ID of a message - * before which messages should be returned. Implies backward paging. - * @param { string } [options.end] - A date string in ISO-8601 format, - * before which messages should be returned. Implies backward paging. - * @param { string } [options.start] - A date string in ISO-8601 format, - * after which messages should be returned. Implies forward paging. - * @param { string } [options.with] - The JID of the entity with - * which messages were exchanged. - * @param { boolean } [options.groupchat] - True if archive in groupchat. - */ - -/** - * Fetch XEP-0313 archived messages based on the passed in criteria. - * @param { _converse.ChatBox | _converse.ChatRoom } model - * @param { MAMOptions } [options] - * @param { ('forwards'|'backwards'|null)} [should_page=null] - Determines whether - * this function should recursively page through the entire result set if a limited - * number of results were returned. - */ - -async function fetchArchivedMessages(model, options = {}, should_page = null) { - if (model.disable_mam) { - return; - } - - const is_muc = model.get('type') === shared_converse.CHATROOMS_TYPE; - - const mam_jid = is_muc ? model.get('jid') : shared_converse.bare_jid; - - if (!(await api.disco.supports(utils_NS.MAM, mam_jid))) { - return; - } - - const max = api.settings.get('archived_messages_page_size'); - const query = Object.assign({ - 'groupchat': is_muc, - 'max': max, - 'with': model.get('jid') - }, options); - const result = await api.archive.query(query); - await handleMAMResult(model, result, query, options, should_page); - - if (result.rsm && !result.complete) { - if (should_page) { - if (should_page === 'forwards') { - options = result.rsm.next(max, options.before).query; - } else if (should_page === 'backwards') { - options = result.rsm.previous(max, options.after).query; - } - - return fetchArchivedMessages(model, options, should_page); - } else { - createPlaceholder(model, options, result); - } - } -} -/** - * Create a placeholder message which is used to indicate gaps in the history. - * @param { _converse.ChatBox | _converse.ChatRoom } model - * @param { MAMOptions } options - * @param { object } result - The RSM result object - */ - -async function createPlaceholder(model, options, result) { - if (options.before == '' && (model.messages.length === 0 || !options.start)) { - // Fetching the latest MAM messages with an empty local cache - return; - } - - if (options.before && !options.start) { - // Infinite scrolling upward - return; - } - - if (options.before == null) { - // eslint-disable-line no-eq-null - // Adding placeholders when paging forwards is not supported yet, - // since currently with standard Converse, we only page forwards - // when fetching the entire history (i.e. no gaps should arise). - return; - } - - const msgs = await Promise.all(result.messages); - const { - rsm - } = result; - const key = `stanza_id ${model.get('jid')}`; - const adjacent_message = msgs.find(m => m[key] === rsm.result.first); - const msg_data = { - 'template_hook': 'getMessageTemplate', - 'time': new Date(new Date(adjacent_message['time']) - 1).toISOString(), - 'before': rsm.result.first, - 'start': options.start - }; - model.messages.add(new MAMPlaceholderMessage(msg_data)); -} -/** - * Fetches messages that might have been archived *after* - * the last archived message in our local cache. - * @param { _converse.ChatBox | _converse.ChatRoom } - */ - - -function fetchNewestMessages(model) { - if (model.disable_mam) { - return; - } - - const most_recent_msg = model.most_recent_cached_message; // if clear_messages_on_reconnection is true, than any recent messages - // must have been received *after* connection and we instead must query - // for earlier messages - - if (most_recent_msg && !api.settings.get('clear_messages_on_reconnection')) { - const should_page = api.settings.get('mam_request_all_pages'); - - if (should_page) { - const stanza_id = most_recent_msg.get(`stanza_id ${model.get('jid')}`); - - if (stanza_id) { - fetchArchivedMessages(model, { - 'after': stanza_id - }, 'forwards'); - } else { - fetchArchivedMessages(model, { - 'start': most_recent_msg.get('time') - }, 'forwards'); - } - } else { - fetchArchivedMessages(model, { - 'before': '', - 'start': most_recent_msg.get('time') - }); - } - } else { - fetchArchivedMessages(model, { - 'before': '' - }); - } -} -;// CONCATENATED MODULE: ./src/headless/plugins/mam/index.js -/** - * @description XEP-0313 Message Archive Management - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - -const { - Strophe: mam_Strophe -} = core_converse.env; -const { - NS: mam_NS -} = mam_Strophe; -core_converse.plugins.add('converse-mam', { - dependencies: ['converse-disco', 'converse-muc'], - - initialize() { - api.settings.extend({ - archived_messages_page_size: '50', - mam_request_all_pages: true, - message_archiving: undefined, - // Supported values are 'always', 'never', 'roster' (https://xmpp.org/extensions/xep-0313.html#prefs) - message_archiving_timeout: 20000 // Time (in milliseconds) to wait before aborting MAM request - - }); - Object.assign(api, mam_api); // This is mainly done to aid with tests - - Object.assign(shared_converse, { - onMAMError: onMAMError, - onMAMPreferences: onMAMPreferences, - handleMAMResult: handleMAMResult, - MAMPlaceholderMessage: MAMPlaceholderMessage - }); - /************************ Event Handlers ************************/ - - api.listen.on('addClientFeatures', () => api.disco.own.features.add(mam_NS.MAM)); - api.listen.on('serviceDiscovered', getMAMPrefsFromFeature); - api.listen.on('chatRoomViewInitialized', view => { - if (api.settings.get('muc_show_logs_before_join')) { - preMUCJoinMAMFetch(view.model); // If we want to show MAM logs before entering the MUC, we need - // to be informed once it's clear that this MUC supports MAM. - - view.model.features.on('change:mam_enabled', () => preMUCJoinMAMFetch(view.model)); - } - }); - api.listen.on('enteredNewRoom', muc => muc.features.get('mam_enabled') && fetchNewestMessages(muc)); - api.listen.on('chatReconnected', chat => { - // XXX: For MUCs, we listen to enteredNewRoom instead - if (chat.get('type') === shared_converse.PRIVATE_CHAT_TYPE) { - fetchNewestMessages(chat); - } - }); - api.listen.on('afterMessagesFetched', chat => { - // XXX: We don't want to query MAM every time this is triggered - // since it's not necessary when the chat is restored from cache. - // (given that BOSH or SMACKS will ensure that you get messages - // sent during the reload). - // With MUCs we can listen for `enteredNewRoom`. - if (chat.get('type') === shared_converse.PRIVATE_CHAT_TYPE && !shared_converse.connection.restored) { - fetchNewestMessages(chat); - } - }); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/ping/utils.js - -const { - Strophe: ping_utils_Strophe, - $iq: ping_utils_$iq -} = core_converse.env; -let lastStanzaDate; -function utils_onWindowStateChanged(data) { - if (data.state === 'visible' && api.connection.connected()) { - api.ping(null, 5000); - } -} -function setLastStanzaDate(date) { - lastStanzaDate = date; -} - -function pong(ping) { - lastStanzaDate = new Date(); - const from = ping.getAttribute('from'); - const id = ping.getAttribute('id'); - const iq = ping_utils_$iq({ - type: 'result', - to: from, - id: id - }); - - shared_converse.connection.sendIQ(iq); - - return true; -} - -function registerPongHandler() { - if (shared_converse.connection.disco !== undefined) { - api.disco.own.features.add(ping_utils_Strophe.NS.PING); - } - - return shared_converse.connection.addHandler(pong, ping_utils_Strophe.NS.PING, "iq", "get"); -} -function registerPingHandler() { - shared_converse.connection.addHandler(() => { - if (api.settings.get('ping_interval') > 0) { - // Handler on each stanza, saves the received date - // in order to ping only when needed. - lastStanzaDate = new Date(); - return true; - } - }); -} -function onConnected() { - // Wrapper so that we can spy on registerPingHandler in tests - registerPongHandler(); - registerPingHandler(); -} -function onEverySecond() { - if (shared_converse.isTestEnv() || !api.connection.connected()) { - return; - } - - const ping_interval = api.settings.get('ping_interval'); - - if (ping_interval > 0) { - const now = new Date(); - - if (!lastStanzaDate) { - lastStanzaDate = now; - } - - if ((now - lastStanzaDate) / 1000 > ping_interval) { - api.ping(); - } - } -} -;// CONCATENATED MODULE: ./src/headless/plugins/ping/api.js - - - -const { - Strophe: ping_api_Strophe, - $iq: ping_api_$iq, - u: ping_api_u -} = core_converse.env; -/* harmony default export */ const ping_api = ({ - /** - * Pings the service represented by the passed in JID by sending an IQ stanza. - * @private - * @method api.ping - * @param { String } [jid] - The JID of the service to ping - * @param { Integer } [timeout] - The amount of time in - * milliseconds to wait for a response. The default is 10000; - */ - async ping(jid, timeout) { - // XXX: We could first check here if the server advertised that it supports PING. - // However, some servers don't advertise while still responding to pings - // - // const feature = _converse.disco_entities[_converse.domain].features.findWhere({'var': Strophe.NS.PING}); - setLastStanzaDate(new Date()); - jid = jid || ping_api_Strophe.getDomainFromJid(shared_converse.bare_jid); - - if (shared_converse.connection) { - const iq = ping_api_$iq({ - 'type': 'get', - 'to': jid, - 'id': ping_api_u.getUniqueId('ping') - }).c('ping', { - 'xmlns': ping_api_Strophe.NS.PING - }); - const result = await api.sendIQ(iq, timeout || 10000, false); - - if (result === null) { - headless_log.warn(`Timeout while pinging ${jid}`); - - if (jid === ping_api_Strophe.getDomainFromJid(shared_converse.bare_jid)) { - api.connection.reconnect(); - } - } else if (ping_api_u.isErrorStanza(result)) { - headless_log.error(`Error while pinging ${jid}`); - headless_log.error(result); - } - - return true; - } - - return false; - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/ping/index.js -/** - * @description - * Converse.js plugin which add support for application-level pings - * as specified in XEP-0199 XMPP Ping. - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - -const { - Strophe: ping_Strophe -} = core_converse.env; -ping_Strophe.addNamespace('PING', "urn:xmpp:ping"); -core_converse.plugins.add('converse-ping', { - initialize() { - api.settings.extend({ - ping_interval: 60 //in seconds - - }); - Object.assign(api, ping_api); - setInterval(onEverySecond, 1000); - api.listen.on('connected', onConnected); - api.listen.on('reconnected', onConnected); - api.listen.on('windowStateChanged', utils_onWindowStateChanged); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/pubsub.js -/** - * @module converse-pubsub - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - -const { - Strophe: pubsub_Strophe, - $iq: pubsub_$iq -} = core_converse.env; -pubsub_Strophe.addNamespace('PUBSUB_ERROR', pubsub_Strophe.NS.PUBSUB + "#errors"); -core_converse.plugins.add('converse-pubsub', { - dependencies: ["converse-disco"], - - initialize() { - /************************ BEGIN API ************************/ - // We extend the default converse.js API to add methods specific to MUC groupchats. - Object.assign(shared_converse.api, { - /** - * The "pubsub" namespace groups methods relevant to PubSub - * - * @namespace _converse.api.pubsub - * @memberOf _converse.api - */ - 'pubsub': { - /** - * Publshes an item to a PubSub node - * - * @method _converse.api.pubsub.publish - * @param {string} jid The JID of the pubsub service where the node resides. - * @param {string} node The node being published to - * @param {Strophe.Builder} item The Strophe.Builder representation of the XML element being published - * @param {object} options An object representing the publisher options - * (see https://xmpp.org/extensions/xep-0060.html#publisher-publish-options) - * @param {boolean} strict_options Indicates whether the publisher - * options are a strict requirement or not. If they're NOT - * strict, then Converse will publish to the node even if - * the publish options precondication cannot be met. - */ - async 'publish'(jid, node, item, options, strict_options = true) { - const stanza = pubsub_$iq({ - 'from': shared_converse.bare_jid, - 'type': 'set', - 'to': jid - }).c('pubsub', { - 'xmlns': pubsub_Strophe.NS.PUBSUB - }).c('publish', { - 'node': node - }).cnode(item.tree()).up().up(); - - if (options) { - jid = jid || shared_converse.bare_jid; - - if (await api.disco.supports(pubsub_Strophe.NS.PUBSUB + '#publish-options', jid)) { - stanza.c('publish-options').c('x', { - 'xmlns': pubsub_Strophe.NS.XFORM, - 'type': 'submit' - }).c('field', { - 'var': 'FORM_TYPE', - 'type': 'hidden' - }).c('value').t(`${pubsub_Strophe.NS.PUBSUB}#publish-options`).up().up(); - Object.keys(options).forEach(k => stanza.c('field', { - 'var': k - }).c('value').t(options[k]).up().up()); - } else { - headless_log.warn(`_converse.api.publish: ${jid} does not support #publish-options, ` + `so we didn't set them even though they were provided.`); - } - } - - try { - await api.sendIQ(stanza); - } catch (iq) { - if (iq instanceof Element && strict_options && iq.querySelector(`precondition-not-met[xmlns="${pubsub_Strophe.NS.PUBSUB_ERROR}"]`)) { - // The publish-options precondition couldn't be - // met. We re-publish but without publish-options. - const el = stanza.nodeTree; - el.querySelector('publish-options').outerHTML = ''; - headless_log.warn(`PubSub: Republishing without publish options. ${el.outerHTML}`); - await api.sendIQ(el); - } else { - throw iq; - } - } - } - - } - }); - /************************ END API ************************/ - } - -}); -;// CONCATENATED MODULE: ./node_modules/lodash-es/isNumber.js - - -/** `Object#toString` result references. */ - -var isNumber_numberTag = '[object Number]'; -/** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - -function isNumber(value) { - return typeof value == 'number' || lodash_es_isObjectLike(value) && _baseGetTag(value) == isNumber_numberTag; -} - -/* harmony default export */ const lodash_es_isNumber = (isNumber); -;// CONCATENATED MODULE: ./node_modules/lodash-es/isNaN.js - -/** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - -function isNaN_isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return lodash_es_isNumber(value) && value != +value; -} - -/* harmony default export */ const lodash_es_isNaN = (isNaN_isNaN); -;// CONCATENATED MODULE: ./src/headless/plugins/status/status.js - - - - -const { - Strophe: status_Strophe, - $pres: status_$pres -} = core_converse.env; -const XMPPStatus = Model.extend({ - defaults() { - return { - "status": api.settings.get("default_state") - }; - }, - - initialize() { - this.on('change', item => { - if (!lodash_es_isObject(item.changed)) { - return; - } - - if ('status' in item.changed || 'status_message' in item.changed) { - api.user.presence.send(this.get('status'), null, this.get('status_message')); - } - }); - }, - - getNickname() { - return shared_converse.nickname; - }, - - getFullname() { - // Gets overridden in converse-vcard - return ''; - }, - - async constructPresence(type, to = null, status_message) { - type = typeof type === 'string' ? type : this.get('status') || api.settings.get("default_state"); - status_message = typeof status_message === 'string' ? status_message : this.get('status_message'); - let presence; - const attrs = { - to - }; - - if (type === 'unavailable' || type === 'probe' || type === 'error' || type === 'unsubscribe' || type === 'unsubscribed' || type === 'subscribe' || type === 'subscribed') { - attrs['type'] = type; - presence = status_$pres(attrs); - } else if (type === 'offline') { - attrs['type'] = 'unavailable'; - presence = status_$pres(attrs); - } else if (type === 'online') { - presence = status_$pres(attrs); - } else { - presence = status_$pres(attrs).c('show').t(type).up(); - } - - if (status_message) { - presence.c('status').t(status_message).up(); - } - - const priority = api.settings.get("priority"); - presence.c('priority').t(lodash_es_isNaN(Number(priority)) ? 0 : priority).up(); - - if (shared_converse.idle) { - const idle_since = new Date(); - idle_since.setSeconds(idle_since.getSeconds() - shared_converse.idle_seconds); - presence.c('idle', { - xmlns: status_Strophe.NS.IDLE, - since: idle_since.toISOString() - }); - } - - presence = await api.hook('constructedPresence', null, presence); - return presence; - } - -}); -/* harmony default export */ const status_status = (XMPPStatus); -;// CONCATENATED MODULE: ./src/headless/plugins/status/api.js - -/* harmony default export */ const status_api = ({ - /** - * @namespace _converse.api.user.presence - * @memberOf _converse.api.user - */ - presence: { - /** - * Send out a presence stanza - * @method _converse.api.user.presence.send - * @param { String } type - * @param { String } to - * @param { String } [status] - An optional status message - * @param { Element[]|Strophe.Builder[]|Element|Strophe.Builder } [child_nodes] - * Nodes(s) to be added as child nodes of the `presence` XML element. - */ - async send(type, to, status, child_nodes) { - await api.waitUntil('statusInitialized'); - const presence = await shared_converse.xmppstatus.constructPresence(type, to, status); - - if (child_nodes) { - if (!Array.isArray(child_nodes)) { - child_nodes = [child_nodes]; - } - - child_nodes.map(c => (c === null || c === void 0 ? void 0 : c.tree()) ?? c).forEach(c => presence.cnode(c).up()); - } - - api.send(presence); - } - - }, - - /** - * Set and get the user's chat status, also called their *availability*. - * @namespace _converse.api.user.status - * @memberOf _converse.api.user - */ - status: { - /** - * Return the current user's availability status. - * @async - * @method _converse.api.user.status.get - * @example _converse.api.user.status.get(); - */ - async get() { - await api.waitUntil('statusInitialized'); - return shared_converse.xmppstatus.get('status'); - }, - - /** - * The user's status can be set to one of the following values: - * - * @async - * @method _converse.api.user.status.set - * @param {string} value The user's chat status (e.g. 'away', 'dnd', 'offline', 'online', 'unavailable' or 'xa') - * @param {string} [message] A custom status message - * - * @example _converse.api.user.status.set('dnd'); - * @example _converse.api.user.status.set('dnd', 'In a meeting'); - */ - async set(value, message) { - const data = { - 'status': value - }; - - if (!Object.keys(shared_converse.STATUS_WEIGHTS).includes(value)) { - throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1'); - } - - if (typeof message === 'string') { - data.status_message = message; - } - - await api.waitUntil('statusInitialized'); - - shared_converse.xmppstatus.save(data); - }, - - /** - * Set and retrieve the user's custom status message. - * - * @namespace _converse.api.user.status.message - * @memberOf _converse.api.user.status - */ - message: { - /** - * @async - * @method _converse.api.user.status.message.get - * @returns {string} The status message - * @example const message = _converse.api.user.status.message.get() - */ - async get() { - await api.waitUntil('statusInitialized'); - return shared_converse.xmppstatus.get('status_message'); - }, - - /** - * @async - * @method _converse.api.user.status.message.set - * @param {string} status The status message - * @example _converse.api.user.status.message.set('In a meeting'); - */ - async set(status) { - await api.waitUntil('statusInitialized'); - - shared_converse.xmppstatus.save({ - status_message: status - }); - } - - } - } -}); -;// CONCATENATED MODULE: ./src/headless/plugins/status/utils.js - - -const { - Strophe: status_utils_Strophe, - $build: status_utils_$build -} = core_converse.env; - -function utils_onStatusInitialized(reconnecting) { - /** - * Triggered when the user's own chat status has been initialized. - * @event _converse#statusInitialized - * @example _converse.api.listen.on('statusInitialized', status => { ... }); - * @example _converse.api.waitUntil('statusInitialized').then(() => { ... }); - */ - api.trigger('statusInitialized', reconnecting); -} - -function initStatus(reconnecting) { - // If there's no xmppstatus obj, then we were never connected to - // begin with, so we set reconnecting to false. - reconnecting = shared_converse.xmppstatus === undefined ? false : reconnecting; - - if (reconnecting) { - utils_onStatusInitialized(reconnecting); - } else { - const id = `converse.xmppstatus-${shared_converse.bare_jid}`; - shared_converse.xmppstatus = new shared_converse.XMPPStatus({ - id - }); - initStorage(shared_converse.xmppstatus, id, 'session'); - - shared_converse.xmppstatus.fetch({ - 'success': () => utils_onStatusInitialized(reconnecting), - 'error': () => utils_onStatusInitialized(reconnecting), - 'silent': true - }); - } -} -function onUserActivity() { - var _converse$connection; - - /* Resets counters and flags relating to CSI and auto_away/auto_xa */ - if (shared_converse.idle_seconds > 0) { - shared_converse.idle_seconds = 0; - } - - if (!((_converse$connection = shared_converse.connection) !== null && _converse$connection !== void 0 && _converse$connection.authenticated)) { - // We can't send out any stanzas when there's no authenticated connection. - // This can happen when the connection reconnects. - return; - } - - if (shared_converse.inactive) { - shared_converse.sendCSI(shared_converse.ACTIVE); - } - - if (shared_converse.idle) { - shared_converse.idle = false; - api.user.presence.send(); - } - - if (shared_converse.auto_changed_status === true) { - shared_converse.auto_changed_status = false; // XXX: we should really remember the original state here, and - // then set it back to that... - - shared_converse.xmppstatus.set('status', api.settings.get("default_state")); - } -} -function utils_onEverySecond() { - var _converse$connection2; - - /* An interval handler running every second. - * Used for CSI and the auto_away and auto_xa features. - */ - if (!((_converse$connection2 = shared_converse.connection) !== null && _converse$connection2 !== void 0 && _converse$connection2.authenticated)) { - // We can't send out any stanzas when there's no authenticated connection. - // This can happen when the connection reconnects. - return; - } - - const stat = shared_converse.xmppstatus.get('status'); - - shared_converse.idle_seconds++; - - if (api.settings.get("csi_waiting_time") > 0 && shared_converse.idle_seconds > api.settings.get("csi_waiting_time") && !shared_converse.inactive) { - shared_converse.sendCSI(shared_converse.INACTIVE); - } - - if (api.settings.get("idle_presence_timeout") > 0 && shared_converse.idle_seconds > api.settings.get("idle_presence_timeout") && !shared_converse.idle) { - shared_converse.idle = true; - api.user.presence.send(); - } - - if (api.settings.get("auto_away") > 0 && shared_converse.idle_seconds > api.settings.get("auto_away") && stat !== 'away' && stat !== 'xa' && stat !== 'dnd') { - shared_converse.auto_changed_status = true; - - shared_converse.xmppstatus.set('status', 'away'); - } else if (api.settings.get("auto_xa") > 0 && shared_converse.idle_seconds > api.settings.get("auto_xa") && stat !== 'xa' && stat !== 'dnd') { - shared_converse.auto_changed_status = true; - - shared_converse.xmppstatus.set('status', 'xa'); - } -} -/** - * Send out a Client State Indication (XEP-0352) - * @function sendCSI - * @param { String } stat - The user's chat status - */ - -function sendCSI(stat) { - api.send(status_utils_$build(stat, { - xmlns: status_utils_Strophe.NS.CSI - })); - shared_converse.inactive = stat === shared_converse.INACTIVE ? true : false; -} -function registerIntervalHandler() { - /* Set an interval of one second and register a handler for it. - * Required for the auto_away, auto_xa and csi_waiting_time features. - */ - if (api.settings.get("auto_away") < 1 && api.settings.get("auto_xa") < 1 && api.settings.get("csi_waiting_time") < 1 && api.settings.get("idle_presence_timeout") < 1) { - // Waiting time of less then one second means features aren't used. - return; - } - - shared_converse.idle_seconds = 0; - shared_converse.auto_changed_status = false; // Was the user's status changed by Converse? - - const { - unloadevent - } = shared_converse; - window.addEventListener('click', shared_converse.onUserActivity); - window.addEventListener('focus', shared_converse.onUserActivity); - window.addEventListener('keypress', shared_converse.onUserActivity); - window.addEventListener('mousemove', shared_converse.onUserActivity); - window.addEventListener(unloadevent, shared_converse.onUserActivity, { - 'once': true, - 'passive': true - }); - window.addEventListener(unloadevent, () => { - var _converse$session; - - return (_converse$session = shared_converse.session) === null || _converse$session === void 0 ? void 0 : _converse$session.save('active', false); - }); - shared_converse.everySecondTrigger = window.setInterval(shared_converse.onEverySecond, 1000); -} -;// CONCATENATED MODULE: ./src/headless/plugins/status/index.js -/** - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - -core_converse.plugins.add('converse-status', { - initialize() { - api.settings.extend({ - auto_away: 0, - // Seconds after which user status is set to 'away' - auto_xa: 0, - // Seconds after which user status is set to 'xa' - csi_waiting_time: 0, - // Support for XEP-0352. Seconds before client is considered idle and CSI is sent out. - default_state: 'online', - priority: 0 - }); - api.promises.add(['statusInitialized']); - shared_converse.XMPPStatus = status_status; - shared_converse.onUserActivity = onUserActivity; - shared_converse.onEverySecond = utils_onEverySecond; - shared_converse.sendCSI = sendCSI; - shared_converse.registerIntervalHandler = registerIntervalHandler; - Object.assign(shared_converse.api.user, status_api); - api.listen.on('presencesInitialized', reconnecting => { - if (!reconnecting) { - shared_converse.registerIntervalHandler(); - } - }); - api.listen.on('clearSession', () => { - if (shared_converse.shouldClearCache() && shared_converse.xmppstatus) { - shared_converse.xmppstatus.destroy(); - - delete shared_converse.xmppstatus; - api.promises.add(['statusInitialized']); - } - }); - api.listen.on('connected', () => initStatus(false)); - api.listen.on('reconnected', () => initStatus(true)); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/roster/utils.js - - - - -const { - $pres: utils_$pres -} = core_converse.env; - -async function initRoster() { - // Initialize the Bakcbone collections that represent the contats - // roster and the roster groups. - await api.waitUntil('VCardsInitialized'); - shared_converse.roster = new shared_converse.RosterContacts(); - let id = `converse.contacts-${shared_converse.bare_jid}`; - initStorage(shared_converse.roster, id); - shared_converse.roster.data = new Model(); - id = `converse-roster-model-${shared_converse.bare_jid}`; - shared_converse.roster.data.id = id; - initStorage(shared_converse.roster.data, id); - - shared_converse.roster.data.fetch(); - /** - * Triggered once the `_converse.RosterContacts` - * been created, but not yet populated with data. - * This event is useful when you want to create views for these collections. - * @event _converse#chatBoxMaximized - * @example _converse.api.listen.on('rosterInitialized', () => { ... }); - * @example _converse.api.waitUntil('rosterInitialized').then(() => { ... }); - */ - - - api.trigger('rosterInitialized'); -} -/** - * Fetch all the roster groups, and then the roster contacts. - * Emit an event after fetching is done in each case. - * @private - * @param { Bool } ignore_cache - If set to to true, the local cache - * will be ignored it's guaranteed that the XMPP server - * will be queried for the roster. - */ - - -async function populateRoster(ignore_cache = false) { - if (ignore_cache) { - shared_converse.send_initial_presence = true; - } - - try { - await shared_converse.roster.fetchRosterContacts(); - api.trigger('rosterContactsFetched'); - } catch (reason) { - headless_log.error(reason); - } finally { - shared_converse.send_initial_presence && api.user.presence.send(); - } -} - -function updateUnreadCounter(chatbox) { - var _converse$roster; - - const contact = (_converse$roster = shared_converse.roster) === null || _converse$roster === void 0 ? void 0 : _converse$roster.findWhere({ - 'jid': chatbox.get('jid') - }); - contact === null || contact === void 0 ? void 0 : contact.save({ - 'num_unread': chatbox.get('num_unread') - }); -} - -function registerPresenceHandler() { - unregisterPresenceHandler(); - shared_converse.presence_ref = shared_converse.connection.addHandler(presence => { - shared_converse.roster.presenceHandler(presence); - - return true; - }, null, 'presence', null); -} - -function unregisterPresenceHandler() { - if (shared_converse.presence_ref !== undefined) { - shared_converse.connection.deleteHandler(shared_converse.presence_ref); - - delete shared_converse.presence_ref; - } -} - -async function clearPresences() { - var _converse$presences; - - await ((_converse$presences = shared_converse.presences) === null || _converse$presences === void 0 ? void 0 : _converse$presences.clearStore()); -} -/** - * Roster specific event handler for the clearSession event - */ - - -async function utils_onClearSession() { - await clearPresences(); - - if (shared_converse.shouldClearCache()) { - if (shared_converse.rostergroups) { - await shared_converse.rostergroups.clearStore(); - delete shared_converse.rostergroups; - } - - if (shared_converse.roster) { - var _converse$roster$data; - - (_converse$roster$data = shared_converse.roster.data) === null || _converse$roster$data === void 0 ? void 0 : _converse$roster$data.destroy(); - await shared_converse.roster.clearStore(); - delete shared_converse.roster; - } - } -} -/** - * Roster specific event handler for the presencesInitialized event - * @param { Boolean } reconnecting - */ - -async function onPresencesInitialized(reconnecting) { - if (reconnecting) { - /** - * Similar to `rosterInitialized`, but instead pertaining to reconnection. - * This event indicates that the roster and its groups are now again - * available after Converse.js has reconnected. - * @event _converse#rosterReadyAfterReconnection - * @example _converse.api.listen.on('rosterReadyAfterReconnection', () => { ... }); - */ - api.trigger('rosterReadyAfterReconnection'); - } else { - await initRoster(); - } - - shared_converse.roster.onConnected(); - - registerPresenceHandler(); - populateRoster(!shared_converse.connection.restored); -} -/** - * Roster specific event handler for the statusInitialized event - * @param { Boolean } reconnecting - */ - -async function roster_utils_onStatusInitialized(reconnecting) { - if (reconnecting) { - // When reconnecting and not resuming a previous session, - // we clear all cached presence data, since it might be stale - // and we'll receive new presence updates - !shared_converse.connection.hasResumed() && (await clearPresences()); - } else { - shared_converse.presences = new shared_converse.Presences(); - const id = `converse.presences-${shared_converse.bare_jid}`; - initStorage(shared_converse.presences, id, 'session'); // We might be continuing an existing session, so we fetch - // cached presence data. - - shared_converse.presences.fetch(); - } - /** - * Triggered once the _converse.Presences collection has been - * initialized and its cached data fetched. - * Returns a boolean indicating whether this event has fired due to - * Converse having reconnected. - * @event _converse#presencesInitialized - * @type { bool } - * @example _converse.api.listen.on('presencesInitialized', reconnecting => { ... }); - */ - - - api.trigger('presencesInitialized', reconnecting); -} -/** - * Roster specific event handler for the chatBoxesInitialized event - */ - -function onChatBoxesInitialized() { - shared_converse.chatboxes.on('change:num_unread', updateUnreadCounter); - - shared_converse.chatboxes.on('add', chatbox => { - if (chatbox.get('type') === shared_converse.PRIVATE_CHAT_TYPE) { - chatbox.setRosterContact(chatbox.get('jid')); - } - }); -} -/** - * Roster specific handler for the rosterContactsFetched promise - */ - -function onRosterContactsFetched() { - shared_converse.roster.on('add', contact => { - // When a new contact is added, check if we already have a - // chatbox open for it, and if so attach it to the chatbox. - const chatbox = shared_converse.chatboxes.findWhere({ - 'jid': contact.get('jid') - }); - - chatbox === null || chatbox === void 0 ? void 0 : chatbox.setRosterContact(contact.get('jid')); - }); -} -/** - * Reject or cancel another user's subscription to our presence updates. - * @function rejectPresenceSubscription - * @param { String } jid - The Jabber ID of the user whose subscription is being canceled - * @param { String } message - An optional message to the user - */ - -function rejectPresenceSubscription(jid, message) { - const pres = utils_$pres({ - to: jid, - type: "unsubscribed" - }); - - if (message && message !== "") { - pres.c("status").t(message); - } - - api.send(pres); -} -function contactsComparator(contact1, contact2) { - const status1 = contact1.presence.get('show') || 'offline'; - const status2 = contact2.presence.get('show') || 'offline'; - - if (shared_converse.STATUS_WEIGHTS[status1] === shared_converse.STATUS_WEIGHTS[status2]) { - const name1 = contact1.getDisplayName().toLowerCase(); - const name2 = contact2.getDisplayName().toLowerCase(); - return name1 < name2 ? -1 : name1 > name2 ? 1 : 0; - } else { - return shared_converse.STATUS_WEIGHTS[status1] < shared_converse.STATUS_WEIGHTS[status2] ? -1 : 1; - } -} -function groupsComparator(a, b) { - const HEADER_WEIGHTS = {}; - HEADER_WEIGHTS[shared_converse.HEADER_UNREAD] = 0; - HEADER_WEIGHTS[shared_converse.HEADER_REQUESTING_CONTACTS] = 1; - HEADER_WEIGHTS[shared_converse.HEADER_CURRENT_CONTACTS] = 2; - HEADER_WEIGHTS[shared_converse.HEADER_UNGROUPED] = 3; - HEADER_WEIGHTS[shared_converse.HEADER_PENDING_CONTACTS] = 4; - const WEIGHTS = HEADER_WEIGHTS; - const special_groups = Object.keys(HEADER_WEIGHTS); - const a_is_special = special_groups.includes(a); - const b_is_special = special_groups.includes(b); - - if (!a_is_special && !b_is_special) { - return a.toLowerCase() < b.toLowerCase() ? -1 : a.toLowerCase() > b.toLowerCase() ? 1 : 0; - } else if (a_is_special && b_is_special) { - return WEIGHTS[a] < WEIGHTS[b] ? -1 : WEIGHTS[a] > WEIGHTS[b] ? 1 : 0; - } else if (!a_is_special && b_is_special) { - const a_header = shared_converse.HEADER_CURRENT_CONTACTS; - return WEIGHTS[a_header] < WEIGHTS[b] ? -1 : WEIGHTS[a_header] > WEIGHTS[b] ? 1 : 0; - } else if (a_is_special && !b_is_special) { - const b_header = shared_converse.HEADER_CURRENT_CONTACTS; - return WEIGHTS[a] < WEIGHTS[b_header] ? -1 : WEIGHTS[a] > WEIGHTS[b_header] ? 1 : 0; - } -} -;// CONCATENATED MODULE: ./src/headless/plugins/roster/contact.js - - - - -const { - Strophe: contact_Strophe, - $iq: contact_$iq, - $pres: contact_$pres -} = core_converse.env; -/** - * @class - * @namespace RosterContact - */ - -const RosterContact = Model.extend({ - defaults: { - 'chat_state': undefined, - 'groups': [], - 'image': shared_converse.DEFAULT_IMAGE, - 'image_type': shared_converse.DEFAULT_IMAGE_TYPE, - 'num_unread': 0, - 'status': undefined - }, - - async initialize(attributes) { - this.initialized = getOpenPromise(); - this.setPresence(); - const { - jid - } = attributes; - const bare_jid = contact_Strophe.getBareJidFromJid(jid).toLowerCase(); - attributes.jid = bare_jid; - this.set(Object.assign({ - 'id': bare_jid, - 'jid': bare_jid, - 'user_id': contact_Strophe.getNodeFromJid(jid) - }, attributes)); - /** - * When a contact's presence status has changed. - * The presence status is either `online`, `offline`, `dnd`, `away` or `xa`. - * @event _converse#contactPresenceChanged - * @type { _converse.RosterContact } - * @example _converse.api.listen.on('contactPresenceChanged', contact => { ... }); - */ - - this.listenTo(this.presence, 'change:show', () => api.trigger('contactPresenceChanged', this)); - this.listenTo(this.presence, 'change:show', () => this.trigger('presenceChanged')); - /** - * Synchronous event which provides a hook for further initializing a RosterContact - * @event _converse#rosterContactInitialized - * @param { _converse.RosterContact } contact - */ - - await api.trigger('rosterContactInitialized', this, { - 'Synchronous': true - }); - this.initialized.resolve(); - }, - - setPresence() { - const jid = this.get('jid'); - this.presence = shared_converse.presences.findWhere({ - 'jid': jid - }) || shared_converse.presences.create({ - 'jid': jid - }); - }, - - openChat() { - const attrs = this.attributes; - api.chats.open(attrs.jid, attrs, true); - }, - - /** - * Return a string of tab-separated values that are to be used when - * matching against filter text. - * - * The goal is to be able to filter against the VCard fullname, - * roster nickname and JID. - * @returns { String } Lower-cased, tab-separated values - */ - getFilterCriteria() { - const nick = this.get('nickname'); - const jid = this.get('jid'); - let criteria = this.getDisplayName(); - criteria = !criteria.includes(jid) ? criteria.concat(` ${jid}`) : criteria; - criteria = !criteria.includes(nick) ? criteria.concat(` ${nick}`) : criteria; - return criteria.toLowerCase(); - }, - - getDisplayName() { - // Gets overridden in converse-vcard where the fullname is may be returned - if (this.get('nickname')) { - return this.get('nickname'); - } else { - return this.get('jid'); - } - }, - - getFullname() { - // Gets overridden in converse-vcard where the fullname may be returned - return this.get('jid'); - }, - - /** - * Send a presence subscription request to this roster contact - * @private - * @method _converse.RosterContacts#subscribe - * @param { String } message - An optional message to explain the - * reason for the subscription request. - */ - subscribe(message) { - const pres = contact_$pres({ - to: this.get('jid'), - type: "subscribe" - }); - - if (message && message !== "") { - pres.c("status").t(message).up(); - } - - const nick = shared_converse.xmppstatus.getNickname() || shared_converse.xmppstatus.getFullname(); - - if (nick) { - pres.c('nick', { - 'xmlns': contact_Strophe.NS.NICK - }).t(nick).up(); - } - - api.send(pres); - this.save('ask', "subscribe"); // ask === 'subscribe' Means we have asked to subscribe to them. - - return this; - }, - - /** - * Upon receiving the presence stanza of type "subscribed", - * the user SHOULD acknowledge receipt of that subscription - * state notification by sending a presence stanza of type - * "subscribe" to the contact - * @private - * @method _converse.RosterContacts#ackSubscribe - */ - ackSubscribe() { - api.send(contact_$pres({ - 'type': 'subscribe', - 'to': this.get('jid') - })); - }, - - /** - * Upon receiving the presence stanza of type "unsubscribed", - * the user SHOULD acknowledge receipt of that subscription state - * notification by sending a presence stanza of type "unsubscribe" - * this step lets the user's server know that it MUST no longer - * send notification of the subscription state change to the user. - * @private - * @method _converse.RosterContacts#ackUnsubscribe - * @param { String } jid - The Jabber ID of the user who is unsubscribing - */ - ackUnsubscribe() { - api.send(contact_$pres({ - 'type': 'unsubscribe', - 'to': this.get('jid') - })); - this.removeFromRoster(); - this.destroy(); - }, - - /** - * Unauthorize this contact's presence subscription - * @private - * @method _converse.RosterContacts#unauthorize - * @param { String } message - Optional message to send to the person being unauthorized - */ - unauthorize(message) { - rejectPresenceSubscription(this.get('jid'), message); - return this; - }, - - /** - * Authorize presence subscription - * @private - * @method _converse.RosterContacts#authorize - * @param { String } message - Optional message to send to the person being authorized - */ - authorize(message) { - const pres = contact_$pres({ - 'to': this.get('jid'), - 'type': "subscribed" - }); - - if (message && message !== "") { - pres.c("status").t(message); - } - - api.send(pres); - return this; - }, - - /** - * Instruct the XMPP server to remove this contact from our roster - * @private - * @method _converse.RosterContacts# - * @returns { Promise } - */ - removeFromRoster() { - const iq = contact_$iq({ - type: 'set' - }).c('query', { - xmlns: contact_Strophe.NS.ROSTER - }).c('item', { - jid: this.get('jid'), - subscription: "remove" - }); - return api.sendIQ(iq); - } - -}); -/* harmony default export */ const contact = (RosterContact); -;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSum.js -/** - * The base implementation of `_.sum` and `_.sumBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ -function baseSum(array, iteratee) { - var result, - index = -1, - length = array.length; - - while (++index < length) { - var current = iteratee(array[index]); - - if (current !== undefined) { - result = result === undefined ? current : result + current; - } - } - - return result; -} - -/* harmony default export */ const _baseSum = (baseSum); -;// CONCATENATED MODULE: ./node_modules/lodash-es/sum.js - - -/** - * Computes the sum of the values in `array`. - * - * @static - * @memberOf _ - * @since 3.4.0 - * @category Math - * @param {Array} array The array to iterate over. - * @returns {number} Returns the sum. - * @example - * - * _.sum([4, 2, 8, 6]); - * // => 20 - */ - -function sum(array) { - return array && array.length ? _baseSum(array, lodash_es_identity) : 0; -} - -/* harmony default export */ const lodash_es_sum = (sum); -;// CONCATENATED MODULE: ./src/headless/plugins/roster/contacts.js - - - - - - - - - -const { - Strophe: contacts_Strophe, - $iq: contacts_$iq, - sizzle: contacts_sizzle, - u: contacts_u -} = core_converse.env; -const RosterContacts = Collection.extend({ - model: contact, - - initialize() { - const id = `roster.state-${shared_converse.bare_jid}-${this.get('jid')}`; - this.state = new Model({ - id, - 'collapsed_groups': [] - }); - initStorage(this.state, id); - this.state.fetch(); - }, - - onConnected() { - // Called as soon as the connection has been established - // (either after initial login, or after reconnection). - // Use the opportunity to register stanza handlers. - this.registerRosterHandler(); - this.registerRosterXHandler(); - }, - - registerRosterHandler() { - // Register a handler for roster IQ "set" stanzas, which update - // roster contacts. - shared_converse.connection.addHandler(iq => { - shared_converse.roster.onRosterPush(iq); - - return true; - }, contacts_Strophe.NS.ROSTER, 'iq', "set"); - }, - - registerRosterXHandler() { - // Register a handler for RosterX message stanzas, which are - // used to suggest roster contacts to a user. - let t = 0; - - shared_converse.connection.addHandler(function (msg) { - window.setTimeout(function () { - shared_converse.connection.flush(); - - shared_converse.roster.subscribeToSuggestedItems.bind(shared_converse.roster)(msg); - }, t); - t += msg.querySelectorAll('item').length * 250; - return true; - }, contacts_Strophe.NS.ROSTERX, 'message', null); - }, - - /** - * Fetches the roster contacts, first by trying the browser cache, - * and if that's empty, then by querying the XMPP server. - * @private - * @returns {promise} Promise which resolves once the contacts have been fetched. - */ - async fetchRosterContacts() { - const result = await new Promise((resolve, reject) => { - this.fetch({ - 'add': true, - 'silent': true, - 'success': resolve, - 'error': (c, e) => reject(e) - }); - }); - - if (contacts_u.isErrorObject(result)) { - headless_log.error(result); // Force a full roster refresh - - shared_converse.session.save('roster_cached', false); - - this.data.save('version', undefined); - } - - if (shared_converse.session.get('roster_cached')) { - /** - * The contacts roster has been retrieved from the local cache (`sessionStorage`). - * @event _converse#cachedRoster - * @type { _converse.RosterContacts } - * @example _converse.api.listen.on('cachedRoster', (items) => { ... }); - * @example _converse.api.waitUntil('cachedRoster').then(items => { ... }); - */ - api.trigger('cachedRoster', result); - } else { - shared_converse.send_initial_presence = true; - return shared_converse.roster.fetchFromServer(); - } - }, - - subscribeToSuggestedItems(msg) { - Array.from(msg.querySelectorAll('item')).forEach(item => { - if (item.getAttribute('action') === 'add') { - shared_converse.roster.addAndSubscribe(item.getAttribute('jid'), shared_converse.xmppstatus.getNickname() || shared_converse.xmppstatus.getFullname()); - } - }); - return true; - }, - - isSelf(jid) { - return contacts_u.isSameBareJID(jid, shared_converse.connection.jid); - }, - - /** - * Add a roster contact and then once we have confirmation from - * the XMPP server we subscribe to that contact's presence updates. - * @private - * @method _converse.RosterContacts#addAndSubscribe - * @param { String } jid - The Jabber ID of the user being added and subscribed to. - * @param { String } name - The name of that user - * @param { Array.String } groups - Any roster groups the user might belong to - * @param { String } message - An optional message to explain the reason for the subscription request. - * @param { Object } attributes - Any additional attributes to be stored on the user's model. - */ - async addAndSubscribe(jid, name, groups, message, attributes) { - const contact = await this.addContactToRoster(jid, name, groups, attributes); - - if (contact instanceof shared_converse.RosterContact) { - contact.subscribe(message); - } - }, - - /** - * Send an IQ stanza to the XMPP server to add a new roster contact. - * @private - * @method _converse.RosterContacts#sendContactAddIQ - * @param { String } jid - The Jabber ID of the user being added - * @param { String } name - The name of that user - * @param { Array.String } groups - Any roster groups the user might belong to - * @param { Function } callback - A function to call once the IQ is returned - * @param { Function } errback - A function to call if an error occurred - */ - sendContactAddIQ(jid, name, groups) { - name = name ? name : null; - const iq = contacts_$iq({ - 'type': 'set' - }).c('query', { - 'xmlns': contacts_Strophe.NS.ROSTER - }).c('item', { - jid, - name - }); - groups.forEach(g => iq.c('group').t(g).up()); - return api.sendIQ(iq); - }, - - /** - * Adds a RosterContact instance to _converse.roster and - * registers the contact on the XMPP server. - * Returns a promise which is resolved once the XMPP server has responded. - * @private - * @method _converse.RosterContacts#addContactToRoster - * @param { String } jid - The Jabber ID of the user being added and subscribed to. - * @param { String } name - The name of that user - * @param { Array.String } groups - Any roster groups the user might belong to - * @param { Object } attributes - Any additional attributes to be stored on the user's model. - */ - async addContactToRoster(jid, name, groups, attributes) { - await api.waitUntil('rosterContactsFetched'); - groups = groups || []; - - try { - await this.sendContactAddIQ(jid, name, groups); - } catch (e) { - headless_log.error(e); - alert(__('Sorry, there was an error while trying to add %1$s as a contact.', name || jid)); - return e; - } - - return this.create(Object.assign({ - 'ask': undefined, - 'nickname': name, - groups, - jid, - 'requesting': false, - 'subscription': 'none' - }, attributes), { - 'sort': false - }); - }, - - async subscribeBack(bare_jid, presence) { - const contact = this.get(bare_jid); - - if (contact instanceof shared_converse.RosterContact) { - contact.authorize().subscribe(); - } else { - var _sizzle$pop; - - // Can happen when a subscription is retried or roster was deleted - const nickname = ((_sizzle$pop = contacts_sizzle(`nick[xmlns="${contacts_Strophe.NS.NICK}"]`, presence).pop()) === null || _sizzle$pop === void 0 ? void 0 : _sizzle$pop.textContent) || null; - const contact = await this.addContactToRoster(bare_jid, nickname, [], { - 'subscription': 'from' - }); - - if (contact instanceof shared_converse.RosterContact) { - contact.authorize().subscribe(); - } - } - }, - - getNumOnlineContacts() { - const ignored = ['offline', 'unavailable']; - return lodash_es_sum(this.models.filter(m => !ignored.includes(m.presence.get('show')))); - }, - - /** - * Handle roster updates from the XMPP server. - * See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push - * @private - * @method _converse.RosterContacts#onRosterPush - * @param { XMLElement } IQ - The IQ stanza received from the XMPP server. - */ - onRosterPush(iq) { - const id = iq.getAttribute('id'); - const from = iq.getAttribute('from'); - - if (from && from !== shared_converse.bare_jid) { - // https://tools.ietf.org/html/rfc6121#page-15 - // - // A receiving client MUST ignore the stanza unless it has no 'from' - // attribute (i.e., implicitly from the bare JID of the user's - // account) or it has a 'from' attribute whose value matches the - // user's bare JID . - headless_log.warn(`Ignoring roster illegitimate roster push message from ${iq.getAttribute('from')}`); - return; - } - - api.send(contacts_$iq({ - type: 'result', - id, - from: shared_converse.connection.jid - })); - const query = contacts_sizzle(`query[xmlns="${contacts_Strophe.NS.ROSTER}"]`, iq).pop(); - this.data.save('version', query.getAttribute('ver')); - const items = contacts_sizzle(`item`, query); - - if (items.length > 1) { - headless_log.error(iq); - throw new Error('Roster push query may not contain more than one "item" element.'); - } - - if (items.length === 0) { - headless_log.warn(iq); - headless_log.warn('Received a roster push stanza without an "item" element.'); - return; - } - - this.updateContact(items.pop()); - /** - * When the roster receives a push event from server (i.e. new entry in your contacts roster). - * @event _converse#rosterPush - * @type { XMLElement } - * @example _converse.api.listen.on('rosterPush', iq => { ... }); - */ - - api.trigger('rosterPush', iq); - return; - }, - - rosterVersioningSupported() { - return api.disco.stream.getFeature('ver', 'urn:xmpp:features:rosterver') && this.data.get('version'); - }, - - /** - * Fetch the roster from the XMPP server - * @private - * @emits _converse#roster - * @returns {promise} - */ - async fetchFromServer() { - const stanza = contacts_$iq({ - 'type': 'get', - 'id': contacts_u.getUniqueId('roster') - }).c('query', { - xmlns: contacts_Strophe.NS.ROSTER - }); - - if (this.rosterVersioningSupported()) { - stanza.attrs({ - 'ver': this.data.get('version') - }); - } - - const iq = await api.sendIQ(stanza, null, false); - - if (iq.getAttribute('type') !== 'error') { - const query = contacts_sizzle(`query[xmlns="${contacts_Strophe.NS.ROSTER}"]`, iq).pop(); - - if (query) { - const items = contacts_sizzle(`item`, query); - items.forEach(item => this.updateContact(item)); - this.data.save('version', query.getAttribute('ver')); - } - } else if (!contacts_u.isServiceUnavailableError(iq)) { - // Some unknown error happened, so we will try to fetch again if the page reloads. - headless_log.error(iq); - headless_log.error("Error while trying to fetch roster from the server"); - return; - } - - shared_converse.session.save('roster_cached', true); - /** - * When the roster has been received from the XMPP server. - * See also the `cachedRoster` event further up, which gets called instead of - * `roster` if its already in `sessionStorage`. - * @event _converse#roster - * @type { XMLElement } - * @example _converse.api.listen.on('roster', iq => { ... }); - * @example _converse.api.waitUntil('roster').then(iq => { ... }); - */ - - - api.trigger('roster', iq); - }, - - /* Update or create RosterContact models based on the given `item` XML - * node received in the resulting IQ stanza from the server. - * @private - * @param { XMLElement } item - */ - updateContact(item) { - const jid = item.getAttribute('jid'); - const contact = this.get(jid); - const subscription = item.getAttribute("subscription"); - const ask = item.getAttribute("ask"); - const groups = [...new Set(contacts_sizzle('group', item).map(e => e.textContent))]; - - if (!contact) { - if (subscription === "none" && ask === null || subscription === "remove") { - return; // We're lazy when adding contacts. - } - - this.create({ - 'ask': ask, - 'nickname': item.getAttribute("name"), - 'groups': groups, - 'jid': jid, - 'subscription': subscription - }, { - sort: false - }); - } else { - if (subscription === "remove") { - return contact.destroy(); - } // We only find out about requesting contacts via the - // presence handler, so if we receive a contact - // here, we know they aren't requesting anymore. - // see docs/DEVELOPER.rst - - - contact.save({ - 'subscription': subscription, - 'ask': ask, - 'nickname': item.getAttribute("name"), - 'requesting': null, - 'groups': groups - }); - } - }, - - createRequestingContact(presence) { - var _sizzle$pop2; - - const bare_jid = contacts_Strophe.getBareJidFromJid(presence.getAttribute('from')); - const nickname = ((_sizzle$pop2 = contacts_sizzle(`nick[xmlns="${contacts_Strophe.NS.NICK}"]`, presence).pop()) === null || _sizzle$pop2 === void 0 ? void 0 : _sizzle$pop2.textContent) || null; - const user_data = { - 'jid': bare_jid, - 'subscription': 'none', - 'ask': null, - 'requesting': true, - 'nickname': nickname - }; - /** - * Triggered when someone has requested to subscribe to your presence (i.e. to be your contact). - * @event _converse#contactRequest - * @type { _converse.RosterContact } - * @example _converse.api.listen.on('contactRequest', contact => { ... }); - */ - - api.trigger('contactRequest', this.create(user_data)); - }, - - handleIncomingSubscription(presence) { - const jid = presence.getAttribute('from'), - bare_jid = contacts_Strophe.getBareJidFromJid(jid), - contact = this.get(bare_jid); - - if (!api.settings.get('allow_contact_requests')) { - rejectPresenceSubscription(jid, __("This client does not allow presence subscriptions")); - } - - if (api.settings.get('auto_subscribe')) { - if (!contact || contact.get('subscription') !== 'to') { - this.subscribeBack(bare_jid, presence); - } else { - contact.authorize(); - } - } else { - if (contact) { - if (contact.get('subscription') !== 'none') { - contact.authorize(); - } else if (contact.get('ask') === "subscribe") { - contact.authorize(); - } - } else { - this.createRequestingContact(presence); - } - } - }, - - handleOwnPresence(presence) { - const jid = presence.getAttribute('from'), - resource = contacts_Strophe.getResourceFromJid(jid), - presence_type = presence.getAttribute('type'); - - if (shared_converse.connection.jid !== jid && presence_type !== 'unavailable' && (api.settings.get('synchronize_availability') === true || api.settings.get('synchronize_availability') === resource)) { - var _presence$querySelect, _presence$querySelect2; - - // Another resource has changed its status and - // synchronize_availability option set to update, - // we'll update ours as well. - const show = ((_presence$querySelect = presence.querySelector('show')) === null || _presence$querySelect === void 0 ? void 0 : _presence$querySelect.textContent) || 'online'; - - shared_converse.xmppstatus.save({ - 'status': show - }, { - 'silent': true - }); - - const status_message = (_presence$querySelect2 = presence.querySelector('status')) === null || _presence$querySelect2 === void 0 ? void 0 : _presence$querySelect2.textContent; - - if (status_message) { - shared_converse.xmppstatus.save({ - 'status_message': status_message - }); - } - } - - if (shared_converse.jid === jid && presence_type === 'unavailable') { - // XXX: We've received an "unavailable" presence from our - // own resource. Apparently this happens due to a - // Prosody bug, whereby we send an IQ stanza to remove - // a roster contact, and Prosody then sends - // "unavailable" globally, instead of directed to the - // particular user that's removed. - // - // Here is the bug report: https://prosody.im/issues/1121 - // - // I'm not sure whether this might legitimately happen - // in other cases. - // - // As a workaround for now we simply send our presence again, - // otherwise we're treated as offline. - api.user.presence.send(); - } - }, - - presenceHandler(presence) { - var _presence$querySelect3; - - const presence_type = presence.getAttribute('type'); - - if (presence_type === 'error') { - return true; - } - - const jid = presence.getAttribute('from'), - bare_jid = contacts_Strophe.getBareJidFromJid(jid); - - if (this.isSelf(bare_jid)) { - return this.handleOwnPresence(presence); - } else if (contacts_sizzle(`query[xmlns="${contacts_Strophe.NS.MUC}"]`, presence).length) { - return; // Ignore MUC - } - - const status_message = (_presence$querySelect3 = presence.querySelector('status')) === null || _presence$querySelect3 === void 0 ? void 0 : _presence$querySelect3.textContent; - const contact = this.get(bare_jid); - - if (contact && status_message !== contact.get('status')) { - contact.save({ - 'status': status_message - }); - } - - if (presence_type === 'subscribed' && contact) { - contact.ackSubscribe(); - } else if (presence_type === 'unsubscribed' && contact) { - contact.ackUnsubscribe(); - } else if (presence_type === 'unsubscribe') { - return; - } else if (presence_type === 'subscribe') { - this.handleIncomingSubscription(presence); - } else if (presence_type === 'unavailable' && contact) { - const resource = contacts_Strophe.getResourceFromJid(jid); - contact.presence.removeResource(resource); - } else if (contact) { - // presence_type is undefined - contact.presence.addResource(presence); - } - } - -}); -/* harmony default export */ const contacts = (RosterContacts); -;// CONCATENATED MODULE: ./src/headless/plugins/roster/api.js - -const { - Strophe: roster_api_Strophe -} = core_converse.env; -/* harmony default export */ const roster_api = ({ - /** - * @namespace _converse.api.contacts - * @memberOf _converse.api - */ - contacts: { - /** - * This method is used to retrieve roster contacts. - * - * @method _converse.api.contacts.get - * @params {(string[]|string)} jid|jids The JID or JIDs of - * the contacts to be returned. - * @returns {promise} Promise which resolves with the - * _converse.RosterContact (or an array of them) representing the contact. - * - * @example - * // Fetch a single contact - * _converse.api.listen.on('rosterContactsFetched', function () { - * const contact = await _converse.api.contacts.get('buddy@example.com') - * // ... - * }); - * - * @example - * // To get multiple contacts, pass in an array of JIDs: - * _converse.api.listen.on('rosterContactsFetched', function () { - * const contacts = await _converse.api.contacts.get( - * ['buddy1@example.com', 'buddy2@example.com'] - * ) - * // ... - * }); - * - * @example - * // To return all contacts, simply call ``get`` without any parameters: - * _converse.api.listen.on('rosterContactsFetched', function () { - * const contacts = await _converse.api.contacts.get(); - * // ... - * }); - */ - async get(jids) { - await api.waitUntil('rosterContactsFetched'); - - const _getter = jid => shared_converse.roster.get(roster_api_Strophe.getBareJidFromJid(jid)); - - if (jids === undefined) { - jids = shared_converse.roster.pluck('jid'); - } else if (typeof jids === 'string') { - return _getter(jids); - } - - return jids.map(_getter); - }, - - /** - * Add a contact. - * - * @method _converse.api.contacts.add - * @param {string} jid The JID of the contact to be added - * @param {string} [name] A custom name to show the user by in the roster - * @example - * _converse.api.contacts.add('buddy@example.com') - * @example - * _converse.api.contacts.add('buddy@example.com', 'Buddy') - */ - async add(jid, name) { - await api.waitUntil('rosterContactsFetched'); - - if (typeof jid !== 'string' || !jid.includes('@')) { - throw new TypeError('contacts.add: invalid jid'); - } - - return shared_converse.roster.addAndSubscribe(jid, name); - } - - } -}); -;// CONCATENATED MODULE: ./src/headless/plugins/roster/presence.js - - - - - -const { - Strophe: presence_Strophe, - dayjs: presence_dayjs, - sizzle: presence_sizzle -} = core_converse.env; -const Resource = Model.extend({ - 'idAttribute': 'name' -}); -const Resources = Collection.extend({ - 'model': Resource -}); -const Presence = Model.extend({ - defaults: { - 'show': 'offline' - }, - - initialize() { - this.resources = new Resources(); - const id = `converse.identities-${this.get('jid')}`; - initStorage(this.resources, id, 'session'); - this.listenTo(this.resources, 'update', this.onResourcesChanged); - this.listenTo(this.resources, 'change', this.onResourcesChanged); - }, - - onResourcesChanged() { - var _hpr$attributes; - - const hpr = this.getHighestPriorityResource(); - const show = (hpr === null || hpr === void 0 ? void 0 : (_hpr$attributes = hpr.attributes) === null || _hpr$attributes === void 0 ? void 0 : _hpr$attributes.show) || 'offline'; - - if (this.get('show') !== show) { - this.save({ - 'show': show - }); - } - }, - - /** - * Return the resource with the highest priority. - * If multiple resources have the same priority, take the latest one. - * @private - */ - getHighestPriorityResource() { - return this.resources.sortBy(r => `${r.get('priority')}-${r.get('timestamp')}`).reverse()[0]; - }, - - /** - * Adds a new resource and it's associated attributes as taken - * from the passed in presence stanza. - * Also updates the presence if the resource has higher priority (and is newer). - * @private - * @param { XMLElement } presence: The presence stanza - */ - addResource(presence) { - var _presence$querySelect, _presence$querySelect2; - - const jid = presence.getAttribute('from'), - name = presence_Strophe.getResourceFromJid(jid), - delay = presence_sizzle(`delay[xmlns="${presence_Strophe.NS.DELAY}"]`, presence).pop(), - priority = ((_presence$querySelect = presence.querySelector('priority')) === null || _presence$querySelect === void 0 ? void 0 : _presence$querySelect.textContent) ?? 0, - resource = this.resources.get(name), - settings = { - 'name': name, - 'priority': lodash_es_isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10), - 'show': ((_presence$querySelect2 = presence.querySelector('show')) === null || _presence$querySelect2 === void 0 ? void 0 : _presence$querySelect2.textContent) ?? 'online', - 'timestamp': delay ? presence_dayjs(delay.getAttribute('stamp')).toISOString() : new Date().toISOString() - }; - - if (resource) { - resource.save(settings); - } else { - this.resources.create(settings); - } - }, - - /** - * Remove the passed in resource from the resources map. - * Also redetermines the presence given that there's one less - * resource. - * @private - * @param { string } name: The resource name - */ - removeResource(name) { - const resource = this.resources.get(name); - - if (resource) { - resource.destroy(); - } - } - -}); -const Presences = Collection.extend({ - 'model': Presence -}); -;// CONCATENATED MODULE: ./src/headless/plugins/roster/index.js -/** - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - - -core_converse.plugins.add('converse-roster', { - dependencies: ['converse-status'], - - initialize() { - api.settings.extend({ - 'allow_contact_requests': true, - 'auto_subscribe': false, - 'synchronize_availability': true - }); - api.promises.add(['cachedRoster', 'roster', 'rosterContactsFetched', 'rosterInitialized']); // API methods only available to plugins - - Object.assign(shared_converse.api, roster_api); - shared_converse.HEADER_CURRENT_CONTACTS = __('My contacts'); - shared_converse.HEADER_PENDING_CONTACTS = __('Pending contacts'); - shared_converse.HEADER_REQUESTING_CONTACTS = __('Contact requests'); - shared_converse.HEADER_UNGROUPED = __('Ungrouped'); - shared_converse.HEADER_UNREAD = __('New messages'); - shared_converse.Presence = Presence; - shared_converse.Presences = Presences; - shared_converse.RosterContact = contact; - shared_converse.RosterContacts = contacts; - api.listen.on('beforeTearDown', () => unregisterPresenceHandler()); - api.listen.on('chatBoxesInitialized', onChatBoxesInitialized); - api.listen.on('clearSession', utils_onClearSession); - api.listen.on('presencesInitialized', onPresencesInitialized); - api.listen.on('statusInitialized', roster_utils_onStatusInitialized); - api.listen.on('streamResumptionFailed', () => shared_converse.session.set('roster_cached', false)); - api.waitUntil('rosterContactsFetched').then(onRosterContactsFetched); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/smacks/utils.js - - - -const { - Strophe: smacks_utils_Strophe -} = core_converse.env; -const smacks_utils_u = core_converse.env.utils; - -function isStreamManagementSupported() { - if (api.connection.isType('bosh') && !shared_converse.isTestEnv()) { - return false; - } - - return api.disco.stream.getFeature('sm', smacks_utils_Strophe.NS.SM); -} - -function handleAck(el) { - if (!shared_converse.session.get('smacks_enabled')) { - return true; - } - - const handled = parseInt(el.getAttribute('h'), 10); - - const last_known_handled = shared_converse.session.get('num_stanzas_handled_by_server'); - - const delta = handled - last_known_handled; - - if (delta < 0) { - const err_msg = `New reported stanza count lower than previous. ` + `New: ${handled} - Previous: ${last_known_handled}`; - headless_log.error(err_msg); - } - - const unacked_stanzas = shared_converse.session.get('unacked_stanzas'); - - if (delta > unacked_stanzas.length) { - const err_msg = `Higher reported acknowledge count than unacknowledged stanzas. ` + `Reported Acknowledged Count: ${delta} -` + `Unacknowledged Stanza Count: ${unacked_stanzas.length} -` + `New: ${handled} - Previous: ${last_known_handled}`; - headless_log.error(err_msg); - } - - shared_converse.session.save({ - 'num_stanzas_handled_by_server': handled, - 'num_stanzas_since_last_ack': 0, - 'unacked_stanzas': unacked_stanzas.slice(delta) - }); - - return true; -} - -function sendAck() { - if (shared_converse.session.get('smacks_enabled')) { - const h = shared_converse.session.get('num_stanzas_handled'); - - const stanza = smacks_utils_u.toStanza(``); - api.send(stanza); - } - - return true; -} - -function stanzaHandler(el) { - if (shared_converse.session.get('smacks_enabled')) { - if (smacks_utils_u.isTagEqual(el, 'iq') || smacks_utils_u.isTagEqual(el, 'presence') || smacks_utils_u.isTagEqual(el, 'message')) { - const h = shared_converse.session.get('num_stanzas_handled'); - - shared_converse.session.save('num_stanzas_handled', h + 1); - } - } - - return true; -} - -function initSessionData() { - shared_converse.session.save({ - 'smacks_enabled': shared_converse.session.get('smacks_enabled') || false, - 'num_stanzas_handled': shared_converse.session.get('num_stanzas_handled') || 0, - 'num_stanzas_handled_by_server': shared_converse.session.get('num_stanzas_handled_by_server') || 0, - 'num_stanzas_since_last_ack': shared_converse.session.get('num_stanzas_since_last_ack') || 0, - 'unacked_stanzas': shared_converse.session.get('unacked_stanzas') || [] - }); -} - -function resetSessionData() { - var _converse$session; - - (_converse$session = shared_converse.session) === null || _converse$session === void 0 ? void 0 : _converse$session.save({ - 'smacks_enabled': false, - 'num_stanzas_handled': 0, - 'num_stanzas_handled_by_server': 0, - 'num_stanzas_since_last_ack': 0, - 'unacked_stanzas': [] - }); -} - -function saveSessionData(el) { - const data = { - 'smacks_enabled': true - }; - - if (['1', 'true'].includes(el.getAttribute('resume'))) { - data['smacks_stream_id'] = el.getAttribute('id'); - } - - shared_converse.session.save(data); - - return true; -} - -function onFailedStanza(el) { - if (el.querySelector('item-not-found')) { - // Stream resumption must happen before resource binding but - // enabling a new stream must happen after resource binding. - // Since resumption failed, we simply continue. - // - // After resource binding, sendEnableStanza will be called - // based on the afterResourceBinding event. - headless_log.warn('Could not resume previous SMACKS session, session id not found. ' + 'A new session will be established.'); - } else { - headless_log.error('Failed to enable stream management'); - headless_log.error(el.outerHTML); - } - - resetSessionData(); - /** - * Triggered when the XEP-0198 stream could not be resumed. - * @event _converse#streamResumptionFailed - */ - - api.trigger('streamResumptionFailed'); - return true; -} - -function resendUnackedStanzas() { - const stanzas = shared_converse.session.get('unacked_stanzas'); // We clear the unacked_stanzas array because it'll get populated - // again in `onStanzaSent` - - - shared_converse.session.save('unacked_stanzas', []); // XXX: Currently we're resending *all* unacked stanzas, including - // IQ[type="get"] stanzas that longer have handlers (because the - // page reloaded or we reconnected, causing removal of handlers). - // - // *Side-note:* Is it necessary to clear handlers upon reconnection? - // - // I've considered not resending those stanzas, but then keeping - // track of what's been sent and ack'd and their order gets - // prohibitively complex. - // - // It's unclear how much of a problem this poses. - // - // Two possible solutions are running @converse/headless as a - // service worker or handling IQ[type="result"] stanzas - // differently, more like push stanzas, so that they don't need - // explicit handlers. - - - stanzas.forEach(s => api.send(s)); -} - -function onResumedStanza(el) { - saveSessionData(el); - handleAck(el); - resendUnackedStanzas(); - shared_converse.connection.do_bind = false; // No need to bind our resource anymore - - shared_converse.connection.authenticated = true; - shared_converse.connection.restored = true; - - shared_converse.connection._changeConnectStatus(smacks_utils_Strophe.Status.CONNECTED, null); -} - -async function sendResumeStanza() { - const promise = getOpenPromise(); - - shared_converse.connection._addSysHandler(el => promise.resolve(onResumedStanza(el)), smacks_utils_Strophe.NS.SM, 'resumed'); - - shared_converse.connection._addSysHandler(el => promise.resolve(onFailedStanza(el)), smacks_utils_Strophe.NS.SM, 'failed'); - - const previous_id = shared_converse.session.get('smacks_stream_id'); - - const h = shared_converse.session.get('num_stanzas_handled'); - - const stanza = smacks_utils_u.toStanza(``); - api.send(stanza); - - shared_converse.connection.flush(); - - await promise; -} - -async function sendEnableStanza() { - if (!api.settings.get('enable_smacks') || shared_converse.session.get('smacks_enabled')) { - return; - } - - if (await isStreamManagementSupported()) { - const promise = getOpenPromise(); - - shared_converse.connection._addSysHandler(el => promise.resolve(saveSessionData(el)), smacks_utils_Strophe.NS.SM, 'enabled'); - - shared_converse.connection._addSysHandler(el => promise.resolve(onFailedStanza(el)), smacks_utils_Strophe.NS.SM, 'failed'); - - const resume = api.connection.isType('websocket') || shared_converse.isTestEnv(); - - const stanza = smacks_utils_u.toStanza(``); - api.send(stanza); - - shared_converse.connection.flush(); - - await promise; - } -} -const smacks_handlers = []; -async function enableStreamManagement() { - var _converse$session2; - - if (!api.settings.get('enable_smacks')) { - return; - } - - if (!(await isStreamManagementSupported())) { - return; - } - - const conn = shared_converse.connection; - - while (smacks_handlers.length) { - conn.deleteHandler(smacks_handlers.pop()); - } - - smacks_handlers.push(conn.addHandler(stanzaHandler)); - smacks_handlers.push(conn.addHandler(sendAck, smacks_utils_Strophe.NS.SM, 'r')); - smacks_handlers.push(conn.addHandler(handleAck, smacks_utils_Strophe.NS.SM, 'a')); - - if ((_converse$session2 = shared_converse.session) !== null && _converse$session2 !== void 0 && _converse$session2.get('smacks_stream_id')) { - await sendResumeStanza(); - } else { - resetSessionData(); - } -} -function onStanzaSent(stanza) { - if (!shared_converse.session) { - headless_log.warn('No _converse.session!'); - return; - } - - if (!shared_converse.session.get('smacks_enabled')) { - return; - } - - if (smacks_utils_u.isTagEqual(stanza, 'iq') || smacks_utils_u.isTagEqual(stanza, 'presence') || smacks_utils_u.isTagEqual(stanza, 'message')) { - const stanza_string = smacks_utils_Strophe.serialize(stanza); - - shared_converse.session.save('unacked_stanzas', (shared_converse.session.get('unacked_stanzas') || []).concat([stanza_string])); - - const max_unacked = api.settings.get('smacks_max_unacked_stanzas'); - - if (max_unacked > 0) { - const num = shared_converse.session.get('num_stanzas_since_last_ack') + 1; - - if (num % max_unacked === 0) { - // Request confirmation of sent stanzas - api.send(smacks_utils_u.toStanza(``)); - } - - shared_converse.session.save({ - 'num_stanzas_since_last_ack': num - }); - } - } -} -;// CONCATENATED MODULE: ./src/headless/plugins/smacks/index.js -/** - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description Converse.js plugin which adds support for XEP-0198: Stream Management - */ - - -const { - Strophe: smacks_Strophe -} = core_converse.env; -smacks_Strophe.addNamespace('SM', 'urn:xmpp:sm:3'); -core_converse.plugins.add('converse-smacks', { - initialize() { - // Configuration values for this plugin - // ==================================== - // Refer to docs/source/configuration.rst for explanations of these - // configuration settings. - api.settings.extend({ - 'enable_smacks': true, - 'smacks_max_unacked_stanzas': 5 - }); - api.listen.on('afterResourceBinding', sendEnableStanza); - api.listen.on('beforeResourceBinding', enableStreamManagement); - api.listen.on('send', onStanzaSent); - api.listen.on('userSessionInitialized', initSessionData); - } - -}); -;// CONCATENATED MODULE: ./src/headless/plugins/vcard.js -/** - * @module converse-vcard - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - -const { - Strophe: vcard_Strophe, - $iq: vcard_$iq, - dayjs: vcard_dayjs -} = core_converse.env; -const vcard_u = core_converse.env.utils; -core_converse.plugins.add('converse-vcard', { - dependencies: ["converse-status", "converse-roster"], - overrides: { - XMPPStatus: { - getNickname() { - const { - _converse - } = this.__super__; - - const nick = this.__super__.getNickname.apply(this); - - if (!nick && _converse.xmppstatus.vcard) { - return _converse.xmppstatus.vcard.get('nickname'); - } else { - return nick; - } - }, - - getFullname() { - const { - _converse - } = this.__super__; - - const fullname = this.__super__.getFullname.apply(this); - - if (!fullname && _converse.xmppstatus.vcard) { - return _converse.xmppstatus.vcard.get('fullname'); - } else { - return fullname; - } - } - - }, - RosterContact: { - getDisplayName() { - if (!this.get('nickname') && this.vcard) { - return this.vcard.getDisplayName(); - } else { - return this.__super__.getDisplayName.apply(this); - } - }, - - getFullname() { - if (this.vcard) { - return this.vcard.get('fullname'); - } else { - return this.__super__.getFullname.apply(this); - } - } - - } - }, - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - api.promises.add('VCardsInitialized'); - /** - * Represents a VCard - * @class - * @namespace _converse.VCard - * @memberOf _converse - */ - - shared_converse.VCard = Model.extend({ - defaults: { - 'image': shared_converse.DEFAULT_IMAGE, - 'image_type': shared_converse.DEFAULT_IMAGE_TYPE - }, - - set(key, val, options) { - // Override Model.prototype.set to make sure that the - // default `image` and `image_type` values are maintained. - let attrs; - - if (typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - if ('image' in attrs && !attrs['image']) { - attrs['image'] = shared_converse.DEFAULT_IMAGE; - attrs['image_type'] = shared_converse.DEFAULT_IMAGE_TYPE; - return Model.prototype.set.call(this, attrs, options); - } else { - return Model.prototype.set.apply(this, arguments); - } - }, - - getDisplayName() { - return this.get('nickname') || this.get('fullname') || this.get('jid'); - } - - }); - shared_converse.VCards = Collection.extend({ - model: shared_converse.VCard, - - initialize() { - this.on('add', vcard => vcard.get('jid') && api.vcard.update(vcard)); - } - - }); - - async function onVCardData(jid, iq) { - const vcard = iq.querySelector('vCard'); - let result = {}; - - if (vcard !== null) { - var _vcard$querySelector, _vcard$querySelector2, _vcard$querySelector3, _vcard$querySelector4, _vcard$querySelector5, _vcard$querySelector6, _vcard$querySelector7; - - result = { - 'stanza': iq, - 'fullname': (_vcard$querySelector = vcard.querySelector('FN')) === null || _vcard$querySelector === void 0 ? void 0 : _vcard$querySelector.textContent, - 'nickname': (_vcard$querySelector2 = vcard.querySelector('NICKNAME')) === null || _vcard$querySelector2 === void 0 ? void 0 : _vcard$querySelector2.textContent, - 'image': (_vcard$querySelector3 = vcard.querySelector('PHOTO BINVAL')) === null || _vcard$querySelector3 === void 0 ? void 0 : _vcard$querySelector3.textContent, - 'image_type': (_vcard$querySelector4 = vcard.querySelector('PHOTO TYPE')) === null || _vcard$querySelector4 === void 0 ? void 0 : _vcard$querySelector4.textContent, - 'url': (_vcard$querySelector5 = vcard.querySelector('URL')) === null || _vcard$querySelector5 === void 0 ? void 0 : _vcard$querySelector5.textContent, - 'role': (_vcard$querySelector6 = vcard.querySelector('ROLE')) === null || _vcard$querySelector6 === void 0 ? void 0 : _vcard$querySelector6.textContent, - 'email': (_vcard$querySelector7 = vcard.querySelector('EMAIL USERID')) === null || _vcard$querySelector7 === void 0 ? void 0 : _vcard$querySelector7.textContent, - 'vcard_updated': new Date().toISOString(), - 'vcard_error': undefined - }; - } - - if (result.image) { - const buffer = vcard_u.base64ToArrayBuffer(result['image']); - const ab = await crypto.subtle.digest('SHA-1', buffer); - result['image_hash'] = vcard_u.arrayBufferToHex(ab); - } - - return result; - } - - function createStanza(type, jid, vcard_el) { - const iq = vcard_$iq(jid ? { - 'type': type, - 'to': jid - } : { - 'type': type - }); - - if (!vcard_el) { - iq.c("vCard", { - 'xmlns': vcard_Strophe.NS.VCARD - }); - } else { - iq.cnode(vcard_el); - } - - return iq; - } - - async function getVCard(_converse, jid) { - const to = vcard_Strophe.getBareJidFromJid(jid) === _converse.bare_jid ? null : jid; - let iq; - - try { - iq = await api.sendIQ(createStanza("get", to)); - } catch (iq) { - return { - 'stanza': iq, - 'jid': jid, - 'vcard_error': new Date().toISOString() - }; - } - - return onVCardData(jid, iq); - } - - async function setVCardOnModel(model) { - let jid; - - if (model instanceof shared_converse.Message) { - if (model.get('type') === 'error') { - return; - } - - jid = model.get('from'); - } else { - jid = model.get('jid'); - } - - await api.waitUntil('VCardsInitialized'); - model.vcard = shared_converse.vcards.findWhere({ - 'jid': jid - }); - - if (!model.vcard) { - model.vcard = shared_converse.vcards.create({ - 'jid': jid - }); - } - - model.vcard.on('change', () => model.trigger('vcard:change')); - } - - function getVCardForChatroomOccupant(message) { - var _message$collection; - - const chatbox = message === null || message === void 0 ? void 0 : (_message$collection = message.collection) === null || _message$collection === void 0 ? void 0 : _message$collection.chatbox; - const nick = vcard_Strophe.getResourceFromJid(message.get('from')); - - if (chatbox && chatbox.get('nick') === nick) { - return shared_converse.xmppstatus.vcard; - } else { - const jid = message.occupant && message.occupant.get('jid') || message.get('from'); - - if (jid) { - return shared_converse.vcards.findWhere({ - jid - }) || shared_converse.vcards.create({ - jid - }); - } else { - headless_log.error(`Could not assign VCard for message because no JID found! msgid: ${message.get('msgid')}`); - return; - } - } - } - - async function setVCardOnMUCMessage(message) { - await api.waitUntil('VCardsInitialized'); - - if (['error', 'info'].includes(message.get('type'))) { - return; - } else { - message.vcard = getVCardForChatroomOccupant(message); - } - } - - shared_converse.initVCardCollection = async function () { - shared_converse.vcards = new shared_converse.VCards(); - const id = `${shared_converse.bare_jid}-converse.vcards`; - initStorage(shared_converse.vcards, id); - await new Promise(resolve => { - shared_converse.vcards.fetch({ - 'success': resolve, - 'error': resolve - }, { - 'silent': true - }); - }); - const vcards = shared_converse.vcards; - - if (shared_converse.session) { - const jid = shared_converse.session.get('bare_jid'); - - shared_converse.xmppstatus.vcard = vcards.findWhere({ - 'jid': jid - }) || vcards.create({ - 'jid': jid - }); - } - /** - * Triggered as soon as the `_converse.vcards` collection has been initialized and populated from cache. - * @event _converse#VCardsInitialized - */ - - - api.trigger('VCardsInitialized'); - }; - - function clearVCardsSession() { - if (shared_converse.shouldClearCache()) { - api.promises.add('VCardsInitialized'); - - if (shared_converse.vcards) { - shared_converse.vcards.clearStore(); - - delete shared_converse.vcards; - } - } - } - /************************ BEGIN Event Handlers ************************/ - - - api.listen.on('chatBoxInitialized', m => setVCardOnModel(m)); - api.listen.on('chatRoomInitialized', m => setVCardOnModel(m)); - api.listen.on('chatRoomMessageInitialized', m => setVCardOnMUCMessage(m)); - api.listen.on('addClientFeatures', () => api.disco.own.features.add(vcard_Strophe.NS.VCARD)); - api.listen.on('clearSession', () => clearVCardsSession()); - api.listen.on('messageInitialized', m => setVCardOnModel(m)); - api.listen.on('rosterContactInitialized', m => setVCardOnModel(m)); - api.listen.on('statusInitialized', shared_converse.initVCardCollection); - /************************ BEGIN API ************************/ - - Object.assign(shared_converse.api, { - /** - * The XEP-0054 VCard API - * - * This API lets you access and update user VCards - * - * @namespace _converse.api.vcard - * @memberOf _converse.api - */ - 'vcard': { - /** - * Enables setting new values for a VCard. - * - * Sends out an IQ stanza to set the user's VCard and if - * successful, it updates the {@link _converse.VCard} - * for the passed in JID. - * - * @method _converse.api.vcard.set - * @param {string} jid The JID for which the VCard should be set - * @param {object} data A map of VCard keys and values - * @example - * _converse.api.vcard.set({ - * 'jid': _converse.bare_jid, - * 'fn': 'John Doe', - * 'nickname': 'jdoe' - * }).then(() => { - * // Succes - * }).catch(() => { - * // Failure - * }). - */ - async set(jid, data) { - if (!jid) { - throw Error("No jid provided for the VCard data"); - } - - const div = document.createElement('div'); - const vcard_el = vcard_u.toStanza(` - - ${data.fn} - ${data.nickname} - ${data.url} - ${data.role} - ${data.email} - - ${data.image_type} - ${data.image} - - `, div); - let result; - - try { - result = await api.sendIQ(createStanza("set", jid, vcard_el)); - } catch (e) { - throw e; - } - - await api.vcard.update(jid, true); - return result; - }, - - /** - * @method _converse.api.vcard.get - * @param {Model|string} model Either a `Model` instance, or a string JID. - * If a `Model` instance is passed in, then it must have either a `jid` - * attribute or a `muc_jid` attribute. - * @param {boolean} [force] A boolean indicating whether the vcard should be - * fetched even if it's been fetched before. - * @returns {promise} A Promise which resolves with the VCard data for a particular JID or for - * a `Model` instance which represents an entity with a JID (such as a roster contact, - * chat or chatroom occupant). - * - * @example - * _converse.api.waitUntil('rosterContactsFetched').then(() => { - * _converse.api.vcard.get('someone@example.org').then( - * (vcard) => { - * // Do something with the vcard... - * } - * ); - * }); - */ - get(model, force) { - if (typeof model === 'string') { - return getVCard(shared_converse, model); - } else if (force || !model.get('vcard_updated') || !vcard_dayjs(model.get('vcard_error')).isSame(new Date(), "day")) { - const jid = model.get('jid'); - - if (!jid) { - headless_log.error("No JID to get vcard for"); - } - - return getVCard(shared_converse, jid); - } else { - return Promise.resolve({}); - } - }, - - /** - * Fetches the VCard associated with a particular `Model` instance - * (by using its `jid` or `muc_jid` attribute) and then updates the model with the - * returned VCard data. - * - * @method _converse.api.vcard.update - * @param {Model} model A `Model` instance - * @param {boolean} [force] A boolean indicating whether the vcard should be - * fetched again even if it's been fetched before. - * @returns {promise} A promise which resolves once the update has completed. - * @example - * _converse.api.waitUntil('rosterContactsFetched').then(async () => { - * const chatbox = await _converse.chatboxes.getChatBox('someone@example.org'); - * _converse.api.vcard.update(chatbox); - * }); - */ - async update(model, force) { - const data = await this.get(model, force); - model = typeof model === 'string' ? shared_converse.vcards.findWhere({ - 'jid': model - }) : model; - - if (!model) { - headless_log.error(`Could not find a VCard model for ${model}`); - return; - } - - delete data['stanza']; - model.save(data); - } - - } - }); - } - -}); -;// CONCATENATED MODULE: ./src/headless/headless.js -/* START: Removable components - * -------------------- - * Any of the following components may be removed if they're not needed. - */ - // XEP-0050 Ad Hoc Commands - - // XEP-0199 XMPP Ping - - // XEP-0206 BOSH - - // XEP-0115 Entity Capabilities - - // XEP-0280 Message Carbons - - // RFC-6121 Instant messaging - - - // XEP-0030 Service discovery - - // Support for headline messages - - // XEP-0313 Message Archive Management - - // XEP-0045 Multi-user chat - - // XEP-0199 XMPP Ping - - // XEP-0060 Pubsub - - // RFC-6121 Contacts Roster - - // XEP-0198 Stream Management - - - // XEP-0054 VCard-temp - -/* END: Removable components */ - - -/* harmony default export */ const headless = ((/* unused pure expression or super */ null && (converse))); -;// CONCATENATED MODULE: ./src/shared/registry.js - -const registry = {}; - -function registry_define(name, constructor) { - this.registry[name] = constructor; -} - -function register() { - Object.keys(registry).forEach(name => { - if (!customElements.get(name)) { - customElements.define(name, registry[name]); - } - }); -} - -api.elements = { - registry, - define: registry_define, - register -}; -;// CONCATENATED MODULE: ./src/shared/components/element.js - - -class CustomElement extends lit_element_h { - constructor() { - super(); - Object.assign(this, Events); - } - - createRenderRoot() { - // Render without the shadow DOM - return this; - } - - disconnectedCallback() { - super.disconnectedCallback(); - this.stopListening(); - } - -} -;// CONCATENATED MODULE: ./src/shared/constants.js -// These are all the view-layer plugins. -// -// For the full Converse build, this list serves -// as a whitelist (see src/converse.js) in addition to the -// CORE_PLUGINS list in src/headless/consts.js. -const VIEW_PLUGINS = ['converse-bookmark-views', 'converse-chatboxviews', 'converse-chatview', 'converse-controlbox', 'converse-dragresize', 'converse-fullscreen', 'converse-headlines-view', 'converse-mam-views', 'converse-minimize', 'converse-modal', 'converse-muc-views', 'converse-notification', 'converse-omemo', 'converse-profile', 'converse-push', 'converse-register', 'converse-roomslist', 'converse-rootview', 'converse-rosterview', 'converse-singleton']; -// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js -var injectStylesIntoStyleTag = __webpack_require__(3379); -var injectStylesIntoStyleTag_default = /*#__PURE__*/__webpack_require__.n(injectStylesIntoStyleTag); -// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleDomAPI.js -var styleDomAPI = __webpack_require__(7795); -var styleDomAPI_default = /*#__PURE__*/__webpack_require__.n(styleDomAPI); -// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertBySelector.js -var insertBySelector = __webpack_require__(569); -var insertBySelector_default = /*#__PURE__*/__webpack_require__.n(insertBySelector); -// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js -var setAttributesWithoutAttributes = __webpack_require__(3565); -var setAttributesWithoutAttributes_default = /*#__PURE__*/__webpack_require__.n(setAttributesWithoutAttributes); -// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertStyleElement.js -var insertStyleElement = __webpack_require__(9216); -var insertStyleElement_default = /*#__PURE__*/__webpack_require__.n(insertStyleElement); -// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleTagTransform.js -var styleTagTransform = __webpack_require__(4589); -var styleTagTransform_default = /*#__PURE__*/__webpack_require__.n(styleTagTransform); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/shared/styles/index.scss -var styles = __webpack_require__(4452); -;// CONCATENATED MODULE: ./src/shared/styles/index.scss - - - - - - - - - - - -var options = {}; - -options.styleTagTransform = (styleTagTransform_default()); -options.setAttributes = (setAttributesWithoutAttributes_default()); - - options.insert = insertBySelector_default().bind(null, "head"); - -options.domAPI = (styleDomAPI_default()); -options.insertStyleElement = (insertStyleElement_default()); - -var update = injectStylesIntoStyleTag_default()(styles/* default */.Z, options); - - - - - /* harmony default export */ const shared_styles = (styles/* default */.Z && styles/* default.locals */.Z.locals ? styles/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/templates/form.js - - -/* harmony default export */ const templates_form = (o => { - const i18n_heading = __('Bookmark this groupchat'); - - const i18n_autojoin = __('Would you like this groupchat to be automatically joined upon startup?'); - - const i18n_cancel = __('Cancel'); - - const i18n_name = __('The name for this bookmark:'); - - const i18n_nick = __('What should your nickname for this groupchat be?'); - - const i18n_submit = __('Save'); - - return T` -
- ${i18n_heading} -
- - -
-
- - -
-
- - -
-
- - -
-
- `; -}); -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/form.js - - - - -class MUCBookmarkForm extends CustomElement { - static get properties() { - return { - 'jid': { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.jid); - } - - render() { - return templates_form(Object.assign(this.model.toJSON(), { - 'onCancel': ev => this.closeBookmarkForm(ev), - 'onSubmit': ev => this.onBookmarkFormSubmitted(ev) - })); - } - - onBookmarkFormSubmitted(ev) { - var _ev$target$querySelec, _ev$target$querySelec2, _ev$target$querySelec3; - - ev.preventDefault(); - - shared_converse.bookmarks.createBookmark({ - 'jid': this.model.get('jid'), - 'autojoin': ((_ev$target$querySelec = ev.target.querySelector('input[name="autojoin"]')) === null || _ev$target$querySelec === void 0 ? void 0 : _ev$target$querySelec.checked) || false, - 'name': (_ev$target$querySelec2 = ev.target.querySelector('input[name=name]')) === null || _ev$target$querySelec2 === void 0 ? void 0 : _ev$target$querySelec2.value, - 'nick': (_ev$target$querySelec3 = ev.target.querySelector('input[name=nick]')) === null || _ev$target$querySelec3 === void 0 ? void 0 : _ev$target$querySelec3.value - }); - - this.closeBookmarkForm(ev); - } - - closeBookmarkForm(ev) { - ev.preventDefault(); - this.model.session.save('view', null); - } - -} - -api.elements.define('converse-muc-bookmark-form', MUCBookmarkForm); -/* harmony default export */ const bookmark_views_form = (MUCBookmarkForm); -;// CONCATENATED MODULE: ./node_modules/lodash-es/invokeMap.js - - - - - -/** - * Invokes the method at `path` of each element in `collection`, returning - * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `path` is a function, it's invoked - * for, and `this` bound to, each element in `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array|Function|string} path The path of the method to invoke or - * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke each method with. - * @returns {Array} Returns the array of results. - * @example - * - * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invokeMap([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - -var invokeMap = _baseRest(function (collection, path, args) { - var index = -1, - isFunc = typeof path == 'function', - result = lodash_es_isArrayLike(collection) ? Array(collection.length) : []; - _baseEach(collection, function (value) { - result[++index] = isFunc ? _apply(path, value, args) : _baseInvoke(value, path, args); - }); - return result; -}); -/* harmony default export */ const lodash_es_invokeMap = (invokeMap); -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/utils.js - - - - - -function getHeadingButtons(view, buttons) { - if (shared_converse.allow_bookmarks && view.model.get('type') === shared_converse.CHATROOMS_TYPE) { - const bookmarked = view.model.get('bookmarked'); - const data = { - 'i18n_title': bookmarked ? __('Unbookmark this groupchat') : __('Bookmark this groupchat'), - 'i18n_text': bookmarked ? __('Unbookmark') : __('Bookmark'), - 'handler': ev => view.toggleBookmark(ev), - 'a_class': 'toggle-bookmark', - 'icon_class': 'fa-bookmark', - 'name': 'bookmark' - }; - const names = buttons.map(t => t.name); - const idx = names.indexOf('details'); - const data_promise = checkBookmarksSupport().then(s => s ? data : ''); - return idx > -1 ? [...buttons.slice(0, idx), data_promise, ...buttons.slice(idx)] : [data_promise, ...buttons]; - } - - return buttons; -} -function removeBookmarkViaEvent(ev) { - ev.preventDefault(); - const name = ev.target.getAttribute('data-bookmark-name'); - const jid = ev.target.getAttribute('data-room-jid'); - - if (confirm(__('Are you sure you want to remove the bookmark "%1$s"?', name))) { - lodash_es_invokeMap(shared_converse.bookmarks.where({ - jid - }), Model.prototype.destroy); - } -} -async function addBookmarkViaEvent(ev) { - ev.preventDefault(); - const jid = ev.target.getAttribute('data-room-jid'); - const room = await api.rooms.open(jid, { - 'bring_to_foreground': true - }); - room.session.save('view', core_converse.MUC.VIEWS.BOOKMARK); -} -function openRoomViaEvent(ev) { - ev.preventDefault(); - const { - Strophe - } = core_converse.env; - const name = ev.target.textContent; - const jid = ev.target.getAttribute('data-room-jid'); - const data = { - 'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)) || jid - }; - api.rooms.open(jid, data, true); -} -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/templates/item.js - - - - -/* harmony default export */ const item = (o => { - const jid = o.bm.get('jid'); - const is_hidden = !!(api.settings.get('hide_open_bookmarks') && shared_converse.chatboxes.get(jid)); - - const info_remove_bookmark = __('Unbookmark this groupchat'); - - const open_title = __('Click to open this groupchat'); - - return T` -
- `; -}); -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/templates/list.js - - - - -/* harmony default export */ const list = (o => { - const is_collapsed = shared_converse.bookmarks.getUnopenedBookmarks().length ? true : false; - - const desc_bookmarks = __('Click to toggle the bookmarks list'); - - const label_bookmarks = __('Bookmarks'); - - return T` -
- - - - ${label_bookmarks} -
- ${shared_converse.bookmarks.map(bm => item(Object.assign({ - bm - }, o)))} -
-
- `; -}); -;// CONCATENATED MODULE: ./node_modules/@converse/skeletor/src/element.js -function element_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - - - - - - - -const paddedLt = /^\s* this.render(), - 'error': (model, err) => { - headless_log.error(err); - this.render(); - } - }); - } - - render() { - V(list({ - 'toggleBookmarksList': ev => this.toggleBookmarksList(ev), - 'toggle_state': this.model.get('toggle-state') - }), this); - } - - toggleBookmarksList(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - const icon_el = ev.target.matches('.fa') ? ev.target : ev.target.querySelector('.fa'); - - if (bookmarks_list_u.hasClass('fa-caret-down', icon_el)) { - bookmarks_list_u.slideIn(this.querySelector('.bookmarks')); - this.model.save({ - 'toggle-state': shared_converse.CLOSED - }); - icon_el.classList.remove('fa-caret-down'); - icon_el.classList.add('fa-caret-right'); - } else { - icon_el.classList.remove('fa-caret-right'); - icon_el.classList.add('fa-caret-down'); - bookmarks_list_u.slideOut(this.querySelector('.bookmarks')); - this.model.save({ - 'toggle-state': shared_converse.OPENED - }); - } - } - -} -api.elements.define('converse-bookmarks', BookmarksView); -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/mixins.js - -const { - u: mixins_u -} = core_converse.env; -const bookmarkableChatRoomView = { - /** - * Set whether the groupchat is bookmarked or not. - * @private - */ - setBookmarkState() { - if (shared_converse.bookmarks !== undefined) { - const models = shared_converse.bookmarks.where({ - 'jid': this.model.get('jid') - }); - - if (!models.length) { - this.model.save('bookmarked', false); - } else { - this.model.save('bookmarked', true); - } - } - }, - - renderBookmarkForm() { - if (!this.bookmark_form) { - this.bookmark_form = new shared_converse.MUCBookmarkForm({ - 'model': this.model, - 'chatroomview': this - }); - const container_el = this.querySelector('.chatroom-body'); - container_el.insertAdjacentElement('beforeend', this.bookmark_form.el); - } - - mixins_u.showElement(this.bookmark_form.el); - }, - - toggleBookmark(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - - const models = shared_converse.bookmarks.where({ - 'jid': this.model.get('jid') - }); - - if (!models.length) { - this.model.session.set('view', core_converse.MUC.VIEWS.BOOKMARK); - } else { - models.forEach(model => model.destroy()); - } - } - -}; -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/bookmark-views/styles/bookmarks.scss -var bookmarks = __webpack_require__(3742); -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/styles/bookmarks.scss - - - - - - - - - - - -var bookmarks_options = {}; - -bookmarks_options.styleTagTransform = (styleTagTransform_default()); -bookmarks_options.setAttributes = (setAttributesWithoutAttributes_default()); - - bookmarks_options.insert = insertBySelector_default().bind(null, "head"); - -bookmarks_options.domAPI = (styleDomAPI_default()); -bookmarks_options.insertStyleElement = (insertStyleElement_default()); - -var bookmarks_update = injectStylesIntoStyleTag_default()(bookmarks/* default */.Z, bookmarks_options); - - - - - /* harmony default export */ const styles_bookmarks = (bookmarks/* default */.Z && bookmarks/* default.locals */.Z.locals ? bookmarks/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/bookmark-views/index.js -/** - * @description Converse.js plugin which adds views for XEP-0048 bookmarks - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - -core_converse.plugins.add('converse-bookmark-views', { - /* Plugin dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. - * - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. By default it's - * false, which means these plugins are only loaded opportunistically. - */ - dependencies: ['converse-chatboxes', 'converse-muc', 'converse-muc-views'], - - initialize() { - // Configuration values for this plugin - // ==================================== - // Refer to docs/source/configuration.rst for explanations of these - // configuration settings. - api.settings.extend({ - hide_open_bookmarks: true - }); - shared_converse.removeBookmarkViaEvent = removeBookmarkViaEvent; - shared_converse.addBookmarkViaEvent = addBookmarkViaEvent; - Object.assign(shared_converse.ChatRoomView.prototype, bookmarkableChatRoomView); - shared_converse.MUCBookmarkForm = bookmark_views_form; - shared_converse.BookmarksView = BookmarksView; - api.listen.on('getHeadingButtons', getHeadingButtons); - api.listen.on('chatRoomViewInitialized', view => view.setBookmarkState()); - } - -}); -;// CONCATENATED MODULE: ./src/templates/background_logo.js - - -/* harmony default export */ const background_logo = (() => T` -
-
-
- - Logo Converse - - - - - - - - - - - - - - - - - - - - - - - - - - - - converse.js - - -
- ${api.settings.get('view_mode') === 'overlayed' ? T`
` : ''} -
`); -;// CONCATENATED MODULE: ./node_modules/lit-html/directive.js -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const directive_t = { - ATTRIBUTE: 1, - CHILD: 2, - PROPERTY: 3, - BOOLEAN_ATTRIBUTE: 4, - EVENT: 5, - ELEMENT: 6 -}, - directive_i = t => (...i) => ({ - _$litDirective$: t, - values: i -}); - -class directive_s { - constructor(t) {} - - T(t, i, s) { - this.Σdt = t, this.M = i, this.Σct = s; - } - - S(t, i) { - return this.update(t, i); - } - - update(t, i) { - return this.render(...i); - } - -} - - -;// CONCATENATED MODULE: ./node_modules/lit-html/directive-helpers.js - -/** - * @license - * Copyright 2020 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -const { - et: directive_helpers_t -} = Z, - directive_helpers_i = o => null === o || "object" != typeof o && "function" != typeof o, - directive_helpers_n = { - HTML: 1, - SVG: 2 -}, - directive_helpers_v = (o, t) => { - var i, n; - return void 0 === t ? void 0 !== (null === (i = o) || void 0 === i ? void 0 : i._$litType$) : (null === (n = o) || void 0 === n ? void 0 : n._$litType$) === t; -}, - directive_helpers_l = o => { - var t; - return void 0 !== (null === (t = o) || void 0 === t ? void 0 : t._$litDirective$); -}, - directive_helpers_r = o => { - var t; - return null === (t = o) || void 0 === t ? void 0 : t._$litDirective$; -}, - directive_helpers_d = o => void 0 === o.strings, - directive_helpers_e = () => document.createComment(""), - directive_helpers_u = (o, i, n) => { - var v; - const l = o.A.parentNode, - r = void 0 === i ? o.B : i.A; - - if (void 0 === n) { - const i = l.insertBefore(directive_helpers_e(), r), - v = l.insertBefore(directive_helpers_e(), r); - n = new directive_helpers_t(i, v, o, o.options); - } else { - const t = n.B.nextSibling, - i = n.M !== o; - - if (i && (null === (v = n.Q) || void 0 === v || v.call(n, o), n.M = o), t !== r || i) { - let o = n.A; - - for (; o !== t;) { - const t = o.nextSibling; - l.insertBefore(o, r), o = t; - } - } - } - - return n; -}, - directive_helpers_c = (o, t, i = o) => (o.I(t, i), o), - directive_helpers_s = {}, - directive_helpers_f = (o, t = directive_helpers_s) => o.H = t, - directive_helpers_a = o => o.H, - directive_helpers_m = o => { - var t; - null === (t = o.P) || void 0 === t || t.call(o, !1, !0); - let i = o.A; - const n = o.B.nextSibling; - - for (; i !== n;) { - const o = i.nextSibling; - i.remove(), i = o; - } -}, - directive_helpers_p = o => { - o.R(); -}; - - -;// CONCATENATED MODULE: ./node_modules/lit-html/directives/repeat.js - - - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -const repeat_u = (e, s, t) => { - const r = new Map(); - - for (let l = s; l <= t; l++) r.set(e[l], l); - - return r; -}, - repeat_c = directive_i(class extends directive_s { - constructor(e) { - if (super(e), e.type !== directive_t.CHILD) throw Error("repeat() can only be used in text expressions"); - } - - Mt(e, s, t) { - let r; - void 0 === t ? t = s : void 0 !== s && (r = s); - const l = [], - o = []; - let i = 0; - - for (const s of e) l[i] = r ? r(s, i) : i, o[i] = t(s, i), i++; - - return { - values: o, - keys: l - }; - } - - render(e, s, t) { - return this.Mt(e, s, t).values; - } - - update(s, [t, r, c]) { - var d; - const p = directive_helpers_a(s), - { - values: v, - keys: a - } = this.Mt(t, r, c); - if (!p) return this.Pt = a, v; - const h = null !== (d = this.Pt) && void 0 !== d ? d : this.Pt = [], - m = []; - let x, - y, - j = 0, - k = p.length - 1, - w = 0, - b = v.length - 1; - - for (; j <= k && w <= b;) if (null === p[j]) j++;else if (null === p[k]) k--;else if (h[j] === a[w]) m[w] = directive_helpers_c(p[j], v[w]), j++, w++;else if (h[k] === a[b]) m[b] = directive_helpers_c(p[k], v[b]), k--, b--;else if (h[j] === a[b]) m[b] = directive_helpers_c(p[j], v[b]), directive_helpers_u(s, m[b + 1], p[j]), j++, b--;else if (h[k] === a[w]) m[w] = directive_helpers_c(p[k], v[w]), directive_helpers_u(s, p[j], p[k]), k--, w++;else if (void 0 === x && (x = repeat_u(a, w, b), y = repeat_u(h, j, k)), x.has(h[j])) { - if (x.has(h[k])) { - const e = y.get(a[w]), - t = void 0 !== e ? p[e] : null; - - if (null === t) { - const e = directive_helpers_u(s, p[j]); - directive_helpers_c(e, v[w]), m[w] = e; - } else m[w] = directive_helpers_c(t, v[w]), directive_helpers_u(s, p[j], t), p[e] = null; - - w++; - } else directive_helpers_m(p[k]), k--; - } else directive_helpers_m(p[j]), j++; - - for (; w <= b;) { - const e = directive_helpers_u(s, m[b + 1]); - directive_helpers_c(e, v[w]), m[w++] = e; - } - - for (; j <= k;) { - const e = p[j++]; - null !== e && directive_helpers_m(e); - } - - return this.Pt = a, directive_helpers_f(s, m), lit_html_w; - } - -}); - - -;// CONCATENATED MODULE: ./node_modules/lit/directives/repeat.js - -;// CONCATENATED MODULE: ./src/plugins/chatboxviews/templates/chats.js - - - - -function shouldShowChat(c) { - const { - CONTROLBOX_TYPE - } = shared_converse; - const is_minimized = api.settings.get('view_mode') === 'overlayed' && c.get('minimized'); - return c.get('type') === CONTROLBOX_TYPE || !(c.get('hidden') || is_minimized); -} - -/* harmony default export */ const chats = (() => { - const { - chatboxes, - CONTROLBOX_TYPE, - CHATROOMS_TYPE, - HEADLINES_TYPE - } = shared_converse; - const view_mode = api.settings.get('view_mode'); - const connection = shared_converse === null || shared_converse === void 0 ? void 0 : shared_converse.connection; - const logged_out = !(connection !== null && connection !== void 0 && connection.connected) || !(connection !== null && connection !== void 0 && connection.authenticated) || (connection === null || connection === void 0 ? void 0 : connection.disconnecting); - return T` - ${!logged_out && view_mode === 'overlayed' ? T`` : ''} - ${repeat_c(chatboxes.filter(shouldShowChat), m => m.get('jid'), m => { - if (m.get('type') === CONTROLBOX_TYPE) { - return T` - ${view_mode === 'overlayed' ? T`` : ''} - - `; - } else if (m.get('type') === CHATROOMS_TYPE) { - return T` - - `; - } else if (m.get('type') === HEADLINES_TYPE) { - return T` - - `; - } else { - return T` - - `; - } - })} - `; -}); -;// CONCATENATED MODULE: ./src/plugins/chatboxviews/view.js - - - - - - -class ConverseChats extends ElementView { - initialize() { - this.model = shared_converse.chatboxes; - this.listenTo(this.model, 'add', this.render); - this.listenTo(this.model, 'change:closed', this.render); - this.listenTo(this.model, 'change:hidden', this.render); - this.listenTo(this.model, 'change:jid', this.render); - this.listenTo(this.model, 'change:minimized', this.render); - this.listenTo(this.model, 'destroy', this.render); // Use listenTo instead of api.listen.to so that event handlers - // automatically get deregistered when the component is dismounted - - this.listenTo(shared_converse, 'connected', this.render); - this.listenTo(shared_converse, 'reconnected', this.render); - this.listenTo(shared_converse, 'disconnected', this.render); - const bg = document.getElementById('conversejs-bg'); - - if (bg && !bg.innerHTML.trim()) { - V(background_logo(), bg); - } - - const body = document.querySelector('body'); - body.classList.add(`converse-${api.settings.get('view_mode')}`); - this.render(); - /** - * Triggered once the _converse.ChatBoxViews view-colleciton has been initialized - * @event _converse#chatBoxViewsInitialized - * @example _converse.api.listen.on('chatBoxViewsInitialized', () => { ... }); - */ - - api.trigger('chatBoxViewsInitialized'); - } - - render() { - V(chats(), this); - } - -} - -api.elements.define('converse-chats', ConverseChats); -;// CONCATENATED MODULE: ./src/plugins/chatboxviews/container.js -class ChatBoxViews { - constructor() { - this.views = {}; - } - - add(key, val) { - this.views[key] = val; - } - - get(key) { - return this.views[key]; - } - - getAll() { - return Object.values(this.views); - } - - keys() { - return Object.keys(this.views); - } - - remove(key) { - delete this.views[key]; - } - - map(f) { - return Object.values(this.views).map(f); - } - - forEach(f) { - return Object.values(this.views).forEach(f); - } - - filter(f) { - return Object.values(this.views).filter(f); - } - - closeAllChatBoxes() { - return Promise.all(Object.values(this.views).map(v => v.close({ - 'name': 'closeAllChatBoxes' - }))); - } - -} - -/* harmony default export */ const container = (ChatBoxViews); -;// CONCATENATED MODULE: ./src/shared/templates/avatar.js - - -const getImgHref = (image, image_type) => { - return image.startsWith('data:') ? image : `data:${image_type};base64,${image}`; -}; - -/* harmony default export */ const avatar = (o => { - if (o.image) { - return T` - - - `; - } else { - return ''; - } -}); -;// CONCATENATED MODULE: ./node_modules/@converse/skeletor/src/view.js -// Backbone.js 1.4.0 -// (c) 2010-2019 Jeremy Ashkenas and DocumentCloud -// Backbone may be freely distributed under the MIT license. -// View -// ---- -// Views are almost more convention than they are actual code. A View -// is simply a JavaScript object that represents a logical chunk of UI in the -// DOM. This might be a single item, an entire list, a sidebar or panel, or -// even the surrounding frame which wraps your whole app. Defining a chunk of -// UI as a **View** allows you to define your DOM events declaratively, without -// having to worry about render order ... and makes it easy for the view to -// react to specific changes in the state of your models. - - - - - - - - - -const view_paddedLt = /^\s* { - shared_converse.chatboxes.on('destroy', m => shared_converse.chatboxviews.remove(m.get('jid'))); - }); - api.listen.on('cleanup', () => delete shared_converse.chatboxviews); - api.listen.on('clearSession', () => shared_converse.chatboxviews.closeAllChatBoxes()); - api.listen.on('chatBoxViewsInitialized', calculateViewportHeightUnit); - window.addEventListener('resize', calculateViewportHeightUnit); - /************************ END Event Handlers ************************/ - - Object.assign(core_converse, { - /** - * Public API method which will ensure that the #conversejs element - * is inserted into a container element. - * - * This method is useful when the #conversejs element has been - * detached from the DOM somehow. - * @async - * @memberOf converse - * @method insertInto - * @example - * converse.insertInto(document.querySelector('#converse-container')); - */ - insertInto(container) { - var _converse$chatboxview; - - const el = (_converse$chatboxview = shared_converse.chatboxviews) === null || _converse$chatboxview === void 0 ? void 0 : _converse$chatboxview.el; - - if (el && !container.contains(el)) { - container.insertAdjacentElement('afterBegin', el); - } else if (!el) { - throw new Error('Cannot insert non-existing #conversejs element into the DOM'); - } - } - - }); - } - -}); -// EXTERNAL MODULE: ./node_modules/bootstrap.native/dist/bootstrap-native.js -var bootstrap_native = __webpack_require__(6434); -var bootstrap_native_default = /*#__PURE__*/__webpack_require__.n(bootstrap_native); -;// CONCATENATED MODULE: ./src/templates/alert.js - -/* harmony default export */ const templates_alert = (o => T``); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/modals/styles/_modal.scss -var _modal = __webpack_require__(6300); -;// CONCATENATED MODULE: ./src/modals/styles/_modal.scss - - - - - - - - - - - -var _modal_options = {}; - -_modal_options.styleTagTransform = (styleTagTransform_default()); -_modal_options.setAttributes = (setAttributesWithoutAttributes_default()); - - _modal_options.insert = insertBySelector_default().bind(null, "head"); - -_modal_options.domAPI = (styleDomAPI_default()); -_modal_options.insertStyleElement = (insertStyleElement_default()); - -var _modal_update = injectStylesIntoStyleTag_default()(_modal/* default */.Z, _modal_options); - - - - - /* harmony default export */ const styles_modal = (_modal/* default */.Z && _modal/* default.locals */.Z.locals ? _modal/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/modals/base.js - - - - - - - -const { - sizzle: base_sizzle -} = core_converse.env; -const base_u = core_converse.env.utils; -const BaseModal = View.extend({ - className: "modal", - persistent: false, - // Whether this modal should persist in the DOM once it's been closed - events: { - 'click .nav-item .nav-link': 'switchTab' - }, - - initialize(options) { - if (!this.id) { - throw new Error("Each modal class must have a unique id attribute"); - } // Allow properties to be set via passed in options - - - Object.assign(this, options); - this.render(); - this.el.setAttribute('tabindex', '-1'); - this.el.setAttribute('role', 'dialog'); - this.el.setAttribute('aria-hidden', 'true'); - const label_id = this.el.querySelector('.modal-title').getAttribute('id'); - label_id && this.el.setAttribute('aria-labelledby', label_id); - this.insertIntoDOM(); - const Modal = (bootstrap_native_default()).Modal; - this.modal = new Modal(this.el, { - backdrop: true, - keyboard: true - }); - this.el.addEventListener('hide.bs.modal', () => this.onHide(), false); - }, - - onHide() { - base_u.removeClass('selected', this.trigger_el); - !this.persistent && api.modal.remove(this); - }, - - insertIntoDOM() { - const container_el = document.querySelector("#converse-modals"); - container_el.insertAdjacentElement('beforeEnd', this.el); - }, - - switchTab(ev) { - ev.stopPropagation(); - ev.preventDefault(); - base_sizzle('.nav-link.active', this.el).forEach(el => { - base_u.removeClass('active', this.el.querySelector(el.getAttribute('href'))); - base_u.removeClass('active', el); - }); - base_u.addClass('active', ev.target); - base_u.addClass('active', this.el.querySelector(ev.target.getAttribute('href'))); - }, - - alert(message, type = 'primary') { - const body = this.el.querySelector('.modal-alert'); - - if (body === null) { - headless_log.error("Could not find a .modal-alert element in the modal to show an alert message in!"); - return; - } // FIXME: Instead of adding the alert imperatively, we should - // find a way to let the modal rerender with an alert message - - - V(templates_alert({ - 'type': `alert-${type}`, - 'message': message - }), body); - const el = body.firstElementChild; - setTimeout(() => { - base_u.addClass('fade-out', el); - setTimeout(() => base_u.removeElement(el), 600); - }, 5000); - }, - - show(ev) { - if (ev) { - ev.preventDefault(); - this.trigger_el = ev.target; - !base_u.hasClass('chat-image', this.trigger_el) && base_u.addClass('selected', this.trigger_el); - } - - this.modal.show(); - } - -}); -/* harmony default export */ const base = (BaseModal); -;// CONCATENATED MODULE: ./src/modals/templates/buttons.js - - -const modal_close_button = T``; -const modal_header_close_button = T``; -;// CONCATENATED MODULE: ./src/modals/templates/alert.js - - -/* harmony default export */ const modals_templates_alert = (o => T` - -`); -;// CONCATENATED MODULE: ./src/modals/alert.js - - - -const Alert = base.extend({ - id: 'alert-modal', - - initialize() { - base.prototype.initialize.apply(this, arguments); - this.listenTo(this.model, 'change', this.render); - }, - - toHTML() { - return modals_templates_alert(Object.assign({ - __: __ - }, this.model.toJSON())); - } - -}); -/* harmony default export */ const modals_alert = (Alert); -;// CONCATENATED MODULE: ./src/modals/templates/prompt.js - - - -const tpl_field = f => T` -
- -
-`; - -/* harmony default export */ const templates_prompt = (o => T` - -`); -;// CONCATENATED MODULE: ./src/modals/confirm.js - - - -const Confirm = base.extend({ - id: 'confirm-modal', - events: { - 'submit .confirm': 'onConfimation' - }, - - initialize() { - this.confirmation = getOpenPromise(); - base.prototype.initialize.apply(this, arguments); - this.listenTo(this.model, 'change', this.render); - this.el.addEventListener('closed.bs.modal', () => this.confirmation.reject(), false); - }, - - toHTML() { - return templates_prompt(this.model.toJSON()); - }, - - afterRender() { - if (!this.close_handler_registered) { - this.el.addEventListener('closed.bs.modal', () => { - if (!this.confirmation.isResolved) { - this.confirmation.reject(); - } - }, false); - this.close_handler_registered = true; - } - }, - - onConfimation(ev) { - ev.preventDefault(); - const form_data = new FormData(ev.target); - const fields = (this.model.get('fields') || []).map(field => { - const value = form_data.get(field.name).trim(); - field.value = value; - - if (field.challenge) { - field.challenge_failed = value !== field.challenge; - } - - return field; - }); - - if (fields.filter(c => c.challenge_failed).length) { - this.model.set('fields', fields); // Setting an array doesn't trigger a change event - - this.model.trigger('change'); - return; - } - - this.confirmation.resolve(fields); - this.modal.hide(); - } - -}); -/* harmony default export */ const modals_confirm = (Confirm); -;// CONCATENATED MODULE: ./src/plugins/modal.js -/** - * @module converse-modal - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - -core_converse.env.BootstrapModal = base; // expose to plugins - -let modals = []; -const modal_api = { - /** - * API namespace for methods relating to modals - * @namespace _converse.api.modal - * @memberOf _converse.api - */ - modal: { - /** - * Shows a modal of type `ModalClass` to the user. - * Will create a new instance of that class if an existing one isn't - * found. - * @param { Class } ModalClass - * @param { Object } [properties] - Optional properties that will be - * set on a newly created modal instance (if no pre-existing modal was - * found). - * @param { Event } [event] - The DOM event that causes the modal to be shown. - */ - show(ModalClass, properties, ev) { - const modal = this.get(ModalClass.id) || this.create(ModalClass, properties); - modal.show(ev); - return modal; - }, - - /** - * Return a modal with the passed-in identifier, if it exists. - * @param { String } id - */ - get(id) { - return modals.filter(m => m.id == id).pop(); - }, - - /** - * Create a modal of the passed-in type. - * @param { Class } ModalClass - * @param { Object } [properties] - Optional properties that will be - * set on the modal instance. - */ - create(ModalClass, properties) { - const modal = new ModalClass(properties); - modals.push(modal); - return modal; - }, - - /** - * Remove a particular modal - * @param { View } modal - */ - remove(modal) { - modals = modals.filter(m => m !== modal); - modal.remove(); - }, - - /** - * Remove all modals - */ - removeAll() { - modals.forEach(m => m.remove()); - modals = []; - } - - }, - - /** - * Show a confirm modal to the user. - * @method _converse.api.confirm - * @param { String } title - The header text for the confirmation dialog - * @param { (String[]|String) } messages - The text to show to the user - * @param { Array } fields - An object representing a fields presented to the user. - * @property { String } Field.label - The form label for the input field. - * @property { String } Field.name - The name for the input field. - * @property { String } [Field.challenge] - A challenge value that must be provided by the user. - * @property { String } [Field.placeholder] - The placeholder for the input field. - * @property { Boolean} [Field.required] - Whether the field is required or not - * @returns { Promise } A promise which resolves with an array of - * filled in fields or `false` if the confirm dialog was closed or canceled. - */ - async confirm(title, messages = [], fields = []) { - if (typeof messages === 'string') { - messages = [messages]; - } - - const model = new Model({ - title, - messages, - fields, - 'type': 'confirm' - }); - const confirm = new modals_confirm({ - model - }); - confirm.show(); - let result; - - try { - result = await confirm.confirmation; - } catch (e) { - result = false; - } - - confirm.remove(); - return result; - }, - - /** - * Show a prompt modal to the user. - * @method _converse.api.prompt - * @param { String } title - The header text for the prompt - * @param { (String[]|String) } messages - The prompt text to show to the user - * @param { String } placeholder - The placeholder text for the prompt input - * @returns { Promise } A promise which resolves with the text provided by the - * user or `false` if the user canceled the prompt. - */ - async prompt(title, messages = [], placeholder = '') { - if (typeof messages === 'string') { - messages = [messages]; - } - - const model = new Model({ - title, - messages, - 'fields': [{ - 'name': 'reason', - 'placeholder': placeholder - }], - 'type': 'prompt' - }); - const prompt = new modals_confirm({ - model - }); - prompt.show(); - let result; - - try { - var _await$prompt$confirm; - - result = (_await$prompt$confirm = (await prompt.confirmation).pop()) === null || _await$prompt$confirm === void 0 ? void 0 : _await$prompt$confirm.value; - } catch (e) { - result = false; - } - - prompt.remove(); - return result; - }, - - /** - * Show an alert modal to the user. - * @method _converse.api.alert - * @param { ('info'|'warn'|'error') } type - The type of alert. - * @param { String } title - The header text for the alert. - * @param { (String[]|String) } messages - The alert text to show to the user. - */ - alert(type, title, messages) { - if (typeof messages === 'string') { - messages = [messages]; - } - - let level; - - if (type === 'error') { - level = 'alert-danger'; - } else if (type === 'info') { - level = 'alert-info'; - } else if (type === 'warn') { - level = 'alert-warning'; - } - - const model = new Model({ - 'title': title, - 'messages': messages, - 'level': level, - 'type': 'alert' - }); - api.modal.show(modals_alert, { - model - }); - } - -}; -core_converse.plugins.add('converse-modal', { - initialize() { - api.listen.on('disconnect', () => { - const container = document.querySelector("#converse-modals"); - - if (container) { - container.innerHTML = ''; - } - }); - api.listen.on('clearSession', () => api.modal.removeAll()); - Object.assign(shared_converse.api, modal_api); - } - -}); -;// CONCATENATED MODULE: ./node_modules/lit-html/async-directive.js - - - - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -const async_directive_r = (i, t) => { - var s, e; - const o = i.N; - if (void 0 === o) return !1; - - for (const i of o) null === (e = (s = i).O) || void 0 === e || e.call(s, t, !1), async_directive_r(i, t); - - return !0; -}, - async_directive_o = i => { - let t, s; - - do { - if (void 0 === (t = i.M)) break; - s = t.N, s.delete(i), i = t; - } while (0 === (null == s ? void 0 : s.size)); -}, - async_directive_h = i => { - for (let t; t = i.M; i = t) { - let s = t.N; - if (void 0 === s) t.N = s = new Set();else if (s.has(i)) break; - s.add(i), async_directive_d(t); - } -}; - -function async_directive_n(i) { - void 0 !== this.N ? (async_directive_o(this), this.M = i, async_directive_h(this)) : this.M = i; -} - -function async_directive_l(i, t = !1, s = 0) { - const e = this.H, - h = this.N; - if (void 0 !== h && 0 !== h.size) if (t) { - if (Array.isArray(e)) for (let i = s; i < e.length; i++) async_directive_r(e[i], !1), async_directive_o(e[i]);else null != e && (async_directive_r(e, !1), async_directive_o(e)); - } else async_directive_r(this, i); -} - -const async_directive_d = i => { - var t, e, r, o; - i.type == directive_t.CHILD && (null !== (t = (r = i).P) && void 0 !== t || (r.P = async_directive_l), null !== (e = (o = i).Q) && void 0 !== e || (o.Q = async_directive_n)); -}; - -class async_directive_c extends directive_s { - constructor() { - super(...arguments), this.isConnected = !0, this.ut = lit_html_w, this.N = void 0; - } - - T(i, t, s) { - super.T(i, t, s), async_directive_h(this); - } - - O(i, t = !0) { - this.at(i), t && (async_directive_r(this, i), async_directive_o(this)); - } - - at(t) { - var s, e; - t !== this.isConnected && (t ? (this.isConnected = !0, this.ut !== lit_html_w && (this.setValue(this.ut), this.ut = lit_html_w), null === (s = this.reconnected) || void 0 === s || s.call(this)) : (this.isConnected = !1, null === (e = this.disconnected) || void 0 === e || e.call(this))); - } - - S(i, t) { - if (!this.isConnected) throw Error(`AsyncDirective ${this.constructor.name} was rendered while its tree was disconnected.`); - return super.S(i, t); - } - - setValue(i) { - if (this.isConnected) { - if (directive_helpers_d(this.Σdt)) this.Σdt.I(i, this);else { - const t = [...this.Σdt.H]; - t[this.Σct] = i, this.Σdt.I(t, this, 0); - } - } else this.ut = i; - } - - disconnected() {} - - reconnected() {} - -} - - -;// CONCATENATED MODULE: ./node_modules/lit-html/directives/until.js - - - - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -const until_e = t => !directive_helpers_i(t) && "function" == typeof t.then, - until_o = directive_i(class extends async_directive_c { - constructor() { - super(...arguments), this.Ct = 2147483647, this.Rt = []; - } - - render(...r) { - var s; - return null !== (s = r.find(t => !until_e(t))) && void 0 !== s ? s : lit_html_w; - } - - update(r, s) { - const i = this.Rt; - let o = i.length; - this.Rt = s; - - for (let t = 0; t < s.length && !(t > this.Ct); t++) { - const r = s[t]; - if (!until_e(r)) return this.Ct = t, r; - t < o && r === i[t] || (this.Ct = 2147483647, o = 0, Promise.resolve(r).then(t => { - const s = this.Rt.indexOf(r); - s > -1 && s < this.Ct && (this.Ct = s, this.setValue(t)); - })); - } - - return lit_html_w; - } - -}); - - -;// CONCATENATED MODULE: ./node_modules/lit/directives/until.js - -;// CONCATENATED MODULE: ./src/shared/chat/message-actions.js - - - - - - -const { - Strophe: message_actions_Strophe, - u: message_actions_u -} = core_converse.env; - -class MessageActions extends CustomElement { - static get properties() { - return { - correcting: { - type: Boolean - }, - editable: { - type: Boolean - }, - hide_url_previews: { - type: Boolean - }, - is_retracted: { - type: Boolean - }, - message_type: { - type: String - }, - model: { - type: Object - }, - unfurls: { - type: Number - } - }; - } - - render() { - return T`${until_o(this.renderActions(), '')}`; - } - - async renderActions() { - // We want to let the message actions menu drop upwards if we're at the - // bottom of the message history, and down otherwise. This is to avoid - // the menu disappearing behind the bottom panel (toolbar, textarea etc). - // That's difficult to know from state, so we're making an approximation here. - const should_drop_up = this.model.collection.length > 2 && this.model === this.model.collection.last(); - const buttons = await this.getActionButtons(); - const items = buttons.map(b => MessageActions.getActionsDropdownItem(b)); - - if (items.length) { - return T``; - } else { - return ''; - } - } - - static getActionsDropdownItem(o) { - return T` - - `; - } - - onMessageEditButtonClicked(ev) { - var _u$ancestor, _u$ancestor$querySele; - - ev.preventDefault(); - const currently_correcting = this.model.collection.findWhere('correcting'); // TODO: Use state intead of DOM querying - // Then this code can also be put on the model - - const unsent_text = (_u$ancestor = message_actions_u.ancestor(this, '.chatbox')) === null || _u$ancestor === void 0 ? void 0 : (_u$ancestor$querySele = _u$ancestor.querySelector('.chat-textarea')) === null || _u$ancestor$querySele === void 0 ? void 0 : _u$ancestor$querySele.value; - - if (unsent_text && (!currently_correcting || currently_correcting.get('message') !== unsent_text)) { - if (!confirm(__('You have an unsent message which will be lost if you continue. Are you sure?'))) { - return; - } - } - - if (currently_correcting !== this.model) { - currently_correcting === null || currently_correcting === void 0 ? void 0 : currently_correcting.save('correcting', false); - this.model.save('correcting', true); - } else { - this.model.save('correcting', false); - } - } - - async onDirectMessageRetractButtonClicked() { - if (this.model.get('sender') !== 'me') { - return headless_log.error("onMessageRetractButtonClicked called for someone else's message!"); - } - - const retraction_warning = __('Be aware that other XMPP/Jabber clients (and servers) may ' + 'not yet support retractions and that this message may not ' + 'be removed everywhere.'); - - const messages = [__('Are you sure you want to retract this message?')]; - - if (api.settings.get('show_retraction_warning')) { - messages[1] = retraction_warning; - } - - const result = await api.confirm(__('Confirm'), messages); - - if (result) { - const chatbox = this.model.collection.chatbox; - chatbox.retractOwnMessage(this.model); - } - } - /** - * Retract someone else's message in this groupchat. - * @private - * @param { _converse.Message } message - The message which we're retracting. - * @param { string } [reason] - The reason for retracting the message. - */ - - - async retractOtherMessage(reason) { - const chatbox = this.model.collection.chatbox; - const result = await chatbox.retractOtherMessage(this.model, reason); - - if (result === null) { - const err_msg = __(`A timeout occurred while trying to retract the message`); - - api.alert('error', __('Error'), err_msg); - headless_log(err_msg, message_actions_Strophe.LogLevel.WARN); - } else if (message_actions_u.isErrorStanza(result)) { - const err_msg = __(`Sorry, you're not allowed to retract this message.`); - - api.alert('error', __('Error'), err_msg); - headless_log(err_msg, message_actions_Strophe.LogLevel.WARN); - headless_log(result, message_actions_Strophe.LogLevel.WARN); - } - } - - async onMUCMessageRetractButtonClicked() { - const retraction_warning = __('Be aware that other XMPP/Jabber clients (and servers) may ' + 'not yet support retractions and that this message may not ' + 'be removed everywhere.'); - - if (this.model.mayBeRetracted()) { - const messages = [__('Are you sure you want to retract this message?')]; - - if (api.settings.get('show_retraction_warning')) { - messages[1] = retraction_warning; - } - - if (await api.confirm(__('Confirm'), messages)) { - const chatbox = this.model.collection.chatbox; - chatbox.retractOwnMessage(this.model); - } - } else if (await this.model.mayBeModerated()) { - if (this.model.get('sender') === 'me') { - let messages = [__('Are you sure you want to retract this message?')]; - - if (api.settings.get('show_retraction_warning')) { - messages = [messages[0], retraction_warning, messages[1]]; - } - - !!(await api.confirm(__('Confirm'), messages)) && this.retractOtherMessage(); - } else { - let messages = [__('You are about to retract this message.'), __('You may optionally include a message, explaining the reason for the retraction.')]; - - if (api.settings.get('show_retraction_warning')) { - messages = [messages[0], retraction_warning, messages[1]]; - } - - const reason = await api.prompt(__('Message Retraction'), messages, __('Optional reason')); - reason !== false && this.retractOtherMessage(reason); - } - } else { - const err_msg = __(`Sorry, you're not allowed to retract this message`); - - api.alert('error', __('Error'), err_msg); - } - } - - onMessageRetractButtonClicked(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - const chatbox = this.model.collection.chatbox; - - if (chatbox.get('type') === shared_converse.CHATROOMS_TYPE) { - this.onMUCMessageRetractButtonClicked(); - } else { - this.onDirectMessageRetractButtonClicked(); - } - } - - onHidePreviewsButtonClicked(ev) { - var _ev$preventDefault2; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault2 = ev.preventDefault) === null || _ev$preventDefault2 === void 0 ? void 0 : _ev$preventDefault2.call(ev); - - if (this.hide_url_previews) { - this.model.save({ - 'hide_url_previews': false, - 'url_preview_transition': 'fade-in' - }); - } else { - const ogp_metadata = this.model.get('ogp_metadata') || []; - const unfurls_to_show = api.settings.get('muc_show_ogp_unfurls') && ogp_metadata.length; - - if (unfurls_to_show) { - this.model.set('url_preview_transition', 'fade-out'); - } else { - this.model.save({ - 'hide_url_previews': true, - 'url_preview_transition': 'fade-in' - }); - } - } - } - - async getActionButtons() { - var _this$model$get; - - const buttons = []; - - if (this.editable) { - buttons.push({ - 'i18n_text': this.correcting ? __('Cancel Editing') : __('Edit'), - 'handler': ev => this.onMessageEditButtonClicked(ev), - 'button_class': 'chat-msg__action-edit', - 'icon_class': 'fa fa-pencil-alt', - 'name': 'edit' - }); - } - - const may_be_moderated = this.model.get('type') === 'groupchat' && (await this.model.mayBeModerated()); - const retractable = !this.is_retracted && (this.model.mayBeRetracted() || may_be_moderated); - - if (retractable) { - buttons.push({ - 'i18n_text': __('Retract'), - 'handler': ev => this.onMessageRetractButtonClicked(ev), - 'button_class': 'chat-msg__action-retract', - 'icon_class': 'fas fa-trash-alt', - 'name': 'retract' - }); - } - - if (!this.model.collection) { - // While we were awaiting, this model got removed from the - // collection (happens during tests) - return []; - } - - const ogp_metadata = this.model.get('ogp_metadata') || []; - const unfurls_to_show = api.settings.get('muc_show_ogp_unfurls') && ogp_metadata.length; - const media_to_show = (_this$model$get = this.model.get('media_urls')) === null || _this$model$get === void 0 ? void 0 : _this$model$get.length; - - if (unfurls_to_show || media_to_show) { - let title; - const hidden_preview = this.hide_url_previews; - - if (ogp_metadata.length > 1) { - title = hidden_preview ? __('Show URL previews') : __('Hide URL previews'); - } else if (ogp_metadata.length === 1) { - title = hidden_preview ? __('Show URL preview') : __('Hide URL preview'); - } else { - title = hidden_preview ? __('Show media') : __('Hide media'); - } - - buttons.push({ - 'i18n_text': title, - 'handler': ev => this.onHidePreviewsButtonClicked(ev), - 'button_class': 'chat-msg__action-hide-previews', - 'icon_class': this.hide_url_previews ? 'fas fa-eye' : 'fas fa-eye-slash', - 'name': 'hide' - }); - } - /** - * *Hook* which allows plugins to add more message action buttons - * @event _converse#getMessageActionButtons - * @example - * api.listen.on('getMessageActionButtons', (el, buttons) => { - * buttons.push({ - * 'i18n_text': 'Foo', - * 'handler': ev => alert('Foo!'), - * 'button_class': 'chat-msg__action-foo', - * 'icon_class': 'fa fa-check', - * 'name': 'foo' - * }); - * return buttons; - * }); - */ - - - return api.hook('getMessageActionButtons', this, buttons); - } - -} - -api.elements.define('converse-message-actions', MessageActions); -;// CONCATENATED MODULE: ./src/modals/templates/image.js - - - -/* harmony default export */ const templates_image = (o => { - return T` - `; -}); -;// CONCATENATED MODULE: ./src/modals/image.js - - -/* harmony default export */ const modals_image = (base.extend({ - id: 'image-modal', - - toHTML() { - return templates_image({ - 'src': this.src, - 'onload': ev => ev.target.parentElement.style.height = `${ev.target.height}px` - }); - } - -})); -;// CONCATENATED MODULE: ./node_modules/lit/directive.js - -;// CONCATENATED MODULE: ./src/templates/audio.js - -/* harmony default export */ const audio = ((url, hide_url) => T`${hide_url ? '' : T`${url}`}`); -;// CONCATENATED MODULE: ./src/shared/gif/stream.js -class Stream { - constructor(data) { - if (data.toString().indexOf('ArrayBuffer') > 0) { - data = new Uint8Array(data); - } - - this.data = data; - this.len = this.data.length; - this.pos = 0; - } - - readByte() { - if (this.pos >= this.data.length) { - throw new Error('Attempted to read past end of stream.'); - } - - if (this.data instanceof Uint8Array) return this.data[this.pos++];else return this.data.charCodeAt(this.pos++) & 0xFF; - } - - readBytes(n) { - const bytes = []; - - for (let i = 0; i < n; i++) { - bytes.push(this.readByte()); - } - - return bytes; - } - - read(n) { - let s = ''; - - for (let i = 0; i < n; i++) { - s += String.fromCharCode(this.readByte()); - } - - return s; - } - - readUnsigned() { - // Little-endian. - const a = this.readBytes(2); - return (a[1] << 8) + a[0]; - } - -} -;// CONCATENATED MODULE: ./src/shared/gif/utils.js -/** - * @copyright Shachaf Ben-Kiki and the Converse.js contributors - * @description - * Started as a fork of Shachaf Ben-Kiki's jsgif library - * https://github.com/shachaf/jsgif - * @license MIT License - */ -function bitsToNum(ba) { - return ba.reduce(function (s, n) { - return s * 2 + n; - }, 0); -} - -function byteToBitArr(bite) { - const a = []; - - for (let i = 7; i >= 0; i--) { - a.push(!!(bite & 1 << i)); - } - - return a; -} - -function lzwDecode(minCodeSize, data) { - // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String? - let pos = 0; // Maybe this streaming thing should be merged with the Stream? - - function readCode(size) { - let code = 0; - - for (let i = 0; i < size; i++) { - if (data.charCodeAt(pos >> 3) & 1 << (pos & 7)) { - code |= 1 << i; - } - - pos++; - } - - return code; - } - - const output = []; - const clearCode = 1 << minCodeSize; - const eoiCode = clearCode + 1; - let codeSize = minCodeSize + 1; - let dict = []; - - const clear = function () { - dict = []; - codeSize = minCodeSize + 1; - - for (let i = 0; i < clearCode; i++) { - dict[i] = [i]; - } - - dict[clearCode] = []; - dict[eoiCode] = null; - }; - - let code; - let last; - - while (true) { - // eslint-disable-line no-constant-condition - last = code; - code = readCode(codeSize); - - if (code === clearCode) { - clear(); - continue; - } - - if (code === eoiCode) break; - - if (code < dict.length) { - if (last !== clearCode) { - dict.push(dict[last].concat(dict[code][0])); - } - } else { - if (code !== dict.length) throw new Error('Invalid LZW code.'); - dict.push(dict[last].concat(dict[last][0])); - } - - output.push.apply(output, dict[code]); - - if (dict.length === 1 << codeSize && codeSize < 12) { - // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long. - codeSize++; - } - } // I don't know if this is technically an error, but some GIFs do it. - //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.'); - - - return output; -} - -function readSubBlocks(st) { - let size, data; - data = ''; - - do { - size = st.readByte(); - data += st.read(size); - } while (size !== 0); - - return data; -} -/** - * Parses GIF image color table information - * @param { Stream } st - * @param { Number } entries - */ - - -function parseCT(st, entries) { - // Each entry is 3 bytes, for RGB. - const ct = []; - - for (let i = 0; i < entries; i++) { - ct.push(st.readBytes(3)); - } - - return ct; -} -/** - * Parses GIF image information - * @param { Stream } st - * @param { ByteStream } img - * @param { Function } [callback] - */ - - -function parseImg(st, img, callback) { - function deinterlace(pixels, width) { - // Of course this defeats the purpose of interlacing. And it's *probably* - // the least efficient way it's ever been implemented. But nevertheless... - const newPixels = new Array(pixels.length); - const rows = pixels.length / width; - - function cpRow(toRow, fromRow) { - const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width); - newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels)); - } // See appendix E. - - - const offsets = [0, 4, 2, 1]; - const steps = [8, 8, 4, 2]; - let fromRow = 0; - - for (let pass = 0; pass < 4; pass++) { - for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) { - cpRow(toRow, fromRow); - fromRow++; - } - } - - return newPixels; - } - - img.leftPos = st.readUnsigned(); - img.topPos = st.readUnsigned(); - img.width = st.readUnsigned(); - img.height = st.readUnsigned(); - const bits = byteToBitArr(st.readByte()); - img.lctFlag = bits.shift(); - img.interlaced = bits.shift(); - img.sorted = bits.shift(); - img.reserved = bits.splice(0, 2); - img.lctSize = bitsToNum(bits.splice(0, 3)); - - if (img.lctFlag) { - img.lct = parseCT(st, 1 << img.lctSize + 1); - } - - img.lzwMinCodeSize = st.readByte(); - const lzwData = readSubBlocks(st); - img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData); - - if (img.interlaced) { - // Move - img.pixels = deinterlace(img.pixels, img.width); - } - - callback === null || callback === void 0 ? void 0 : callback(img); -} -/** - * Parses GIF header information - * @param { Stream } st - * @param { Function } [callback] - */ - - -function parseHeader(st, callback) { - const hdr = {}; - hdr.sig = st.read(3); - hdr.ver = st.read(3); - - if (hdr.sig !== 'GIF') { - throw new Error('Not a GIF file.'); - } - - hdr.width = st.readUnsigned(); - hdr.height = st.readUnsigned(); - const bits = byteToBitArr(st.readByte()); - hdr.gctFlag = bits.shift(); - hdr.colorRes = bitsToNum(bits.splice(0, 3)); - hdr.sorted = bits.shift(); - hdr.gctSize = bitsToNum(bits.splice(0, 3)); - hdr.bgColor = st.readByte(); - hdr.pixelAspectRatio = st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64 - - if (hdr.gctFlag) { - hdr.gct = parseCT(st, 1 << hdr.gctSize + 1); - } - - callback === null || callback === void 0 ? void 0 : callback(hdr); -} - -function parseExt(st, block, handler) { - function parseGCExt(block) { - st.readByte(); // blocksize, always 4 - - const bits = byteToBitArr(st.readByte()); - block.reserved = bits.splice(0, 3); // Reserved; should be 000. - - block.disposalMethod = bitsToNum(bits.splice(0, 3)); - block.userInput = bits.shift(); - block.transparencyGiven = bits.shift(); - block.delayTime = st.readUnsigned(); - block.transparencyIndex = st.readByte(); - block.terminator = st.readByte(); - handler === null || handler === void 0 ? void 0 : handler.gce(block); - } - - function parseComExt(block) { - block.comment = readSubBlocks(st); - handler.com && handler.com(block); - } - - function parsePTExt(block) { - // No one *ever* uses this. If you use it, deal with parsing it yourself. - st.readByte(); // blocksize, always 12 - - block.ptHeader = st.readBytes(12); - block.ptData = readSubBlocks(st); - handler.pte && handler.pte(block); - } - - function parseAppExt(block) { - function parseNetscapeExt(block) { - st.readByte(); // blocksize, always 3 - - block.unknown = st.readByte(); // ??? Always 1? What is this? - - block.iterations = st.readUnsigned(); - block.terminator = st.readByte(); - handler.app && handler.app.NETSCAPE && handler.app.NETSCAPE(block); - } - - function parseUnknownAppExt(block) { - block.appData = readSubBlocks(st); // FIXME: This won't work if a handler wants to match on any identifier. - - handler.app && handler.app[block.identifier] && handler.app[block.identifier](block); - } - - st.readByte(); // blocksize, always 11 - - block.identifier = st.read(8); - block.authCode = st.read(3); - - switch (block.identifier) { - case 'NETSCAPE': - parseNetscapeExt(block); - break; - - default: - parseUnknownAppExt(block); - break; - } - } - - function parseUnknownExt(block) { - block.data = readSubBlocks(st); - handler.unknown && handler.unknown(block); - } - - block.label = st.readByte(); - - switch (block.label) { - case 0xF9: - block.extType = 'gce'; - parseGCExt(block); - break; - - case 0xFE: - block.extType = 'com'; - parseComExt(block); - break; - - case 0x01: - block.extType = 'pte'; - parsePTExt(block); - break; - - case 0xFF: - block.extType = 'app'; - parseAppExt(block); - break; - - default: - block.extType = 'unknown'; - parseUnknownExt(block); - break; - } -} -/** - * @param { Stream } st - * @param { GIFParserHandlers } handler - */ - - -function parseBlock(st, handler) { - const block = {}; - block.sentinel = st.readByte(); - - switch (String.fromCharCode(block.sentinel)) { - // For ease of matching - case '!': - block.type = 'ext'; - parseExt(st, block, handler); - break; - - case ',': - block.type = 'img'; - parseImg(st, block, handler === null || handler === void 0 ? void 0 : handler.img); - break; - - case ';': - block.type = 'eof'; - handler === null || handler === void 0 ? void 0 : handler.eof(block); - break; - - default: - throw new Error('Unknown block: 0x' + block.sentinel.toString(16)); - // TODO: Pad this with a 0. - } - - if (block.type !== 'eof') setTimeout(() => parseBlock(st, handler), 0); -} -/** - * Takes a Stream and parses it for GIF data, calling the relevant handler - * methods on the passed in `handler` object. - * @param { Stream } st - * @param { GIFParserHandlers } handler - */ - - -function parseGIF(st, handler = {}) { - parseHeader(st, handler === null || handler === void 0 ? void 0 : handler.hdr); - setTimeout(() => parseBlock(st, handler), 0); -} -;// CONCATENATED MODULE: ./src/shared/gif/index.js -/** - * @copyright Shachaf Ben-Kiki, JC Brand - * @description - * Started as a fork of Shachaf Ben-Kiki's jsgif library - * https://github.com/shachaf/jsgif - * @license MIT License - */ - - - -const DELAY_FACTOR = 10; -class ConverseGif { - /** - * Creates a new ConverseGif instance - * @param { HTMLElement } el - * @param { Object } [options] - * @param { Number } [options.width] - The width, in pixels, of the canvas - * @param { Number } [options.height] - The height, in pixels, of the canvas - * @param { Boolean } [options.loop=true] - Setting this to `true` will enable looping of the gif - * @param { Boolean } [options.autoplay=true] - Same as the rel:autoplay attribute above, this arg overrides the img tag info. - * @param { Number } [options.max_width] - Scale images over max_width down to max_width. Helpful with mobile. - * @param { Function } [options.onIterationEnd] - Add a callback for when the gif reaches the end of a single loop (one iteration). The first argument passed will be the gif HTMLElement. - * @param { Boolean } [options.show_progress_bar=true] - * @param { String } [options.progress_bg_color='rgba(0,0,0,0.4)'] - * @param { String } [options.progress_color='rgba(255,0,22,.8)'] - * @param { Number } [options.progress_bar_height=5] - */ - constructor(el, opts) { - this.options = Object.assign({ - width: null, - height: null, - autoplay: true, - loop: true, - show_progress_bar: true, - progress_bg_color: 'rgba(0,0,0,0.4)', - progress_color: 'rgba(255,0,22,.8)', - progress_bar_height: 5 - }, opts); - this.el = el; - this.gif_el = el.querySelector('img'); - this.canvas = el.querySelector('canvas'); - this.ctx = this.canvas.getContext('2d'); // It's good practice to pre-render to an offscreen canvas - - this.offscreenCanvas = document.createElement('canvas'); - this.ctx_scaled = false; - this.disposal_method = null; - this.disposal_restore_from_idx = null; - this.frame = null; - this.frame_offsets = []; // elements have .x and .y properties - - this.frames = []; - this.last_disposal_method = null; - this.last_img = null; - this.load_error = null; - this.playing = this.options.autoplay; - this.transparency = null; - this.frame_idx = 0; - this.iteration_count = 0; - this.start = null; - this.initialize(); - } - - async initialize() { - if (this.options.width && this.options.height) { - this.setSizes(this.options.width, this.options.height); - } - - const data = await this.fetchGIF(this.gif_el.src); - requestAnimationFrame(() => this.startParsing(data)); - } - - initPlayer() { - if (this.load_error) return; - - if (!(this.options.width && this.options.height)) { - this.ctx.scale(this.getCanvasScale(), this.getCanvasScale()); - } // Show the first frame - - - this.frame_idx = 0; - this.putFrame(this.frame_idx); - - if (this.options.autoplay) { - var _this$frames$this$fra; - - const delay = (((_this$frames$this$fra = this.frames[this.frame_idx]) === null || _this$frames$this$fra === void 0 ? void 0 : _this$frames$this$fra.delay) ?? 0) * DELAY_FACTOR; - setTimeout(() => this.play(), delay); - } - } - /** - * Gets the index of the frame "up next" - * @returns {number} - */ - - - getNextFrameNo() { - return (this.frame_idx + 1 + this.frames.length) % this.frames.length; - } - /** - * Called once we've looped through all frames in the GIF - * @returns { Boolean } - Returns `true` if the GIF is now paused (i.e. further iterations are not desired) - */ - - - onIterationEnd() { - var _this$options$onItera, _this$options; - - this.iteration_count++; - (_this$options$onItera = (_this$options = this.options).onIterationEnd) === null || _this$options$onItera === void 0 ? void 0 : _this$options$onItera.call(_this$options, this); - - if (!this.options.loop) { - this.pause(); - return true; - } - - return false; - } - /** - * Inner callback for the `requestAnimationFrame` function. - * - * This method gets wrapped by an arrow function so that the `previous_timestamp` and - * `frame_delay` parameters can also be passed in. The `timestamp` - * parameter comes from `requestAnimationFrame`. - * - * The purpose of this method is to call `putFrame` with the right delay - * in order to render the GIF animation. - * - * Note, this method will cause the *next* upcoming frame to be rendered, - * not the current one. - * - * This means `this.frame_idx` will be incremented before calling `this.putFrame`, so - * `putFrame(0)` needs to be called *before* this method, otherwise the - * animation will incorrectly start from frame #1 (this is done in `initPlayer`). - * - * @param { DOMHighRestTimestamp } timestamp - The timestamp as returned by `requestAnimationFrame` - * @param { DOMHighRestTimestamp } previous_timestamp - The timestamp from the previous iteration of this method. - * We need this in order to calculate whether we have waited long enough to - * show the next frame. - * @param { Number } frame_delay - The delay (in 1/100th of a second) - * before the currently being shown frame should be replaced by a new one. - */ - - - onAnimationFrame(timestamp, previous_timestamp, frame_delay) { - var _this$frames$this$fra2; - - if (!this.playing) { - return; - } - - if (timestamp - previous_timestamp < frame_delay) { - this.hovering ? this.drawPauseIcon() : this.putFrame(this.frame_idx); // We need to wait longer - - requestAnimationFrame(ts => this.onAnimationFrame(ts, previous_timestamp, frame_delay)); - return; - } - - const next_frame = this.getNextFrameNo(); - - if (next_frame === 0 && this.onIterationEnd()) { - return; - } - - this.frame_idx = next_frame; - this.putFrame(this.frame_idx); - const delay = (((_this$frames$this$fra2 = this.frames[this.frame_idx]) === null || _this$frames$this$fra2 === void 0 ? void 0 : _this$frames$this$fra2.delay) || 8) * DELAY_FACTOR; - requestAnimationFrame(ts => this.onAnimationFrame(ts, timestamp, delay)); - } - - setSizes(w, h) { - this.canvas.width = w * this.getCanvasScale(); - this.canvas.height = h * this.getCanvasScale(); - this.offscreenCanvas.width = w; - this.offscreenCanvas.height = h; - this.offscreenCanvas.style.width = w + 'px'; - this.offscreenCanvas.style.height = h + 'px'; - this.offscreenCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0); - } - - setFrameOffset(frame, offset) { - if (!this.frame_offsets[frame]) { - this.frame_offsets[frame] = offset; - return; - } - - if (typeof offset.x !== 'undefined') { - this.frame_offsets[frame].x = offset.x; - } - - if (typeof offset.y !== 'undefined') { - this.frame_offsets[frame].y = offset.y; - } - } - - doShowProgress(pos, length, draw) { - if (draw && this.options.show_progress_bar) { - let height = this.options.progress_bar_height; - const top = (this.canvas.height - height) / (this.ctx_scaled ? this.getCanvasScale() : 1); - const mid = pos / length * this.canvas.width / (this.ctx_scaled ? this.getCanvasScale() : 1); - const width = this.canvas.width / (this.ctx_scaled ? this.getCanvasScale() : 1); - height /= this.ctx_scaled ? this.getCanvasScale() : 1; - this.ctx.fillStyle = this.options.progress_bg_color; - this.ctx.fillRect(mid, top, width - mid, height); - this.ctx.fillStyle = this.options.progress_color; - this.ctx.fillRect(0, top, mid, height); - } - } - /** - * Starts parsing the GIF stream data by calling `parseGIF` and passing in - * a map of handler functions. - * @param { String } data - The GIF file data, as returned by the server - */ - - - startParsing(data) { - const stream = new Stream(data); - /** - * @typedef { Object } GIFParserHandlers - * A map of callback functions passed `parseGIF`. These functions are - * called as various parts of the GIF file format are parsed. - * @property { Function } hdr - Callback to handle the GIF header data - * @property { Function } gce - Callback to handle the GIF Graphic Control Extension data - * @property { Function } com - Callback to handle the comment extension block - * @property { Function } img - Callback to handle image data - * @property { Function } eof - Callback once the end of file has been reached - */ - - const handler = { - 'hdr': this.withProgress(stream, header => this.handleHeader(header)), - 'gce': this.withProgress(stream, gce => this.handleGCE(gce)), - 'com': this.withProgress(stream), - 'img': this.withProgress(stream, img => this.doImg(img), true), - 'eof': () => this.handleEOF(stream) - }; - - try { - parseGIF(stream, handler); - } catch (err) { - this.showError('parse'); - } - } - - drawError() { - this.ctx.fillStyle = 'black'; - this.ctx.fillRect(0, 0, this.options.width ? this.options.width : this.hdr.width, this.options.height ? this.options.height : this.hdr.height); - this.ctx.strokeStyle = 'red'; - this.ctx.lineWidth = 3; - this.ctx.moveTo(0, 0); - this.ctx.lineTo(this.options.width ? this.options.width : this.hdr.width, this.options.height ? this.options.height : this.hdr.height); - this.ctx.moveTo(0, this.options.height ? this.options.height : this.hdr.height); - this.ctx.lineTo(this.options.width ? this.options.width : this.hdr.width, 0); - this.ctx.stroke(); - } - - showError(errtype) { - this.load_error = errtype; - this.hdr = { - width: this.gif_el.width, - height: this.gif_el.height - }; // Fake header. - - this.frames = []; - this.drawError(); - this.el.requestUpdate(); - } - - handleHeader(header) { - this.hdr = header; - this.setSizes(this.options.width ?? this.hdr.width, this.options.height ?? this.hdr.height); - } - /** - * Handler for GIF Graphic Control Extension (GCE) data - */ - - - handleGCE(gce) { - this.pushFrame(gce.delayTime); - this.clear(); - this.transparency = gce.transparencyGiven ? gce.transparencyIndex : null; - this.disposal_method = gce.disposalMethod; - } - /** - * Handler for when the end of the GIF's file has been reached - */ - - - handleEOF(stream) { - this.doDecodeProgress(stream, false); - - if (!(this.options.width && this.options.height)) { - this.canvas.width = this.hdr.width * this.getCanvasScale(); - this.canvas.height = this.hdr.height * this.getCanvasScale(); - } - - this.initPlayer(); - !this.options.autoplay && this.drawPlayIcon(); - } - - pushFrame(delay) { - if (!this.frame) return; - this.frames.push({ - data: this.frame.getImageData(0, 0, this.hdr.width, this.hdr.height), - delay - }); - this.frame_offsets.push({ - x: 0, - y: 0 - }); - } - - doImg(img) { - this.frame = this.frame || this.offscreenCanvas.getContext('2d'); - const currIdx = this.frames.length; //ct = color table, gct = global color table - - const ct = img.lctFlag ? img.lct : this.hdr.gct; // TODO: What if neither exists? - - /* - * Disposal method indicates the way in which the graphic is to - * be treated after being displayed. - * - * Values : 0 - No disposal specified. The decoder is - * not required to take any action. - * 1 - Do not dispose. The graphic is to be left - * in place. - * 2 - Restore to background color. The area used by the - * graphic must be restored to the background color. - * 3 - Restore to previous. The decoder is required to - * restore the area overwritten by the graphic with - * what was there prior to rendering the graphic. - * - * Importantly, "previous" means the frame state - * after the last disposal of method 0, 1, or 2. - */ - - if (currIdx > 0) { - if (this.last_disposal_method === 3) { - // Restore to previous - // If we disposed every frame including first frame up to this point, then we have - // no composited frame to restore to. In this case, restore to background instead. - if (this.disposal_restore_from_idx !== null) { - this.frame.putImageData(this.frames[this.disposal_restore_from_idx].data, 0, 0); - } else { - this.frame.clearRect(this.last_img.leftPos, this.last_img.topPos, this.last_img.width, this.last_img.height); - } - } else { - this.disposal_restore_from_idx = currIdx - 1; - } - - if (this.last_disposal_method === 2) { - // Restore to background color - // Browser implementations historically restore to transparent; we do the same. - // http://www.wizards-toolkit.org/discourse-server/viewtopic.php?f=1&t=21172#p86079 - this.frame.clearRect(this.last_img.leftPos, this.last_img.topPos, this.last_img.width, this.last_img.height); - } - } // else, Undefined/Do not dispose. - // frame contains final pixel data from the last frame; do nothing - //Get existing pixels for img region after applying disposal method - - - const imgData = this.frame.getImageData(img.leftPos, img.topPos, img.width, img.height); //apply color table colors - - img.pixels.forEach((pixel, i) => { - // imgData.data === [R,G,B,A,R,G,B,A,...] - if (pixel !== this.transparency) { - imgData.data[i * 4 + 0] = ct[pixel][0]; - imgData.data[i * 4 + 1] = ct[pixel][1]; - imgData.data[i * 4 + 2] = ct[pixel][2]; - imgData.data[i * 4 + 3] = 255; // Opaque. - } - }); - this.frame.putImageData(imgData, img.leftPos, img.topPos); - - if (!this.ctx_scaled) { - this.ctx.scale(this.getCanvasScale(), this.getCanvasScale()); - this.ctx_scaled = true; - } - - if (!this.last_img) { - // This is the first receivd image, so we draw it - this.ctx.drawImage(this.offscreenCanvas, 0, 0); - } - - this.last_img = img; - } - /** - * Draws a gif frame at a specific index inside the canvas. - * @param { Number } i - The frame index - */ - - - putFrame(i, show_pause_on_hover = true) { - i = parseInt(i, 10); - - if (i > this.frames.length - 1) { - i = 0; - } - - if (i < 0) { - i = 0; - } - - const offset = this.frame_offsets[i]; - this.offscreenCanvas.getContext('2d').putImageData(this.frames[i].data, offset.x, offset.y); - this.ctx.globalCompositeOperation = 'copy'; - this.ctx.drawImage(this.offscreenCanvas, 0, 0); - - if (show_pause_on_hover && this.hovering) { - this.drawPauseIcon(); - } - } - - clear() { - this.transparency = null; - this.last_disposal_method = this.disposal_method; - this.disposal_method = null; - this.frame = null; - } - /** - * Start playing the gif - */ - - - play() { - this.playing = true; - requestAnimationFrame(ts => this.onAnimationFrame(ts, 0, 0)); - } - /** - * Pause the gif - */ - - - pause() { - this.playing = false; - requestAnimationFrame(() => this.drawPlayIcon()); - } - - drawPauseIcon() { - if (!this.playing) { - return; - } // Clear the potential play button by re-rendering the current frame - - - this.putFrame(this.frame_idx, false); - this.ctx.globalCompositeOperation = 'source-over'; // Draw dark overlay - - this.ctx.fillStyle = 'rgb(0, 0, 0, 0.25)'; - this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); - const icon_size = this.canvas.height * 0.1; // Draw bars - - this.ctx.lineWidth = this.canvas.height * 0.04; - this.ctx.beginPath(); - this.ctx.moveTo(this.canvas.width / 2 - icon_size / 2, this.canvas.height / 2 - icon_size); - this.ctx.lineTo(this.canvas.width / 2 - icon_size / 2, this.canvas.height / 2 + icon_size); - this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)'; - this.ctx.stroke(); - this.ctx.beginPath(); - this.ctx.moveTo(this.canvas.width / 2 + icon_size / 2, this.canvas.height / 2 - icon_size); - this.ctx.lineTo(this.canvas.width / 2 + icon_size / 2, this.canvas.height / 2 + icon_size); - this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)'; - this.ctx.stroke(); // Draw circle - - this.ctx.lineWidth = this.canvas.height * 0.02; - this.ctx.strokeStyle = 'rgb(200, 200, 200, 0.75)'; - this.ctx.beginPath(); - this.ctx.arc(this.canvas.width / 2, this.canvas.height / 2, icon_size * 1.5, 0, 2 * Math.PI); - this.ctx.stroke(); - } - - drawPlayIcon() { - if (this.playing) { - return; - } // Clear the potential pause button by re-rendering the current frame - - - this.putFrame(this.frame_idx, false); - this.ctx.globalCompositeOperation = 'source-over'; // Draw dark overlay - - this.ctx.fillStyle = 'rgb(0, 0, 0, 0.25)'; - this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); // Draw triangle - - const triangle_size = this.canvas.height * 0.1; - const region = new Path2D(); - region.moveTo(this.canvas.width / 2 + triangle_size, this.canvas.height / 2); // start at the pointy end - - region.lineTo(this.canvas.width / 2 - triangle_size / 2, this.canvas.height / 2 + triangle_size); - region.lineTo(this.canvas.width / 2 - triangle_size / 2, this.canvas.height / 2 - triangle_size); - region.closePath(); - this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)'; - this.ctx.fill(region); // Draw circle - - const circle_size = triangle_size * 1.5; - this.ctx.lineWidth = this.canvas.height * 0.02; - this.ctx.strokeStyle = 'rgb(200, 200, 200, 0.75)'; - this.ctx.beginPath(); - this.ctx.arc(this.canvas.width / 2, this.canvas.height / 2, circle_size, 0, 2 * Math.PI); - this.ctx.stroke(); - } - - doDecodeProgress(stream, draw) { - this.doShowProgress(stream.pos, stream.data.length, draw); - } - /** - * @param{boolean=} draw Whether to draw progress bar or not; - * this is not idempotent because of translucency. - * Note that this means that the text will be unsynchronized - * with the progress bar on non-frames; - * but those are typically so small (GCE etc.) that it doesn't really matter - */ - - - withProgress(stream, fn, draw) { - return block => { - fn === null || fn === void 0 ? void 0 : fn(block); - this.doDecodeProgress(stream, draw); - }; - } - - getCanvasScale() { - let scale; - - if (this.options.max_width && this.hdr && this.hdr.width > this.options.max_width) { - scale = this.options.max_width / this.hdr.width; - } else { - scale = 1; - } - - return scale; - } - /** - * Makes an HTTP request to fetch a GIF - * @param { String } url - * @returns { Promise } Returns a promise which resolves with the response data. - */ - - - fetchGIF(url) { - const promise = getOpenPromise(); - const h = new XMLHttpRequest(); - h.open('GET', url, true); - h === null || h === void 0 ? void 0 : h.overrideMimeType('text/plain; charset=x-user-defined'); - - h.onload = () => { - if (h.status != 200) { - this.showError('xhr - response'); - return promise.reject(); - } - - promise.resolve(h.response); - }; - - h.onprogress = e => e.lengthComputable && this.doShowProgress(e.loaded, e.total, true); - - h.onerror = () => this.showError('xhr'); - - h.send(); - return promise; - } - -} -;// CONCATENATED MODULE: ./src/templates/file.js - - -/* harmony default export */ const file = ((url, name) => { - const i18n_download = __('Download file "%1$s"', name); - - return T`${i18n_download}`; -}); -;// CONCATENATED MODULE: ./src/templates/form_captcha.js - -/* harmony default export */ const form_captcha = (o => T` -
- ${o.label ? T`` : ''} - - -
-`); -;// CONCATENATED MODULE: ./src/templates/form_checkbox.js - -/* harmony default export */ const form_checkbox = (o => T` -
- - -
`); -;// CONCATENATED MODULE: ./src/templates/form_help.js - -/* harmony default export */ const form_help = (o => T`

${o.text}

`); -;// CONCATENATED MODULE: ./src/templates/form_input.js - -/* harmony default export */ const form_input = (o => T` -
- ${o.type !== 'hidden' ? T`` : ''} - - - ${o.type === 'password' && o.fixed_username ? T` - - ` : ''} - - -
`); -;// CONCATENATED MODULE: ./src/templates/form_select.js - - -const tpl_option = o => T``; - -/* harmony default export */ const form_select = (o => { - var _o$options; - - return T` -
- - -
`; -}); -;// CONCATENATED MODULE: ./src/templates/form_textarea.js - -/* harmony default export */ const form_textarea = (o => T` - - -`); -;// CONCATENATED MODULE: ./src/templates/form_url.js - -/* harmony default export */ const form_url = (o => T` - `); -;// CONCATENATED MODULE: ./src/templates/form_username.js - -/* harmony default export */ const form_username = (o => T` -
- ${o.label ? T`` : ''} -
-
- -
${o.domain}
-
-
-
`); -;// CONCATENATED MODULE: ./src/templates/hyperlink.js - - - -function onClickXMPPURI(ev) { - ev.preventDefault(); - api.rooms.open(ev.target.href); -} - -/* harmony default export */ const hyperlink = ((uri, url_text) => { - let normalized_url = uri.normalize()._string; - - const pretty_url = uri._parts.urn ? normalized_url : uri.readable(); - const visible_url = url_text || pretty_url; - - if (!uri._parts.protocol && !normalized_url.startsWith('http://') && !normalized_url.startsWith('https://')) { - normalized_url = 'http://' + normalized_url; - } - - if (uri._parts.protocol === 'xmpp' && uri._parts.query === 'join') { - return T` - ${visible_url}`; - } - - return T`${visible_url}`; -}); -;// CONCATENATED MODULE: ./src/templates/video.js - -/* harmony default export */ const video = ((url, hide_url) => T`${hide_url ? '' : T`${url}`}`); -;// CONCATENATED MODULE: ./src/utils/html.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description This is the DOM/HTML utilities module. - */ - - - - - - - - - - - - - - - - - - -const { - sizzle: html_sizzle -} = core_converse.env; -const APPROVED_URL_PROTOCOLS = ['http', 'https', 'xmpp', 'mailto']; - -function getAutoCompleteProperty(name, options) { - return { - 'muc#roomconfig_lang': 'language', - 'muc#roomconfig_roomsecret': options !== null && options !== void 0 && options.new_password ? 'new-password' : 'current-password' - }[name]; -} - -const XFORM_TYPE_MAP = { - 'text-private': 'password', - 'text-single': 'text', - 'fixed': 'label', - 'boolean': 'checkbox', - 'hidden': 'hidden', - 'jid-multi': 'textarea', - 'list-single': 'dropdown', - 'list-multi': 'dropdown' -}; - -function slideOutWrapup(el) { - /* Wrapup function for slideOut. */ - el.removeAttribute('data-slider-marker'); - el.classList.remove('collapsed'); - el.style.overflow = ''; - el.style.height = ''; -} - -function getFileName(uri) { - try { - return decodeURI(uri.filename()); - } catch (error) { - headless_log.debug(error); - return uri.filename(); - } -} -/** - * Returns the markup for a URL that points to a downloadable asset - * (such as a video, image or audio file). - * @method u#getOOBURLMarkup - * @param { String } url - * @returns { String } - */ - - -function getOOBURLMarkup(url) { - const uri = getURI(url); - - if (uri === null) { - return url; - } - - if (isVideoURL(uri)) { - return video(url); - } else if (isAudioURL(uri)) { - return audio(url); - } else if (isImageURL(uri)) { - return file(uri.toString(), getFileName(uri)); - } else { - return file(uri.toString(), getFileName(uri)); - } -} -/** - * Return the height of the passed in DOM element, - * based on the heights of its children. - * @method u#calculateElementHeight - * @param {HTMLElement} el - * @returns {integer} - */ - -utils_core.calculateElementHeight = function (el) { - return Array.from(el.children).reduce((result, child) => result + child.offsetHeight, 0); -}; - -utils_core.getNextElement = function (el, selector = '*') { - let next_el = el.nextElementSibling; - - while (next_el !== null && !html_sizzle.matchesSelector(next_el, selector)) { - next_el = next_el.nextElementSibling; - } - - return next_el; -}; - -utils_core.getPreviousElement = function (el, selector = '*') { - let prev_el = el.previousElementSibling; - - while (prev_el !== null && !html_sizzle.matchesSelector(prev_el, selector)) { - prev_el = prev_el.previousElementSibling; - } - - return prev_el; -}; - -utils_core.getFirstChildElement = function (el, selector = '*') { - let first_el = el.firstElementChild; - - while (first_el !== null && !html_sizzle.matchesSelector(first_el, selector)) { - first_el = first_el.nextElementSibling; - } - - return first_el; -}; - -utils_core.getLastChildElement = function (el, selector = '*') { - let last_el = el.lastElementChild; - - while (last_el !== null && !html_sizzle.matchesSelector(last_el, selector)) { - last_el = last_el.previousElementSibling; - } - - return last_el; -}; - -utils_core.hasClass = function (className, el) { - return el instanceof Element && el.classList.contains(className); -}; - -utils_core.toggleClass = function (className, el) { - utils_core.hasClass(className, el) ? utils_core.removeClass(className, el) : utils_core.addClass(className, el); -}; -/** - * Add a class to an element. - * @method u#addClass - * @param {string} className - * @param {Element} el - */ - - -utils_core.addClass = function (className, el) { - el instanceof Element && el.classList.add(className); - return el; -}; -/** - * Remove a class from an element. - * @method u#removeClass - * @param {string} className - * @param {Element} el - */ - - -utils_core.removeClass = function (className, el) { - el instanceof Element && el.classList.remove(className); - return el; -}; - -utils_core.removeElement = function (el) { - el instanceof Element && el.parentNode && el.parentNode.removeChild(el); - return el; -}; - -utils_core.getElementFromTemplateResult = function (tr) { - const div = document.createElement('div'); - V(tr, div); - return div.firstElementChild; -}; - -utils_core.showElement = el => { - utils_core.removeClass('collapsed', el); - utils_core.removeClass('hidden', el); -}; - -utils_core.hideElement = function (el) { - el instanceof Element && el.classList.add('hidden'); - return el; -}; - -utils_core.ancestor = function (el, selector) { - let parent = el; - - while (parent !== null && !html_sizzle.matchesSelector(parent, selector)) { - parent = parent.parentElement; - } - - return parent; -}; -/** - * Return the element's siblings until one matches the selector. - * @private - * @method u#nextUntil - * @param { HTMLElement } el - * @param { String } selector - */ - - -utils_core.nextUntil = function (el, selector) { - const matches = []; - let sibling_el = el.nextElementSibling; - - while (sibling_el !== null && !sibling_el.matches(selector)) { - matches.push(sibling_el); - sibling_el = sibling_el.nextElementSibling; - } - - return matches; -}; -/** - * Helper method that replace HTML-escaped symbols with equivalent characters - * (e.g. transform occurrences of '&' to '&') - * @private - * @method u#unescapeHTML - * @param { String } string - a String containing the HTML-escaped symbols. - */ - - -utils_core.unescapeHTML = function (string) { - var div = document.createElement('div'); - div.innerHTML = string; - return div.innerText; -}; - -utils_core.escapeHTML = function (string) { - return string.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); -}; - -function isProtocolApproved(protocol, safeProtocolsList = APPROVED_URL_PROTOCOLS) { - return !!safeProtocolsList.includes(protocol); -} // Will return false if URL is malformed or contains disallowed characters - - -function isUrlValid(urlString) { - try { - const url = new URL(urlString); - return !!url; - } catch (error) { - return false; - } -} - -function getHyperlinkTemplate(url) { - const http_url = RegExp('^w{3}.', 'ig').test(url) ? `http://${url}` : url; - const uri = getURI(url); - - if (uri !== null && isUrlValid(http_url) && (isProtocolApproved(uri._parts.protocol) || !uri._parts.protocol)) { - return hyperlink(uri, url); - } - - return url; -} - -utils_core.slideInAllElements = function (elements, duration = 300) { - return Promise.all(Array.from(elements).map(e => utils_core.slideIn(e, duration))); -}; - -utils_core.slideToggleElement = function (el, duration) { - if (utils_core.hasClass('collapsed', el) || utils_core.hasClass('hidden', el)) { - return utils_core.slideOut(el, duration); - } else { - return utils_core.slideIn(el, duration); - } -}; -/** - * Shows/expands an element by sliding it out of itself - * @private - * @method u#slideOut - * @param { HTMLElement } el - The HTML string - * @param { Number } duration - The duration amount in milliseconds - */ - - -utils_core.slideOut = function (el, duration = 200) { - return new Promise((resolve, reject) => { - if (!el) { - const err = 'An element needs to be passed in to slideOut'; - headless_log.warn(err); - reject(new Error(err)); - return; - } - - const marker = el.getAttribute('data-slider-marker'); - - if (marker) { - el.removeAttribute('data-slider-marker'); - window.cancelAnimationFrame(marker); - } - - const end_height = utils_core.calculateElementHeight(el); - - if (window.converse_disable_effects) { - // Effects are disabled (for tests) - el.style.height = end_height + 'px'; - slideOutWrapup(el); - resolve(); - return; - } - - if (!utils_core.hasClass('collapsed', el) && !utils_core.hasClass('hidden', el)) { - resolve(); - return; - } - - const steps = duration / 17; // We assume 17ms per animation which is ~60FPS - - let height = 0; - - function draw() { - height += end_height / steps; - - if (height < end_height) { - el.style.height = height + 'px'; - el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw)); - } else { - // We recalculate the height to work around an apparent - // browser bug where browsers don't know the correct - // offsetHeight beforehand. - el.removeAttribute('data-slider-marker'); - el.style.height = utils_core.calculateElementHeight(el) + 'px'; - el.style.overflow = ''; - el.style.height = ''; - resolve(); - } - } - - el.style.height = '0'; - el.style.overflow = 'hidden'; - el.classList.remove('hidden'); - el.classList.remove('collapsed'); - el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw)); - }); -}; - -utils_core.slideIn = function (el, duration = 200) { - /* Hides/collapses an element by sliding it into itself. */ - return new Promise((resolve, reject) => { - if (!el) { - const err = 'An element needs to be passed in to slideIn'; - headless_log.warn(err); - return reject(new Error(err)); - } else if (utils_core.hasClass('collapsed', el)) { - return resolve(el); - } else if (window.converse_disable_effects) { - // Effects are disabled (for tests) - el.classList.add('collapsed'); - el.style.height = ''; - return resolve(el); - } - - const marker = el.getAttribute('data-slider-marker'); - - if (marker) { - el.removeAttribute('data-slider-marker'); - window.cancelAnimationFrame(marker); - } - - const original_height = el.offsetHeight, - steps = duration / 17; // We assume 17ms per animation which is ~60FPS - - let height = original_height; - el.style.overflow = 'hidden'; - - function draw() { - height -= original_height / steps; - - if (height > 0) { - el.style.height = height + 'px'; - el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw)); - } else { - el.removeAttribute('data-slider-marker'); - el.classList.add('collapsed'); - el.style.height = ''; - resolve(el); - } - } - - el.setAttribute('data-slider-marker', window.requestAnimationFrame(draw)); - }); -}; - -function afterAnimationEnds(el, callback) { - el.classList.remove('visible'); - - if (lodash_es_isFunction(callback)) { - callback(); - } -} - -utils_core.isInDOM = function (el) { - return document.querySelector('body').contains(el); -}; - -utils_core.isVisible = function (el) { - if (el === null) { - return false; - } - - if (utils_core.hasClass('hidden', el)) { - return false; - } // XXX: Taken from jQuery's "visible" implementation - - - return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0; -}; - -utils_core.fadeIn = function (el, callback) { - if (!el) { - headless_log.warn('An element needs to be passed in to fadeIn'); - } - - if (window.converse_disable_effects) { - el.classList.remove('hidden'); - return afterAnimationEnds(el, callback); - } - - if (utils_core.hasClass('hidden', el)) { - el.classList.add('visible'); - el.classList.remove('hidden'); - el.addEventListener('webkitAnimationEnd', () => afterAnimationEnds(el, callback)); - el.addEventListener('animationend', () => afterAnimationEnds(el, callback)); - el.addEventListener('oanimationend', () => afterAnimationEnds(el, callback)); - } else { - afterAnimationEnds(el, callback); - } -}; -/** - * Takes an XML field in XMPP XForm (XEP-004: Data Forms) format returns a - * [TemplateResult](https://lit.polymer-project.org/api/classes/_lit_html_.templateresult.html). - * @method u#xForm2TemplateResult - * @param { XMLElement } field - the field to convert - * @param { XMLElement } stanza - the containing stanza - * @param { Object } options - * @returns { TemplateResult } - */ - - -utils_core.xForm2TemplateResult = function (field, stanza, options) { - if (field.getAttribute('type') === 'list-single' || field.getAttribute('type') === 'list-multi') { - const values = utils_core.queryChildren(field, 'value').map(el => el === null || el === void 0 ? void 0 : el.textContent); - const options = utils_core.queryChildren(field, 'option').map(option => { - var _option$querySelector; - - const value = (_option$querySelector = option.querySelector('value')) === null || _option$querySelector === void 0 ? void 0 : _option$querySelector.textContent; - return { - 'value': value, - 'label': option.getAttribute('label'), - 'selected': values.includes(value), - 'required': !!field.querySelector('required') - }; - }); - return form_select({ - options, - 'id': utils_core.getUniqueId(), - 'label': field.getAttribute('label'), - 'multiple': field.getAttribute('type') === 'list-multi', - 'name': field.getAttribute('var'), - 'required': !!field.querySelector('required') - }); - } else if (field.getAttribute('type') === 'fixed') { - var _field$querySelector; - - const text = (_field$querySelector = field.querySelector('value')) === null || _field$querySelector === void 0 ? void 0 : _field$querySelector.textContent; - return form_help({ - text - }); - } else if (field.getAttribute('type') === 'jid-multi') { - var _field$querySelector2; - - return form_textarea({ - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label') || '', - 'value': (_field$querySelector2 = field.querySelector('value')) === null || _field$querySelector2 === void 0 ? void 0 : _field$querySelector2.textContent, - 'required': !!field.querySelector('required') - }); - } else if (field.getAttribute('type') === 'boolean') { - var _field$querySelector3; - - const value = (_field$querySelector3 = field.querySelector('value')) === null || _field$querySelector3 === void 0 ? void 0 : _field$querySelector3.textContent; - return form_checkbox({ - 'id': utils_core.getUniqueId(), - 'name': field.getAttribute('var'), - 'label': field.getAttribute('label') || '', - 'checked': (value === '1' || value === 'true') && 'checked="1"' || '', - 'required': !!field.querySelector('required') - }); - } else if (field.getAttribute('var') === 'url') { - var _field$querySelector4; - - return form_url({ - 'label': field.getAttribute('label') || '', - 'value': (_field$querySelector4 = field.querySelector('value')) === null || _field$querySelector4 === void 0 ? void 0 : _field$querySelector4.textContent - }); - } else if (field.getAttribute('var') === 'username') { - var _field$querySelector5; - - return form_username({ - 'domain': ' @' + options.domain, - 'name': field.getAttribute('var'), - 'type': XFORM_TYPE_MAP[field.getAttribute('type')], - 'label': field.getAttribute('label') || '', - 'value': (_field$querySelector5 = field.querySelector('value')) === null || _field$querySelector5 === void 0 ? void 0 : _field$querySelector5.textContent, - 'required': !!field.querySelector('required') - }); - } else if (field.getAttribute('var') === 'ocr') { - // Captcha - const uri = field.querySelector('uri'); - const el = html_sizzle('data[cid="' + uri.textContent.replace(/^cid:/, '') + '"]', stanza)[0]; - return form_captcha({ - 'label': field.getAttribute('label'), - 'name': field.getAttribute('var'), - 'data': el === null || el === void 0 ? void 0 : el.textContent, - 'type': uri.getAttribute('type'), - 'required': !!field.querySelector('required') - }); - } else { - var _field$querySelector6; - - const name = field.getAttribute('var'); - return form_input({ - 'id': utils_core.getUniqueId(), - 'label': field.getAttribute('label') || '', - 'name': name, - 'fixed_username': options === null || options === void 0 ? void 0 : options.fixed_username, - 'autocomplete': getAutoCompleteProperty(name, options), - 'placeholder': null, - 'required': !!field.querySelector('required'), - 'type': XFORM_TYPE_MAP[field.getAttribute('type')], - 'value': (_field$querySelector6 = field.querySelector('value')) === null || _field$querySelector6 === void 0 ? void 0 : _field$querySelector6.textContent - }); - } -}; - -Object.assign(utils_core, { - getOOBURLMarkup -}); -/* harmony default export */ const html = (utils_core); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/shared/components/styles/gif.scss -var gif = __webpack_require__(3735); -;// CONCATENATED MODULE: ./src/shared/components/styles/gif.scss - - - - - - - - - - - -var gif_options = {}; - -gif_options.styleTagTransform = (styleTagTransform_default()); -gif_options.setAttributes = (setAttributesWithoutAttributes_default()); - - gif_options.insert = insertBySelector_default().bind(null, "head"); - -gif_options.domAPI = (styleDomAPI_default()); -gif_options.insertStyleElement = (insertStyleElement_default()); - -var gif_update = injectStylesIntoStyleTag_default()(gif/* default */.Z, gif_options); - - - - - /* harmony default export */ const styles_gif = (gif/* default */.Z && gif/* default.locals */.Z.locals ? gif/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/shared/components/gif.js - - - - - - -class ConverseGIF extends CustomElement { - static get properties() { - /** - * @typedef { Object } ConverseGIFComponentProperties - * @property { Boolean } autoplay - * @property { Boolean } noloop - * @property { String } progress_color - * @property { String } nick - * @property { ('url'|'empty'|'error') } fallback - * @property { String } src - */ - return { - 'autoplay': { - type: Boolean - }, - 'noloop': { - type: Boolean - }, - 'progress_color': { - type: String - }, - 'fallback': { - type: String - }, - 'src': { - type: String - } - }; - } - - constructor() { - super(); - this.autoplay = false; - this.noloop = false; - this.fallback = 'url'; - } - - initialize() { - const options = { - 'autoplay': this.autoplay, - 'loop': !this.noloop - }; - - if (this.progress_color) { - options['progress_color'] = this.progress_color; - } - - this.supergif = new ConverseGif(this, options); - } - - updated(changed) { - if (!this.supergif || changed.has('src')) { - this.initialize(); - return; - } - - if (changed.has('autoplay')) { - this.supergif.options.autoplay = this.autoplay; - } - - if (changed.has('noloop')) { - this.supergif.options.loop = !this.noloop; - } - - if (changed.has('progress_color')) { - this.supergif.options.progress_color = this.progress_color; - } - } - - render() { - var _this$supergif; - - return (_this$supergif = this.supergif) !== null && _this$supergif !== void 0 && _this$supergif.load_error && ['url', 'empty'].includes(this.fallback) ? this.renderErrorFallback() : T` this.setHover()} - @mouseleave=${() => this.unsetHover()} - @click=${ev => this.onControlsClicked(ev)}>`; - } - - renderErrorFallback() { - if (this.fallback === 'url') { - return getHyperlinkTemplate(this.src); - } else if (this.fallback === 'empty') { - return ''; - } - } - - setHover() { - if (this.supergif) { - this.supergif.hovering = true; - this.hover_timeout && clearTimeout(this.hover_timeout); - this.hover_timeout = setTimeout(() => this.unsetHover(), 2000); - } - } - - unsetHover() { - if (this.supergif) this.supergif.hovering = false; - } - - onControlsClicked(ev) { - ev.preventDefault(); - - if (this.supergif.playing) { - this.supergif.pause(); - } else { - // When the user manually clicks play, we turn on looping - this.supergif.options.loop = true; - this.supergif.play(); - } - } - -} -api.elements.define('converse-gif', ConverseGIF); -;// CONCATENATED MODULE: ./src/templates/gif.js - - -/* harmony default export */ const templates_gif = ((url, hide_url) => T`${hide_url ? '' : T`${url}`}`); -;// CONCATENATED MODULE: ./node_modules/lit/async-directive.js - -;// CONCATENATED MODULE: ./src/shared/directives/image.js - - - - - - -const { - URI: image_URI -} = core_converse.env; - -class ImageDirective extends async_directive_c { - render(src, href, onLoad, onClick) { - return href ? T`${this.renderImage(src, href, onLoad, onClick)}` : this.renderImage(src, href, onLoad, onClick); - } - - renderImage(src, href, onLoad, onClick) { - return T` this.onError(src, href, onLoad, onClick)} - @load=${onLoad}/>`; - } - - onError(src, href, onLoad, onClick) { - if (isURLWithImageExtension(src)) { - href && this.setValue(getHyperlinkTemplate(href)); - } else { - // Before giving up and falling back to just rendering a hyperlink, - // we attach `.png` and try one more time. - // This works with some Imgur URLs - const uri = new image_URI(src); - const filename = uri.filename(); - uri.filename(`${filename}.png`); - this.setValue(renderImage(uri.toString(), href, onLoad, onClick)); - } - } - -} -/** - * lit directive which attempts to render an element from a URL. - * It will fall back to rendering an element if it can't. - * - * @param { String } src - The value that will be assigned to the `src` attribute of the `` element. - * @param { String } href - The value that will be assigned to the `href` attribute of the `` element. - * @param { Function } onLoad - A callback function to be called once the image has loaded. - * @param { Function } onClick - A callback function to be called once the image has been clicked. - */ - - -const renderImage = directive_i(ImageDirective); -;// CONCATENATED MODULE: ./src/templates/image.js - - -/* harmony default export */ const src_templates_image = (o => T`${renderImage(o.url, o.href, o.onLoad, o.onClick)}`); -;// CONCATENATED MODULE: ./src/shared/directives/styling.js - - - - - -async function transform(t) { - await t.addTemplates(); - return t.payload; -} - -class StylingDirective extends directive_s { - render(txt, offset, mentions, options) { - // eslint-disable-line class-methods-use-this - const t = new RichText(txt, offset, mentions, Object.assign(options, { - 'show_images': false, - 'embed_videos': false, - 'embed_audio': false - })); - return T`${until_o(transform(t), T`${t}`)}`; - } - -} - -const renderStylingDirectiveBody = directive_i(StylingDirective); -;// CONCATENATED MODULE: ./src/shared/styling.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - * @description Utility functions to help with parsing XEP-393 message styling hints - * @todo Other parsing helpers can be made more abstract and placed here. - */ - - -const bracketing_directives = ['*', '_', '~', '`']; -const styling_directives = [...bracketing_directives, '```', '>']; -const styling_map = { - '*': { - 'name': 'strong', - 'type': 'span' - }, - '_': { - 'name': 'emphasis', - 'type': 'span' - }, - '~': { - 'name': 'strike', - 'type': 'span' - }, - '`': { - 'name': 'preformatted', - 'type': 'span' - }, - '```': { - 'name': 'preformatted_block', - 'type': 'block' - }, - '>': { - 'name': 'quote', - 'type': 'block' - } -}; -const dont_escape = ['_', '>', '`', '~']; -const styling_templates = { - // m is the chatbox model - // i is the offset of this directive relative to the start of the original message - 'emphasis': (txt, i, mentions, options) => T`_${renderStylingDirectiveBody(txt, i, mentions, options)}_`, - 'preformatted': txt => T`\`${txt}\``, - 'preformatted_block': txt => T`
\`\`\`
${txt}
\`\`\`
`, - 'quote': (txt, i, mentions, options) => T`
${renderStylingDirectiveBody(txt, i, mentions, options)}
`, - 'strike': (txt, i, mentions, options) => T`~${renderStylingDirectiveBody(txt, i, mentions, options)}~`, - 'strong': (txt, i, mentions, options) => T`*${renderStylingDirectiveBody(txt, i, mentions, options)}*` -}; -/** - * Checks whether a given character "d" at index "i" of "text" is a valid opening or closing directive. - * @param { String } d - The potential directive - * @param { String } text - The text in which the directive appears - * @param { Number } i - The directive index - * @param { Boolean } opening - Check for a valid opening or closing directive - */ - -function isValidDirective(d, text, i, opening) { - // Ignore directives that are parts of words - // More info on the Regexes used here: https://javascript.info/regexp-unicode#unicode-properties-p - if (opening) { - const regex = RegExp(dont_escape.includes(d) ? `^(\\p{L}|\\p{N})${d}` : `^(\\p{L}|\\p{N})\\${d}`, 'u'); - - if (i > 1 && regex.test(text.slice(i - 1))) { - return false; - } - - const is_quote = isQuoteDirective(d); - - if (is_quote && i > 0 && text[i - 1] !== '\n') { - // Quote directives must be on newlines - return false; - } else if (bracketing_directives.includes(d) && text[i + 1] === d) { - // Don't consider empty bracketing directives as valid (e.g. **, `` etc.) - return false; - } - } else { - const regex = RegExp(dont_escape.includes(d) ? `^${d}(\\p{L}|\\p{N})` : `^\\${d}(\\p{L}|\\p{N})`, 'u'); - - if (i < text.length - 1 && regex.test(text.slice(i))) { - return false; - } - - if (bracketing_directives.includes(d) && text[i - 1] === d) { - // Don't consider empty directives as valid (e.g. **, `` etc.) - return false; - } - } - - return true; -} -/** - * Given a specific index "i" of "text", return the directive it matches or - * null otherwise. - * @param { String } text - The text in which the directive appears - * @param { Number } i - The directive index - * @param { Boolean } opening - Whether we're looking for an opening or closing directive - */ - - -function getDirective(text, i, opening = true) { - let d; - - if (/(^```\s*\n|^```\s*$)/.test(text.slice(i)) && (i === 0 || text[i - 1] === '\n' || text[i - 1] === '>')) { - d = text.slice(i, i + 3); - } else if (styling_directives.includes(text.slice(i, i + 1))) { - d = text.slice(i, i + 1); - if (!isValidDirective(d, text, i, opening)) return null; - } else { - return null; - } - - return d; -} -/** - * Given a directive "d", which occurs in "text" at index "i", check that it - * has a valid closing directive and return the length from start to end of the - * directive. - * @param { String } d -The directive - * @param { Number } i - The directive index - * @param { String } text -The text in which the directive appears - */ - - -function getDirectiveLength(d, text, i) { - if (!d) { - return 0; - } - - const begin = i; - i += d.length; - - if (isQuoteDirective(d)) { - i += text.slice(i).split(/\n[^>]/).shift().length; - return i - begin; - } else if (styling_map[d].type === 'span') { - const line = text.slice(i).split('\n').shift(); - let j = 0; - let idx = line.indexOf(d); - - while (idx !== -1) { - if (getDirective(text, i + idx, false) === d) { - return idx + 2 * d.length; - } - - idx = line.indexOf(d, j++); - } - - return 0; - } else { - // block directives - const substring = text.slice(i + 1); - let j = 0; - let idx = substring.indexOf(d); - - while (idx !== -1) { - if (getDirective(text, i + 1 + idx, false) === d) { - return idx + 1 + 2 * d.length; - } - - idx = substring.indexOf(d, j++); - } - - return 0; - } -} - -function getDirectiveAndLength(text, i) { - const d = getDirective(text, i); - const length = d ? getDirectiveLength(d, text, i) : 0; - return length > 0 ? { - d, - length - } : {}; -} -const isQuoteDirective = d => ['>', '>'].includes(d); -function getDirectiveTemplate(d, text, offset, mentions, options) { - const template = styling_templates[styling_map[d].name]; - - if (isQuoteDirective(d)) { - const newtext = text.replace(/\n>/g, '\n') // Don't show the directive itself - .replace(/\n$/, ''); // Trim line-break at the end - - return template(newtext, offset, mentions, options); - } else { - return template(text, offset, mentions, options); - } -} -function containsDirectives(text) { - for (let i = 0; i < styling_directives.length; i++) { - if (text.includes(styling_directives[i])) { - return true; - } - } -} -;// CONCATENATED MODULE: ./src/shared/rich-text.js - - - - - - - - - - - - -const { - URI: rich_text_URI -} = core_converse.env; - -const rich_text_isString = s => typeof s === 'string'; // We don't render more than two line-breaks, replace extra line-breaks with -// the zero-width whitespace character - - -const collapseLineBreaks = text => text.replace(/\n\n+/g, m => `\n${'\u200B'.repeat(m.length - 2)}\n`); - -const tpl_mention_with_nick = o => T`${o.mention}`; - -const tpl_mention = o => T`${o.mention}`; -/** - * @class RichText - * A String subclass that is used to render rich text (i.e. text that contains - * hyperlinks, images, mentions, styling etc.). - * - * The "rich" parts of the text is represented by lit TemplateResult - * objects which are added via the {@link RichText.addTemplateResult} - * method and saved as metadata. - * - * By default Converse adds TemplateResults to support emojis, hyperlinks, - * images, map URIs and mentions. - * - * 3rd party plugins can listen for the `beforeMessageBodyTransformed` - * and/or `afterMessageBodyTransformed` events and then call - * `addTemplateResult` on the RichText instance in order to add their own - * rich features. - */ - - -class RichText extends String { - /** - * Create a new {@link RichText} instance. - * @param { String } text - The text to be annotated - * @param { Integer } offset - The offset of this particular piece of text - * from the start of the original message text. This is necessary because - * RichText instances can be nested when templates call directives - * which create new RichText instances (as happens with XEP-393 styling directives). - * @param { Array } mentions - An array of mention references - * @param { Object } options - * @param { String } options.nick - The current user's nickname (only relevant if the message is in a XEP-0045 MUC) - * @param { Boolean } options.render_styling - Whether XEP-0393 message styling should be applied to the message - * @param { Boolean } options.show_images - Whether image URLs should be rendered as tags. - * @param { Boolean } options.embed_videos - Whether video URLs should be rendered as
- `; -}); -;// CONCATENATED MODULE: ./src/modals/user-details.js - - - - - -const user_details_u = core_converse.env.utils; - -function removeContact(contact) { - contact.removeFromRoster(() => contact.destroy(), e => { - e && headless_log.error(e); - api.alert('error', __('Error'), [__('Sorry, there was an error while trying to remove %1$s as a contact.', contact.getDisplayName())]); - }); -} - -const UserDetailsModal = base.extend({ - id: 'user-details-modal', - persistent: true, - events: { - 'click button.refresh-contact': 'refreshContact', - 'click .fingerprint-trust .btn input': 'toggleDeviceTrust' - }, - - initialize() { - base.prototype.initialize.apply(this, arguments); - this.model.rosterContactAdded.then(() => this.registerContactEventHandlers()); - this.listenTo(this.model, 'change', this.render); - this.registerContactEventHandlers(); - /** - * Triggered once the UserDetailsModal has been initialized - * @event _converse#userDetailsModalInitialized - * @type { _converse.ChatBox } - * @example _converse.api.listen.on('userDetailsModalInitialized', chatbox => { ... }); - */ - - api.trigger('userDetailsModalInitialized', this.model); - }, - - toHTML() { - var _this$model; - - const vcard = (_this$model = this.model) === null || _this$model === void 0 ? void 0 : _this$model.vcard; - const vcard_json = vcard ? vcard.toJSON() : {}; - return user_details(Object.assign(this.model.toJSON(), vcard_json, { - '_converse': shared_converse, - 'allow_contact_removal': api.settings.get('allow_contact_removal'), - 'display_name': this.model.getDisplayName(), - 'is_roster_contact': this.model.contact !== undefined, - 'removeContact': ev => this.removeContact(ev), - 'view': this, - 'utils': user_details_u - })); - }, - - registerContactEventHandlers() { - if (this.model.contact !== undefined) { - this.listenTo(this.model.contact, 'change', this.render); - this.listenTo(this.model.contact.vcard, 'change', this.render); - this.model.contact.on('destroy', () => { - delete this.model.contact; - this.render(); - }); - } - }, - - async refreshContact(ev) { - if (ev && ev.preventDefault) { - ev.preventDefault(); - } - - const refresh_icon = this.el.querySelector('.fa-refresh'); - user_details_u.addClass('fa-spin', refresh_icon); - - try { - await api.vcard.update(this.model.contact.vcard, true); - } catch (e) { - headless_log.fatal(e); - this.alert(__('Sorry, something went wrong while trying to refresh'), 'danger'); - } - - user_details_u.removeClass('fa-spin', refresh_icon); - }, - - removeContact(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - - if (!api.settings.get('allow_contact_removal')) { - return; - } - - const result = confirm(__("Are you sure you want to remove this contact?")); - - if (result === true) { - // XXX: The `dismissHandler` in bootstrap.native tries to - // reference the remove button after it's been cleared from - // the DOM, so we delay removing the contact to give it time. - setTimeout(() => removeContact(this.model.contact), 1); - this.modal.hide(); - } - } - -}); -shared_converse.UserDetailsModal = UserDetailsModal; -/* harmony default export */ const modals_user_details = (UserDetailsModal); -;// CONCATENATED MODULE: ./src/shared/chat/templates/info-message.js - - - -const { - dayjs: info_message_dayjs -} = core_converse.env; -/* harmony default export */ const info_message = (el => { - const isodate = info_message_dayjs(el.model.get('time')).toISOString(); - - const i18n_retry = __('Retry'); - - return T` -
- -
- - -
- ${el.model.get('reason') ? T`${el.model.get('reason')}` : ``} - ${el.model.get('error_text') ? T`${el.model.get('error_text')}` : ``} - ${el.model.get('retry_event_id') ? T`${i18n_retry}` : ''} -
`; -}); -;// CONCATENATED MODULE: ./src/shared/chat/templates/unfurl.js - - - -function isValidURL(url) { - // We don't consider relative URLs as valid - return !!getURI(url).host(); -} - -function isValidImage(image) { - return image && isImageDomainAllowed(image) && isValidURL(image); -} - -function shouldHideMediaURL(o) { - return isGIFURL(o.url) || isVideoURL(o.url) || isAudioURL(o.url); -} - -const tpl_url_wrapper = (o, wrapped_template) => o.url && isValidURL(o.url) && !isGIFURL(o.url) ? T`${wrapped_template(o)}` : wrapped_template(o); - -const tpl_image = o => T``; - -/* harmony default export */ const unfurl = (o => { - const valid_image = isValidImage(o.image); - const has_body_info = o.title || o.description || o.url; - - if (valid_image || has_body_info) { - return T`
- ${valid_image ? tpl_url_wrapper(o, tpl_image) : ''} - ${has_body_info ? T` -
- ${o.title ? tpl_url_wrapper(o, o => T`
${o.title}
`) : ''} - ${o.description ? T`

` : ''} - ${o.url ? T`

${getURI(o.url).domain()}

` : ''} -
` : ''} -
`; - } else { - return ''; - } -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/shared/chat/styles/unfurl.scss -var styles_unfurl = __webpack_require__(7415); -;// CONCATENATED MODULE: ./src/shared/chat/styles/unfurl.scss - - - - - - - - - - - -var unfurl_options = {}; - -unfurl_options.styleTagTransform = (styleTagTransform_default()); -unfurl_options.setAttributes = (setAttributesWithoutAttributes_default()); - - unfurl_options.insert = insertBySelector_default().bind(null, "head"); - -unfurl_options.domAPI = (styleDomAPI_default()); -unfurl_options.insertStyleElement = (insertStyleElement_default()); - -var unfurl_update = injectStylesIntoStyleTag_default()(styles_unfurl/* default */.Z, unfurl_options); - - - - - /* harmony default export */ const chat_styles_unfurl = (styles_unfurl/* default */.Z && styles_unfurl/* default.locals */.Z.locals ? styles_unfurl/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/shared/chat/unfurl.js - - - - -class MessageUnfurl extends CustomElement { - static get properties() { - return { - description: { - type: String - }, - image: { - type: String - }, - jid: { - type: String - }, - title: { - type: String - }, - url: { - type: String - } - }; - } - - render() { - return unfurl(Object.assign({ - 'onload': () => this.onImageLoad() - }, { - description: this.description || '', - image: this.image || '', - title: this.title || '', - url: this.url || '' - })); - } - - onImageLoad() { - this.dispatchEvent(new CustomEvent('imageLoaded', { - detail: this, - 'bubbles': true - })); - } - -} -api.elements.define('converse-message-unfurl', MessageUnfurl); -;// CONCATENATED MODULE: ./src/shared/chat/templates/message.js - - - - -/* harmony default export */ const templates_message = ((el, o) => { - var _el$model$get, _el$model$get2; - - const i18n_new_messages = __('New messages'); - - return T` - ${o.is_first_unread ? T`

${i18n_new_messages}
` : ''} -
- - - - - ${o.should_show_avatar ? renderAvatar(el.getAvatarData()) : ''} -
- - ${!o.is_me_message ? T` - - ${o.username} - ${o.hats.map(h => T`${h.title}`)} - - ${o.is_encrypted ? T`` : ''} - ` : ''} -
-
- ${o.is_me_message ? T` -   - ${o.is_me_message ? '**' : ''}${o.username} ` : ''} - ${o.is_retracted ? el.renderRetraction() : el.renderMessageText()} -
- -
- - ${!el.model.get('hide_url_previews') ? (_el$model$get2 = el.model.get('ogp_metadata')) === null || _el$model$get2 === void 0 ? void 0 : _el$model$get2.map(m => { - var _el$chatbox; - - return T``; - }) : ''} -
-
`; -}); -;// CONCATENATED MODULE: ./src/shared/chat/templates/message-text.js - - - - - -const tpl_edited_icon = el => { - const i18n_edited = __('This message has been edited'); - - return T``; -}; - -/* harmony default export */ const message_text = (el => { - const i18n_show = __('Show more'); - - const is_groupchat_message = el.model.get('type') === 'groupchat'; - - const i18n_show_less = __('Show less'); - - const tpl_spoiler_hint = T` - - `; - const spoiler_classes = el.model.get('is_spoiler') ? `spoiler ${el.model.get('is_spoiler_visible') ? '' : 'hidden'}` : ''; - const text = el.model.getMessageText(); - const show_oob = el.model.get('oob_url') && text !== el.model.get('oob_url'); - return T` - ${el.model.get('is_spoiler') ? tpl_spoiler_hint : ''} - ${el.model.get('subject') ? T`
${el.model.get('subject')}
` : ''} - - - ${el.model.get('received') && !el.model.isMeCommand() && !is_groupchat_message ? T`` : ''} - ${el.model.get('edited') ? tpl_edited_icon(el) : ''} - - ${show_oob ? T`
${getOOBURLMarkup(el.model.get('oob_url'))}
` : ''} -
${el.model.get('error_text') || el.model.get('error')}
- `; -}); -;// CONCATENATED MODULE: ./src/templates/spinner.js - -/* harmony default export */ const spinner = ((o = {}) => { - var _o$classes; - - if ((_o$classes = o.classes) !== null && _o$classes !== void 0 && _o$classes.includes('hor_centered')) { - return T`
`; - } else { - return T``; - } -}); -// EXTERNAL MODULE: ./node_modules/lodash/debounce.js -var lodash_debounce = __webpack_require__(4971); -var debounce_default = /*#__PURE__*/__webpack_require__.n(lodash_debounce); -;// CONCATENATED MODULE: ./src/shared/chat/templates/new-day.js - -/* harmony default export */ const new_day = (o => T` -
-
- -
-`); -;// CONCATENATED MODULE: ./src/shared/chat/utils.js - - - -const { - dayjs: utils_dayjs -} = core_converse.env; -function onScrolledDown(model) { - if (!model.isHidden()) { - if (api.settings.get('allow_url_history_change')) { - // Clear location hash if set to one of the messages in our history - const hash = window.location.hash; - hash && model.messages.get(hash.slice(1)) && shared_converse.router.history.navigate(); - } - } -} -/** - * Called when the chat content is scrolled up or down. - * We want to record when the user has scrolled away from - * the bottom, so that we don't automatically scroll away - * from what the user is reading when new messages are received. - * - * Don't call this method directly, instead, call `markScrolled`, - * which debounces this method. - */ - -function _markScrolled(ev) { - const el = ev.target; - - if (el.nodeName.toLowerCase() !== 'converse-chat-content') { - return; - } - - let scrolled = true; - const is_at_bottom = Math.floor(el.scrollTop) === 0; - const is_at_top = Math.ceil(el.clientHeight - el.scrollTop) >= el.scrollHeight - Math.ceil(el.scrollHeight / 20); - - if (is_at_bottom) { - scrolled = false; - onScrolledDown(el.model); - } else if (is_at_top) { - /** - * Triggered once the chat's message area has been scrolled to the top - * @event _converse#chatBoxScrolledUp - * @property { _converse.ChatBoxView | _converse.ChatRoomView } view - * @example _converse.api.listen.on('chatBoxScrolledUp', obj => { ... }); - */ - api.trigger('chatBoxScrolledUp', el); - } - - if (el.model.get('scolled') !== scrolled) { - el.model.ui.set({ - scrolled - }); - } -} - -const markScrolled = debounce_default()(ev => _markScrolled(ev), 50); -/** - * Given a message object, returns a TemplateResult indicating a new day if - * the passed in message is more than a day later than its predecessor. - * @param { _converse.Message } - */ - -function getDayIndicator(message) { - var _message$collection; - - const messages = (_message$collection = message.collection) === null || _message$collection === void 0 ? void 0 : _message$collection.models; - - if (!messages) { - return; - } - - const idx = messages.indexOf(message); - const prev_message = messages[idx - 1]; - - if (!prev_message || utils_dayjs(message.get('time')).isAfter(utils_dayjs(prev_message.get('time')), 'day')) { - const day_date = utils_dayjs(message.get('time')).startOf('day'); - return new_day({ - 'type': 'date', - 'time': day_date.toISOString(), - 'datestring': day_date.format("dddd MMM Do YYYY") - }); - } -} -function getHats(message) { - if (message.get('type') === 'groupchat') { - var _message$occupant; - - const allowed_hats = api.settings.get('muc_hats').filter(hat => hat).map(hat => hat.toLowerCase()); - let vcard_roles = []; - - if (allowed_hats.includes('vcard_roles')) { - vcard_roles = message.vcard ? message.vcard.get('role') : null; - vcard_roles = vcard_roles ? vcard_roles.split(',').filter(hat => hat).map(hat => ({ - title: hat - })) : []; - } - - const muc_role = message.occupant ? [message.occupant.get('role')] : []; - const muc_affiliation = message.occupant ? [message.occupant.get('affiliation')] : []; - const affiliation_role_hats = [...muc_role, ...muc_affiliation].filter(hat => hat).filter(hat => allowed_hats.includes(hat.toLowerCase())).map(hat => ({ - title: hat - })); - const hats = allowed_hats.includes('xep317') ? ((_message$occupant = message.occupant) === null || _message$occupant === void 0 ? void 0 : _message$occupant.get('hats')) || [] : []; - return [...hats, ...vcard_roles, ...affiliation_role_hats]; - } - - return []; -} -;// CONCATENATED MODULE: ./src/shared/chat/message.js - - - - - - - - - - - - - - - - - - - -const { - Strophe: chat_message_Strophe, - dayjs: message_dayjs -} = core_converse.env; -class Message extends CustomElement { - static get properties() { - return { - jid: { - type: String - }, - mid: { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - async initialize() { - await this.setModels(); - - if (!this.model) { - // Happen during tests due to a race condition - headless_log.error('Could not find module for converse-chat-message'); - return; - } - - this.listenTo(this.chatbox, 'change:first_unread_id', this.requestUpdate); - this.listenTo(this.model, 'change', this.requestUpdate); - this.model.vcard && this.listenTo(this.model.vcard, 'change', this.requestUpdate); - - if (this.model.get('type') === 'groupchat') { - if (this.model.occupant) { - this.listenTo(this.model.occupant, 'change', this.requestUpdate); - } else { - this.listenTo(this.model, 'occupantAdded', () => { - this.listenTo(this.model.occupant, 'change', this.requestUpdate); - }); - } - } - } - - async setModels() { - this.chatbox = await api.chatboxes.get(this.jid); - await this.chatbox.initialized; - await this.chatbox.messages.fetched; - this.model = this.chatbox.messages.get(this.mid); - this.model && this.requestUpdate(); - } - - render() { - if (!this.model) { - return ''; - } else if (this.show_spinner) { - return spinner(); - } else if (this.model.get('file') && this.model.get('upload') !== shared_converse.SUCCESS) { - return this.renderFileProgress(); - } else if (['error', 'info'].includes(this.model.get('type'))) { - return this.renderInfoMessage(); - } else { - return this.renderChatMessage(); - } - } - - getProps() { - return Object.assign(this.model.toJSON(), this.getDerivedMessageProps()); - } - - renderInfoMessage() { - return info_message(this); - } - - renderFileProgress() { - if (!this.model.file) { - // Can happen when file upload failed and page was reloaded - return ''; - } - - const i18n_uploading = __('Uploading file:'); - - const filename = this.model.file.name; - const size = filesize_min_default()(this.model.file.size); - return T` -
- ${renderAvatar(this.getAvatarData())} -
- ${i18n_uploading} ${filename}, ${size} - -
-
`; - } - - renderChatMessage() { - return templates_message(this, this.getProps()); - } - - shouldShowAvatar() { - return api.settings.get('show_message_avatar') && !this.model.isMeCommand() && this.type !== 'headline'; - } - - getAvatarData() { - var _this$model$vcard, _this$model$vcard2; - - const image_type = ((_this$model$vcard = this.model.vcard) === null || _this$model$vcard === void 0 ? void 0 : _this$model$vcard.get('image_type')) || shared_converse.DEFAULT_IMAGE_TYPE; - const image_data = ((_this$model$vcard2 = this.model.vcard) === null || _this$model$vcard2 === void 0 ? void 0 : _this$model$vcard2.get('image')) || shared_converse.DEFAULT_IMAGE; - const image = "data:" + image_type + ";base64," + image_data; - return { - 'classes': 'chat-msg__avatar', - 'height': 36, - 'width': 36, - image - }; - } - - onUnfurlAnimationEnd() { - if (this.model.get('url_preview_transition') === 'fade-out') { - this.model.save({ - 'hide_url_previews': !this.model.get('hide_url_previews'), - 'url_preview_transition': 'fade-in' - }); - } - } - - async onRetryClicked() { - this.show_spinner = true; - this.requestUpdate(); - await api.trigger(this.model.get('retry_event_id'), { - 'synchronous': true - }); - this.model.destroy(); - this.parentElement.removeChild(this); - } - - isRetracted() { - return this.model.get('retracted') || this.model.get('moderated') === 'retracted'; - } - - hasMentions() { - const is_groupchat = this.model.get('type') === 'groupchat'; - return is_groupchat && this.model.get('sender') === 'them' && this.chatbox.isUserMentioned(this.model); - } - - getOccupantAffiliation() { - var _this$model$occupant; - - return (_this$model$occupant = this.model.occupant) === null || _this$model$occupant === void 0 ? void 0 : _this$model$occupant.get('affiliation'); - } - - getOccupantRole() { - var _this$model$occupant2; - - return (_this$model$occupant2 = this.model.occupant) === null || _this$model$occupant2 === void 0 ? void 0 : _this$model$occupant2.get('role'); - } - - getExtraMessageClasses() { - const extra_classes = [this.model.isFollowup() ? 'chat-msg--followup' : null, this.model.get('is_delayed') ? 'delayed' : null, this.model.isMeCommand() ? 'chat-msg--action' : null, this.isRetracted() ? 'chat-msg--retracted' : null, this.model.get('type'), this.shouldShowAvatar() ? 'chat-msg--with-avatar' : null].map(c => c); - - if (this.model.get('type') === 'groupchat') { - extra_classes.push(this.getOccupantRole() ?? ''); - extra_classes.push(this.getOccupantAffiliation() ?? ''); - - if (this.model.get('sender') === 'them' && this.hasMentions()) { - extra_classes.push('mentioned'); - } - } - - this.model.get('correcting') && extra_classes.push('correcting'); - return extra_classes.filter(c => c).join(" "); - } - - getDerivedMessageProps() { - const format = api.settings.get('time_format'); - return { - 'pretty_time': message_dayjs(this.model.get('edited') || this.model.get('time')).format(format), - 'has_mentions': this.hasMentions(), - 'hats': getHats(this.model), - 'is_first_unread': this.chatbox.get('first_unread_id') === this.model.get('id'), - 'is_me_message': this.model.isMeCommand(), - 'is_retracted': this.isRetracted(), - 'username': this.model.getDisplayName(), - 'should_show_avatar': this.shouldShowAvatar() - }; - } - - getRetractionText() { - if (this.model.get('type') === 'groupchat' && this.model.get('moderated_by')) { - const retracted_by_mod = this.model.get('moderated_by'); - const chatbox = this.model.collection.chatbox; - - if (!this.model.mod) { - this.model.mod = chatbox.occupants.findOccupant({ - 'jid': retracted_by_mod - }) || chatbox.occupants.findOccupant({ - 'nick': chat_message_Strophe.getResourceFromJid(retracted_by_mod) - }); - } - - const modname = this.model.mod ? this.model.mod.getDisplayName() : 'A moderator'; - return __('%1$s has removed this message', modname); - } else { - return __('%1$s has removed this message', this.model.getDisplayName()); - } - } - - renderRetraction() { - const retraction_text = this.isRetracted() ? this.getRetractionText() : null; - return T` -
${retraction_text}
- ${this.model.get('moderation_reason') ? T`${this.model.get('moderation_reason')}` : ''} - `; - } - - renderMessageText() { - return message_text(this); - } - - showUserModal(ev) { - if (this.model.get('sender') === 'me') { - api.modal.show(shared_converse.ProfileModal, { - model: this.model - }, ev); - } else if (this.model.get('type') === 'groupchat') { - ev.preventDefault(); - api.modal.show(modals_occupant, { - 'model': this.model.occupant - }, ev); - } else { - ev.preventDefault(); - const chatbox = this.model.collection.chatbox; - api.modal.show(modals_user_details, { - model: chatbox - }, ev); - } - } - - showMessageVersionsModal(ev) { - ev.preventDefault(); - api.modal.show(modals_message_versions, { - 'model': this.model - }, ev); - } - - toggleSpoilerMessage(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - this.model.save({ - 'is_spoiler_visible': !this.model.get('is_spoiler_visible') - }); - } - -} -api.elements.define('converse-chat-message', Message); -;// CONCATENATED MODULE: ./src/shared/chat/message-history.js - - - - - - - -class MessageHistory extends CustomElement { - static get properties() { - return { - model: { - type: Object - }, - messages: { - type: Array - } - }; - } - - render() { - const msgs = this.messages; - - if (msgs.length) { - return repeat_c(msgs, m => m.get('id'), m => T`${this.renderMessage(m)}`); - } else { - return ''; - } - } - - renderMessage(model) { - if (model.get('dangling_retraction') || model.get('is_only_key')) { - return ''; - } - - const template_hook = model.get('template_hook'); - - if (typeof template_hook === 'string') { - const template_promise = api.hook(template_hook, model, ''); - return until_o(template_promise, ''); - } else { - const template = T``; - const day = getDayIndicator(model); - return day ? [day, template] : template; - } - } - -} -api.elements.define('converse-message-history', MessageHistory); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/shared/chat/styles/chat-content.scss -var chat_content = __webpack_require__(8269); -;// CONCATENATED MODULE: ./src/shared/chat/styles/chat-content.scss - - - - - - - - - - - -var chat_content_options = {}; - -chat_content_options.styleTagTransform = (styleTagTransform_default()); -chat_content_options.setAttributes = (setAttributesWithoutAttributes_default()); - - chat_content_options.insert = insertBySelector_default().bind(null, "head"); - -chat_content_options.domAPI = (styleDomAPI_default()); -chat_content_options.insertStyleElement = (insertStyleElement_default()); - -var chat_content_update = injectStylesIntoStyleTag_default()(chat_content/* default */.Z, chat_content_options); - - - - - /* harmony default export */ const styles_chat_content = (chat_content/* default */.Z && chat_content/* default.locals */.Z.locals ? chat_content/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/shared/chat/chat-content.js - - - - - - -class ChatContent extends CustomElement { - static get properties() { - return { - jid: { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - disconnectedCallback() { - super.disconnectedCallback(); - this.removeEventListener('scroll', markScrolled); - } - - async initialize() { - await this.setModels(); - this.listenTo(this.model, 'change:hidden_occupants', this.requestUpdate); - this.listenTo(this.model.messages, 'add', this.requestUpdate); - this.listenTo(this.model.messages, 'change', this.requestUpdate); - this.listenTo(this.model.messages, 'remove', this.requestUpdate); - this.listenTo(this.model.messages, 'rendered', this.requestUpdate); - this.listenTo(this.model.messages, 'reset', this.requestUpdate); - this.listenTo(this.model.notifications, 'change', this.requestUpdate); - this.listenTo(this.model.ui, 'change', this.requestUpdate); - this.listenTo(this.model.ui, 'change:scrolled', this.scrollDown); - - if (this.model.occupants) { - this.listenTo(this.model.occupants, 'change', this.requestUpdate); - } - - this.addEventListener('scroll', markScrolled); - } - - async setModels() { - this.model = await api.chatboxes.get(this.jid); - await this.model.initialized; - this.requestUpdate(); - } - - render() { - var _this$model$ui; - - if (!this.model) { - return ''; - } // This element has "flex-direction: reverse", so elements here are - // shown in reverse order. - - - return T` -
${this.model.getNotificationsText()}
- - - ${(_this$model$ui = this.model.ui) !== null && _this$model$ui !== void 0 && _this$model$ui.get('chat-content-spinner-top') ? T`` : ''} - `; - } - - scrollDown() { - if (this.model.ui.get('scrolled')) { - return; - } - - if (this.scrollTo) { - const behavior = this.scrollTop ? 'smooth' : 'auto'; - this.scrollTo({ - 'top': 0, - behavior - }); - } else { - this.scrollTop = 0; - } - /** - * Triggered once the converse-chat-content element has been scrolled down to the bottom. - * @event _converse#chatBoxScrolledDown - * @type {object} - * @property { _converse.ChatBox | _converse.ChatRoom } chatbox - The chat model - * @example _converse.api.listen.on('chatBoxScrolledDown', obj => { ... }); - */ - - - api.trigger('chatBoxScrolledDown', { - 'chatbox': this.model - }); - } - -} -api.elements.define('converse-chat-content', ChatContent); -;// CONCATENATED MODULE: ./node_modules/lit-html/directives/unsafe-html.js - - -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -class unsafe_html_n extends directive_s { - constructor(i) { - if (super(i), this.vt = A, i.type !== directive_t.CHILD) throw Error(this.constructor.directiveName + "() can only be used in child bindings"); - } - - render(r) { - if (r === A) return this.Vt = void 0, this.vt = r; - if (r === lit_html_w) return r; - if ("string" != typeof r) throw Error(this.constructor.directiveName + "() called with a non-string value"); - if (r === this.vt) return this.Vt; - this.vt = r; - const s = [r]; - return s.raw = s, this.Vt = { - _$litType$: this.constructor.resultType, - strings: s, - values: [] - }; - } - -} - -unsafe_html_n.directiveName = "unsafeHTML", unsafe_html_n.resultType = 1; -const unsafe_html_o = directive_i(unsafe_html_n); - -;// CONCATENATED MODULE: ./node_modules/lit/directives/unsafe-html.js - -;// CONCATENATED MODULE: ./src/shared/chat/help-messages.js - - - - - - -class ChatHelp extends CustomElement { - static get properties() { - return { - chat_type: { - type: String - }, - messages: { - type: Array - }, - model: { - type: Object - }, - type: { - type: String - } - }; - } - - render() { - const isodate = new Date().toISOString(); - return [T``, ...this.messages.map(m => this.renderHelpMessage({ - isodate, - 'markup': purify_default().sanitize(m, { - 'ALLOWED_TAGS': ['strong'] - }) - }))]; - } - - close() { - this.model.set({ - 'show_help_messages': false - }); - } - - renderHelpMessage(o) { - return T`
${unsafe_html_o(o.markup)}
`; - } - -} -api.elements.define('converse-chat-help', ChatHelp); -;// CONCATENATED MODULE: ./src/shared/chat/templates/emoji-picker.js - - - -const emoji_picker_u = core_converse.env.utils; - -const emoji_category = o => { - return T` -
  • - - ${o.emoji} -
  • - `; -}; - -const emoji_picker_header = o => { - const cats = api.settings.get('emoji_categories'); - - const transform = c => cats[c] ? emoji_category(Object.assign({ - 'category': c, - 'emoji': o.sn2Emoji(cats[c]) - }, o)) : ''; - - return T`
      ${Object.keys(cats).map(transform)}
    `; -}; - -const emoji_item = o => { - return T` -
  • - ${emoji_picker_u.shortnamesToEmojis(o.emoji.sn)} -
  • - `; -}; - -const tpl_search_results = o => { - const i18n_search_results = __('Search results'); - - return T` - - ${i18n_search_results} -
      - ${o.search_results.map(emoji => emoji_item(Object.assign({ - emoji - }, o)))} -
    -
    - `; -}; - -const emojis_for_category = o => { - return T` - ${__(api.settings.get('emoji_category_labels')[o.category])} -
      - ${Object.values(core_converse.emojis.json[o.category]).map(emoji => emoji_item(Object.assign({ - emoji - }, o)))} -
    `; -}; - -const tpl_all_emojis = o => { - const cats = api.settings.get('emoji_categories'); - return T` - - ${Object.keys(cats).map(c => cats[c] ? emojis_for_category(Object.assign({ - 'category': c - }, o)) : '')} - `; -}; - -const skintone_emoji = o => { - return T` -
  • - ${emoji_picker_u.shortnamesToEmojis(':' + o.skintone + ':')} -
  • `; -}; - -const tpl_emoji_picker = o => { - const i18n_search = __('Search'); - - const skintones = ['tone1', 'tone2', 'tone3', 'tone4', 'tone5']; - return T` -
    - - ${o.query ? '' : emoji_picker_header(o)} -
    - ${o.render_emojis ? T`` : ''} - -
    - -
      ${skintones.map(skintone => skintone_emoji(Object.assign({ - skintone - }, o)))}
    -
    `; -}; -;// CONCATENATED MODULE: ./src/shared/chat/emoji-picker-content.js - - - - -const { - sizzle: emoji_picker_content_sizzle -} = core_converse.env; -class EmojiPickerContent extends CustomElement { - static get properties() { - return { - 'chatview': { - type: Object - }, - 'search_results': { - type: Array - }, - 'current_skintone': { - type: String - }, - 'model': { - type: Object - }, - 'query': { - type: String - } - }; - } - - render() { - const props = { - 'current_skintone': this.current_skintone, - 'insertEmoji': ev => this.insertEmoji(ev), - 'query': this.query, - 'search_results': this.search_results, - 'shouldBeHidden': shortname => this.shouldBeHidden(shortname) - }; - return T` -
    - ${tpl_search_results(props)} - ${tpl_all_emojis(props)} -
    - `; - } - - firstUpdated() { - this.initIntersectionObserver(); - } - - initIntersectionObserver() { - if (!window.IntersectionObserver) { - return; - } - - if (this.observer) { - this.observer.disconnect(); - } else { - const options = { - root: this.querySelector('.emoji-picker__lists'), - threshold: [0.1] - }; - - const handler = ev => this.setCategoryOnVisibilityChange(ev); - - this.observer = new IntersectionObserver(handler, options); - } - - emoji_picker_content_sizzle('.emoji-picker', this).forEach(a => this.observer.observe(a)); - } - - setCategoryOnVisibilityChange(entries) { - const selected = this.parentElement.navigator.selected; - const intersection_with_selected = entries.filter(i => i.target.contains(selected)).pop(); - let current; // Choose the intersection that contains the currently selected - // element, or otherwise the one with the largest ratio. - - if (intersection_with_selected) { - current = intersection_with_selected; - } else { - current = entries.reduce((p, c) => c.intersectionRatio >= ((p === null || p === void 0 ? void 0 : p.intersectionRatio) || 0) ? c : p, null); - } - - if (current && current.isIntersecting) { - const category = current.target.getAttribute('data-category'); - - if (category !== this.model.get('current_category')) { - this.parentElement.preserve_scroll = true; - this.model.save({ - 'current_category': category - }); - } - } - } - - insertEmoji(ev) { - ev.preventDefault(); - ev.stopPropagation(); - const target = ev.target.nodeName === 'IMG' ? ev.target.parentElement : ev.target; - this.parentElement.insertIntoTextArea(target.getAttribute('data-emoji')); - } - - shouldBeHidden(shortname) { - // Helper method for the template which decides whether an - // emoji should be hidden, based on which skin tone is - // currently being applied. - if (shortname.includes('_tone')) { - if (!this.current_skintone || !shortname.includes(this.current_skintone)) { - return true; - } - } else { - if (this.current_skintone && core_converse.emojis.toned.includes(shortname)) { - return true; - } - } - - if (this.query && !shared_converse.FILTER_CONTAINS(shortname, this.query)) { - return true; - } - - return false; - } - -} -api.elements.define('converse-emoji-picker-content', EmojiPickerContent); -;// CONCATENATED MODULE: ./src/shared/chat/emoji-dropdown.js - - - - - - -const emoji_dropdown_u = core_converse.env.utils; -class EmojiDropdown extends Dropdown { - static get properties() { - return { - chatview: { - type: Object - } - }; - } - - constructor() { - super(); // This is an optimization, we lazily render the emoji picker, otherwise tests slow to a crawl. - - this.render_emojis = false; - } - - initModel() { - if (!this.init_promise) { - this.init_promise = (async () => { - await api.emojis.initialize(); - const id = `converse.emoji-${shared_converse.bare_jid}-${this.chatview.model.get('jid')}`; - this.model = new shared_converse.EmojiPicker({ - 'id': id - }); - initStorage(this.model, id); - await new Promise(resolve => this.model.fetch({ - 'success': resolve, - 'error': resolve - })); // We never want still be in the autocompleting state upon page load - - this.model.set({ - 'autocompleting': null, - 'ac_position': null - }); - })(); - } - - return this.init_promise; - } - - render() { - return T` -
    - - -
    `; - } - - connectedCallback() { - super.connectedCallback(); - this.render_emojis = false; - } - - toggleMenu(ev) { - ev.stopPropagation(); - ev.preventDefault(); - - if (emoji_dropdown_u.hasClass('show', this.menu)) { - if (emoji_dropdown_u.ancestor(ev.target, '.toggle-emojis')) { - this.hideMenu(); - } - } else { - this.showMenu(); - } - } - - async showMenu() { - await this.initModel(); - - if (!this.render_emojis) { - // Trigger an update so that emojis are rendered - this.render_emojis = true; - await this.requestUpdate(); - } - - super.showMenu(); - setTimeout(() => { - var _this$querySelector; - - return (_this$querySelector = this.querySelector('.emoji-search')) === null || _this$querySelector === void 0 ? void 0 : _this$querySelector.focus(); - }); - } - -} -api.elements.define('converse-emoji-dropdown', EmojiDropdown); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/shared/chat/styles/emoji.scss -var emoji = __webpack_require__(9796); -;// CONCATENATED MODULE: ./src/shared/chat/styles/emoji.scss - - - - - - - - - - - -var emoji_options = {}; - -emoji_options.styleTagTransform = (styleTagTransform_default()); -emoji_options.setAttributes = (setAttributesWithoutAttributes_default()); - - emoji_options.insert = insertBySelector_default().bind(null, "head"); - -emoji_options.domAPI = (styleDomAPI_default()); -emoji_options.insertStyleElement = (insertStyleElement_default()); - -var emoji_update = injectStylesIntoStyleTag_default()(emoji/* default */.Z, emoji_options); - - - - - /* harmony default export */ const styles_emoji = (emoji/* default */.Z && emoji/* default.locals */.Z.locals ? emoji/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/shared/chat/emoji-picker.js - - - - - - - - -const chat_emoji_picker_u = core_converse.env.utils; -class EmojiPicker extends CustomElement { - static get properties() { - return { - 'chatview': { - type: Object - }, - 'current_category': { - type: String, - 'reflect': true - }, - 'current_skintone': { - type: String, - 'reflect': true - }, - 'model': { - type: Object - }, - 'query': { - type: String, - 'reflet': true - }, - // This is an optimization, we lazily render the emoji picker, otherwise tests slow to a crawl. - 'render_emojis': { - type: Boolean - } - }; - } - - firstUpdated() { - super.firstUpdated(); - this.listenTo(this.model, 'change', o => this.onModelChanged(o.changed)); - this.initArrowNavigation(); - } - - constructor() { - super(); - this._search_results = []; - this.debouncedFilter = lodash_es_debounce(input => this.model.set({ - 'query': input.value - }), 250); - } - - get search_results() { - return this._search_results; - } - - set search_results(value) { - this._search_results = value; - this.requestUpdate(); - } - - render() { - return tpl_emoji_picker({ - 'chatview': this.chatview, - 'current_category': this.current_category, - 'current_skintone': this.current_skintone, - 'model': this.model, - 'onCategoryPicked': ev => this.chooseCategory(ev), - 'onSearchInputBlurred': ev => this.chatview.emitFocused(ev), - 'onSearchInputFocus': ev => this.onSearchInputFocus(ev), - 'onSearchInputKeyDown': ev => this.onKeyDown(ev), - 'onSkintonePicked': ev => this.chooseSkinTone(ev), - 'query': this.query, - 'search_results': this.search_results, - 'render_emojis': this.render_emojis, - 'sn2Emoji': shortname => chat_emoji_picker_u.shortnamesToEmojis(this.getTonedShortname(shortname)) - }); - } - - updated(changed) { - changed.has('query') && this.updateSearchResults(changed); - changed.has('current_category') && this.setScrollPosition(); - } - - onModelChanged(changed) { - if ('current_category' in changed) this.current_category = changed.current_category; - if ('current_skintone' in changed) this.current_skintone = changed.current_skintone; - if ('query' in changed) this.query = changed.query; - } - - setScrollPosition() { - if (this.preserve_scroll) { - this.preserve_scroll = false; - return; - } - - const el = this.querySelector('.emoji-lists__container--browse'); - const heading = this.querySelector(`#emoji-picker-${this.current_category}`); - - if (heading) { - // +4 due to 2px padding on list elements - el.scrollTop = heading.offsetTop - heading.offsetHeight * 3 + 4; - } - } - - updateSearchResults(changed) { - const old_query = changed.get('query'); - const contains = shared_converse.FILTER_CONTAINS; - - if (this.query) { - if (this.query === old_query) { - return this.search_results; - } else if (old_query && this.query.includes(old_query)) { - this.search_results = this.search_results.filter(e => contains(e.sn, this.query)); - } else { - this.search_results = core_converse.emojis.list.filter(e => contains(e.sn, this.query)); - } - } else if (this.search_results.length) { - // Avoid re-rendering by only setting to new empty array if it wasn't empty before - this.search_results = []; - } - - this.requestUpdate(); - } - - registerEvents() { - this.onGlobalKeyDown = ev => this._onGlobalKeyDown(ev); - - const body = document.querySelector('body'); - body.addEventListener('keydown', this.onGlobalKeyDown); - } - - connectedCallback() { - super.connectedCallback(); - this.registerEvents(); - } - - disconnectedCallback() { - const body = document.querySelector('body'); - body.removeEventListener('keydown', this.onGlobalKeyDown); - super.disconnectedCallback(); - } - - _onGlobalKeyDown(ev) { - if (!this.navigator) { - return; - } - - if (ev.keyCode === core_converse.keycodes.ENTER && this.navigator.selected && chat_emoji_picker_u.isVisible(this)) { - this.onEnterPressed(ev); - } else if (ev.keyCode === core_converse.keycodes.DOWN_ARROW && !this.navigator.enabled && chat_emoji_picker_u.isVisible(this)) { - this.enableArrowNavigation(ev); - } - } - - setCategoryForElement(el) { - const old_category = this.current_category; - const category = (el === null || el === void 0 ? void 0 : el.getAttribute('data-category')) || old_category; - - if (old_category !== category) { - this.model.save({ - 'current_category': category - }); - } - } - - insertIntoTextArea(value) { - const autocompleting = this.model.get('autocompleting'); - const ac_position = this.model.get('ac_position'); - this.chatview.getMessageForm().insertIntoTextArea(value, autocompleting, false, ac_position); - this.model.set({ - 'autocompleting': null, - 'query': '', - 'ac_position': null - }); - } - - chooseSkinTone(ev) { - ev.preventDefault(); - ev.stopPropagation(); - const target = ev.target.nodeName === 'IMG' ? ev.target.parentElement : ev.target; - const skintone = target.getAttribute("data-skintone").trim(); - - if (this.current_skintone === skintone) { - this.model.save({ - 'current_skintone': '' - }); - } else { - this.model.save({ - 'current_skintone': skintone - }); - } - } - - chooseCategory(ev) { - ev.preventDefault && ev.preventDefault(); - ev.stopPropagation && ev.stopPropagation(); - const el = ev.target.matches('li') ? ev.target : chat_emoji_picker_u.ancestor(ev.target, 'li'); - this.setCategoryForElement(el); - this.navigator.select(el); - !this.navigator.enabled && this.navigator.enable(); - } - - onKeyDown(ev) { - if (ev.keyCode === core_converse.keycodes.TAB) { - if (ev.target.value) { - ev.preventDefault(); - const match = core_converse.emojis.shortnames.find(sn => shared_converse.FILTER_CONTAINS(sn, ev.target.value)); - match && this.model.set({ - 'query': match - }); - } else if (!this.navigator.enabled) { - this.enableArrowNavigation(ev); - } - } else if (ev.keyCode === core_converse.keycodes.DOWN_ARROW && !this.navigator.enabled) { - this.enableArrowNavigation(ev); - } else if (ev.keyCode === core_converse.keycodes.ENTER) { - this.onEnterPressed(ev); - } else if (ev.keyCode === core_converse.keycodes.ESCAPE) { - chat_emoji_picker_u.ancestor(this, 'converse-emoji-dropdown').hideMenu(); - this.chatview.el.querySelector('.chat-textarea').focus(); - ev.stopPropagation(); - ev.preventDefault(); - } else if (ev.keyCode !== core_converse.keycodes.ENTER && ev.keyCode !== core_converse.keycodes.DOWN_ARROW) { - this.debouncedFilter(ev.target); - } - } - - onEnterPressed(ev) { - if (ev.emoji_keypress_handled) { - // Prevent the emoji from being inserted a 2nd time due to this - // method being called by two event handlers: onKeyDown and _onGlobalKeyDown - return; - } - - ev.preventDefault(); - ev.stopPropagation(); - ev.emoji_keypress_handled = true; - - if (core_converse.emojis.shortnames.includes(ev.target.value)) { - this.insertIntoTextArea(ev.target.value); - } else if (this.search_results.length === 1) { - this.insertIntoTextArea(this.search_results[0].sn); - } else if (this.navigator.selected && this.navigator.selected.matches('.insert-emoji')) { - this.insertIntoTextArea(this.navigator.selected.getAttribute('data-emoji')); - } else if (this.navigator.selected && this.navigator.selected.matches('.emoji-category')) { - this.chooseCategory({ - 'target': this.navigator.selected - }); - } - } - - onSearchInputFocus(ev) { - this.chatview.emitBlurred(ev); - this.disableArrowNavigation(); - } - - getTonedShortname(shortname) { - if (core_converse.emojis.toned.includes(shortname) && this.current_skintone) { - return `${shortname.slice(0, shortname.length - 1)}_${this.current_skintone}:`; - } - - return shortname; - } - - initArrowNavigation() { - if (!this.navigator) { - const default_selector = 'li:not(.hidden):not(.emoji-skintone), .emoji-search'; - const options = { - 'jump_to_picked': '.emoji-category', - 'jump_to_picked_selector': '.emoji-category.picked', - 'jump_to_picked_direction': dom_navigator.DIRECTION.down, - 'picked_selector': '.picked', - 'scroll_container': this.querySelector('.emoji-picker__lists'), - 'getSelector': direction => { - if (direction === dom_navigator.DIRECTION.down) { - const c = this.navigator.selected && this.navigator.selected.getAttribute('data-category'); - return c ? `ul[data-category="${c}"] li:not(.hidden):not(.emoji-skintone), .emoji-search` : default_selector; - } else { - return default_selector; - } - }, - 'onSelected': el => { - el.matches('.insert-emoji') && this.setCategoryForElement(el.parentElement); - el.matches('.insert-emoji, .emoji-category') && el.firstElementChild.focus(); - el.matches('.emoji-search') && el.focus(); - } - }; - this.navigator = new dom_navigator(this, options); - } - } - - disableArrowNavigation() { - this.navigator.disable(); - } - - enableArrowNavigation(ev) { - var _ev$preventDefault, _ev$stopPropagation; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation = ev.stopPropagation) === null || _ev$stopPropagation === void 0 ? void 0 : _ev$stopPropagation.call(ev); - this.disableArrowNavigation(); - this.navigator.enable(); - this.navigator.handleKeydown(ev); - } - -} -api.elements.define('converse-emoji-picker', EmojiPicker); -;// CONCATENATED MODULE: ./src/shared/chat/templates/message-limit.js - - -/* harmony default export */ const message_limit = (counter => { - const i18n_chars_remaining = __('Message characters remaining'); - - return T`${counter}`; -}); -;// CONCATENATED MODULE: ./src/shared/chat/message-limit.js - - - -class MessageLimitIndicator extends CustomElement { - static get properties() { - return { - model: { - type: Object - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.listenTo(this.model, 'change:draft', this.requestUpdate); - } - - render() { - const limit = api.settings.get('message_limit'); - if (!limit) return ''; - const chars = this.model.get('draft') || ''; - return message_limit(limit - chars.length); - } - -} -api.elements.define('converse-message-limit-indicator', MessageLimitIndicator); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/shared/chat/styles/toolbar.scss -var toolbar = __webpack_require__(7991); -;// CONCATENATED MODULE: ./src/shared/chat/styles/toolbar.scss - - - - - - - - - - - -var toolbar_options = {}; - -toolbar_options.styleTagTransform = (styleTagTransform_default()); -toolbar_options.setAttributes = (setAttributesWithoutAttributes_default()); - - toolbar_options.insert = insertBySelector_default().bind(null, "head"); - -toolbar_options.domAPI = (styleDomAPI_default()); -toolbar_options.insertStyleElement = (insertStyleElement_default()); - -var toolbar_update = injectStylesIntoStyleTag_default()(toolbar/* default */.Z, toolbar_options); - - - - - /* harmony default export */ const styles_toolbar = (toolbar/* default */.Z && toolbar/* default.locals */.Z.locals ? toolbar/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/shared/chat/toolbar.js - - - - - - - - -const toolbar_Strophe = core_converse.env.Strophe; -class ChatToolbar extends CustomElement { - static get properties() { - return { - composing_spoiler: { - type: Boolean - }, - hidden_occupants: { - type: Boolean - }, - is_groupchat: { - type: Boolean - }, - message_limit: { - type: Number - }, - model: { - type: Object - }, - show_call_button: { - type: Boolean - }, - show_emoji_button: { - type: Boolean - }, - show_send_button: { - type: Boolean - }, - show_spoiler_button: { - type: Boolean - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.listenTo(this.model, 'change:composing_spoiler', this.requestUpdate); - } - - render() { - const i18n_send_message = __('Send the message'); - - return T` - ${until_o(this.getButtons(), '')} - ${this.show_send_button ? T`` : ''} - `; - } - - firstUpdated() { - /** - * Triggered once the _converse.ChatBoxView's toolbar has been rendered - * @event _converse#renderToolbar - * @type { _converse.ChatBoxView } - * @example _converse.api.listen.on('renderToolbar', this => { ... }); - */ - api.trigger('renderToolbar', this); - } - - getButtons() { - var _api$settings$get; - - const buttons = []; - - if (this.show_emoji_button) { - const chatview = shared_converse.chatboxviews.get(this.model.get('jid')); - - buttons.push(T``); - } - - if (this.show_call_button) { - const i18n_start_call = __('Start a call'); - - buttons.push(T` - `); - } - - const message_limit = api.settings.get('message_limit'); - - if (message_limit) { - buttons.push(T` - - `); - } - - if (this.show_spoiler_button) { - buttons.push(this.getSpoilerButton()); - } - - const http_upload_promise = api.disco.supports(toolbar_Strophe.NS.HTTPUPLOAD, shared_converse.domain); - buttons.push(T`${until_o(http_upload_promise.then(is_supported => this.getHTTPUploadButton(is_supported)), '')}`); - - if (this.is_groupchat && (_api$settings$get = api.settings.get('visible_toolbar_buttons')) !== null && _api$settings$get !== void 0 && _api$settings$get.toggle_occupants) { - const i18n_hide_occupants = __('Hide participants'); - - const i18n_show_occupants = __('Show participants'); - - buttons.push(T` - `); - } - /** - * *Hook* which allows plugins to add more buttons to a chat's toolbar - * @event _converse#getToolbarButtons - * @example - * api.listen.on('getToolbarButtons', (toolbar_el, buttons) { - * buttons.push(html` - * ` - * ); - * return buttons; - * } - */ - - - return shared_converse.api.hook('getToolbarButtons', this, buttons); - } - - getHTTPUploadButton(is_supported) { - if (is_supported) { - const i18n_choose_file = __('Choose a file to send'); - - return T` - - `; - } else { - return ''; - } - } - - getSpoilerButton() { - var _model$presence; - - const model = this.model; - - if (!this.is_groupchat && !((_model$presence = model.presence) !== null && _model$presence !== void 0 && _model$presence.resources.length)) { - return; - } - - let i18n_toggle_spoiler; - - if (this.composing_spoiler) { - i18n_toggle_spoiler = __("Click to write as a normal (non-spoiler) message"); - } else { - i18n_toggle_spoiler = __("Click to write your message as a spoiler"); - } - - const markup = T` - `; - - if (this.is_groupchat) { - return markup; - } else { - const contact_jid = model.get('jid'); - const spoilers_promise = Promise.all(model.presence.resources.map(r => api.disco.supports(toolbar_Strophe.NS.SPOILER, `${contact_jid}/${r.get('name')}`))).then(results => results.reduce((acc, val) => acc && val, true)); - return T`${until_o(spoilers_promise.then(() => markup), '')}`; - } - } - - toggleFileUpload(ev) { - var _ev$preventDefault, _ev$stopPropagation; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation = ev.stopPropagation) === null || _ev$stopPropagation === void 0 ? void 0 : _ev$stopPropagation.call(ev); - this.querySelector('.fileupload').click(); - } - - onFileSelection(evt) { - this.model.sendFiles(evt.target.files); - } - - toggleComposeSpoilerMessage(ev) { - var _ev$preventDefault2, _ev$stopPropagation2; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault2 = ev.preventDefault) === null || _ev$preventDefault2 === void 0 ? void 0 : _ev$preventDefault2.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation2 = ev.stopPropagation) === null || _ev$stopPropagation2 === void 0 ? void 0 : _ev$stopPropagation2.call(ev); - this.model.set('composing_spoiler', !this.model.get('composing_spoiler')); - } - - toggleOccupants(ev) { - var _ev$preventDefault3, _ev$stopPropagation3; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault3 = ev.preventDefault) === null || _ev$preventDefault3 === void 0 ? void 0 : _ev$preventDefault3.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation3 = ev.stopPropagation) === null || _ev$stopPropagation3 === void 0 ? void 0 : _ev$stopPropagation3.call(ev); - this.model.save({ - 'hidden_occupants': !this.model.get('hidden_occupants') - }); - } - - toggleCall(ev) { - var _ev$preventDefault4, _ev$stopPropagation4; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault4 = ev.preventDefault) === null || _ev$preventDefault4 === void 0 ? void 0 : _ev$preventDefault4.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation4 = ev.stopPropagation) === null || _ev$stopPropagation4 === void 0 ? void 0 : _ev$stopPropagation4.call(ev); - /** - * When a call button (i.e. with class .toggle-call) on a chatbox has been clicked. - * @event _converse#callButtonClicked - * @type { object } - * @property { Strophe.Connection } _converse.connection - The XMPP Connection object - * @property { _converse.ChatBox | _converse.ChatRoom } _converse.connection - The XMPP Connection object - * @example _converse.api.listen.on('callButtonClicked', (connection, model) => { ... }); - */ - - api.trigger('callButtonClicked', { - connection: shared_converse.connection, - model: this.model - }); - } - -} -window.customElements.define('converse-chat-toolbar', ChatToolbar); -;// CONCATENATED MODULE: ./src/plugins/chatview/utils.js - - - -function clearHistory(jid) { - if (shared_converse.router.history.getFragment() === `converse/chat?jid=${jid}`) { - shared_converse.router.navigate(''); - } -} -async function getHeadingDropdownItem(promise_or_data) { - const data = await promise_or_data; - return T` - - - ${data.i18n_text} - - `; -} -async function getHeadingStandaloneButton(promise_or_data) { - const data = await promise_or_data; - return T` - - `; -} -async function clearMessages(chat) { - const result = confirm(__('Are you sure you want to clear the messages from this conversation?')); - - if (result === true) { - await chat.clearMessages(); - } -} -function parseMessageForCommands(chat, text) { - const match = text.replace(/^\s*/, '').match(/^\/(.*)\s*$/); - - if (match) { - if (match[1] === 'clear') { - clearMessages(chat); - return true; - } else if (match[1] === 'close') { - var _converse$chatboxview; - - (_converse$chatboxview = shared_converse.chatboxviews.get(chat.get('jid'))) === null || _converse$chatboxview === void 0 ? void 0 : _converse$chatboxview.close(); - return true; - } else if (match[1] === 'help') { - chat.set({ - 'show_help_messages': false - }, { - 'silent': true - }); - chat.set({ - 'show_help_messages': true - }); - return true; - } - } -} -function resetElementHeight(ev) { - if (ev.target.value) { - const height = ev.target.scrollHeight + 'px'; - - if (ev.target.style.height != height) { - ev.target.style.height = 'auto'; - ev.target.style.height = height; - } - } else { - ev.target.style = ''; - } -} -;// CONCATENATED MODULE: ./src/plugins/chatview/templates/chat-head.js - - - - - - - -async function getStandaloneButtons(promise) { - const heading_btns = await promise; - const standalone_btns = heading_btns.filter(b => b.standalone); - return standalone_btns.map(b => getHeadingStandaloneButton(b)); -} - -async function getDropdownButtons(promise) { - const heading_btns = await promise; - const dropdown_btns = heading_btns.filter(b => !b.standalone); - return dropdown_btns.map(b => getHeadingDropdownItem(b)); -} - -/* harmony default export */ const chat_head = (o => { - var _o$model; - - const vcard = (_o$model = o.model) === null || _o$model === void 0 ? void 0 : _o$model.vcard; - const vcard_json = vcard ? vcard.toJSON() : {}; - - const i18n_profile = __("The User's Profile Image"); - - const avatar_data = Object.assign({ - 'alt_text': i18n_profile, - 'extra_classes': '', - 'height': 40, - 'width': 40 - }, vcard_json); - const avatar = T`${renderAvatar(avatar_data)}`; - const display_name = o.model.getDisplayName(); - - const tpl_dropdown_btns = () => getDropdownButtons(o.heading_buttons_promise).then(btns => btns.length ? T`` : ''); - - const tpl_standalone_btns = () => getStandaloneButtons(o.heading_buttons_promise).then(btns => btns.reverse().map(b => until_o(b, ''))); - - return T` -
    -
    - ${!shared_converse.api.settings.get("singleton") ? T`` : ''} - ${o.type !== shared_converse.HEADLINES_TYPE ? T`${avatar}` : ''} -
    - ${o.type !== shared_converse.HEADLINES_TYPE ? T`${display_name}` : display_name} -
    -
    -
    - ${until_o(tpl_dropdown_btns(), '')} - ${until_o(tpl_standalone_btns(), '')} -
    -
    - ${o.status ? T`

    ${o.status}

    ` : ''} - `; -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/chatview/styles/chat-head.scss -var styles_chat_head = __webpack_require__(6220); -;// CONCATENATED MODULE: ./src/plugins/chatview/styles/chat-head.scss - - - - - - - - - - - -var chat_head_options = {}; - -chat_head_options.styleTagTransform = (styleTagTransform_default()); -chat_head_options.setAttributes = (setAttributesWithoutAttributes_default()); - - chat_head_options.insert = insertBySelector_default().bind(null, "head"); - -chat_head_options.domAPI = (styleDomAPI_default()); -chat_head_options.insertStyleElement = (insertStyleElement_default()); - -var chat_head_update = injectStylesIntoStyleTag_default()(styles_chat_head/* default */.Z, chat_head_options); - - - - - /* harmony default export */ const chatview_styles_chat_head = (styles_chat_head/* default */.Z && styles_chat_head/* default.locals */.Z.locals ? styles_chat_head/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/chatview/heading.js - - - - - - -class ChatHeading extends CustomElement { - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - initialize() { - var _this$model$rosterCon; - - this.model = shared_converse.chatboxes.get(this.getAttribute('jid')); - this.listenTo(this.model, 'change:status', this.requestUpdate); - this.listenTo(this.model, 'vcard:change', this.requestUpdate); - - if (this.model.contact) { - this.listenTo(this.model.contact, 'destroy', this.requestUpdate); - } - - (_this$model$rosterCon = this.model.rosterContactAdded) === null || _this$model$rosterCon === void 0 ? void 0 : _this$model$rosterCon.then(() => { - this.listenTo(this.model.contact, 'change:nickname', this.requestUpdate); - this.requestUpdate(); - }); - } - - render() { - return chat_head(Object.assign(this.model.toJSON(), { - 'heading_buttons_promise': this.getHeadingButtons(), - 'model': this.model, - 'showUserDetailsModal': ev => this.showUserDetailsModal(ev) - })); - } - - showUserDetailsModal(ev) { - ev.preventDefault(); - api.modal.show(modals_user_details, { - model: this.model - }, ev); - } - - close(ev) { - ev.preventDefault(); - this.model.close(); - } - /** - * Returns a list of objects which represent buttons for the chat's header. - * @async - * @emits _converse#getHeadingButtons - */ - - - getHeadingButtons() { - const buttons = [{ - 'a_class': 'show-user-details-modal', - 'handler': ev => this.showUserDetailsModal(ev), - 'i18n_text': __('Details'), - 'i18n_title': __('See more information about this person'), - 'icon_class': 'fa-id-card', - 'name': 'details', - 'standalone': api.settings.get('view_mode') === 'overlayed' - }]; - - if (!api.settings.get('singleton')) { - buttons.push({ - 'a_class': 'close-chatbox-button', - 'handler': ev => this.close(ev), - 'i18n_text': __('Close'), - 'i18n_title': __('Close and end this conversation'), - 'icon_class': 'fa-times', - 'name': 'close', - 'standalone': api.settings.get('view_mode') === 'overlayed' - }); - } - /** - * *Hook* which allows plugins to add more buttons to a chat's heading. - * @event _converse#getHeadingButtons - * @example - * api.listen.on('getHeadingButtons', (view, buttons) => { - * buttons.push({ - * 'i18n_title': __('Foo'), - * 'i18n_text': __('Foo Bar'), - * 'handler': ev => alert('Foo!'), - * 'a_class': 'toggle-foo', - * 'icon_class': 'fa-foo', - * 'name': 'foo' - * }); - * return buttons; - * }); - */ - - - const chatview = shared_converse.chatboxviews.get(this.getAttribute('jid')); - - if (chatview) { - return shared_converse.api.hook('getHeadingButtons', chatview, buttons); - } else { - return buttons; // Happens during tests - } - } - -} -api.elements.define('converse-chat-heading', ChatHeading); -;// CONCATENATED MODULE: ./src/plugins/chatview/templates/message-form.js - - - - -/* harmony default export */ const message_form = (o => { - const label_message = o.composing_spoiler ? __('Hidden message') : __('Message'); - - const label_spoiler_hint = __('Optional hint'); - - const show_send_button = api.settings.get('show_send_button'); - return T` -
    - - -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/chatview/message-form.js - - - - - -const { - u: message_form_u -} = core_converse.env; -class MessageForm extends ElementView { - async connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.getAttribute('jid')); - await this.model.initialized; - this.listenTo(this.model.messages, 'change:correcting', this.onMessageCorrecting); - this.render(); - } - - toHTML() { - var _this$querySelector, _this$querySelector2; - - return message_form(Object.assign(this.model.toJSON(), { - 'onDrop': ev => this.onDrop(ev), - 'hint_value': (_this$querySelector = this.querySelector('.spoiler-hint')) === null || _this$querySelector === void 0 ? void 0 : _this$querySelector.value, - 'message_value': (_this$querySelector2 = this.querySelector('.chat-textarea')) === null || _this$querySelector2 === void 0 ? void 0 : _this$querySelector2.value, - 'onChange': ev => this.model.set({ - 'draft': ev.target.value - }), - 'onKeyDown': ev => this.onKeyDown(ev), - 'onKeyUp': ev => this.onKeyUp(ev), - 'onPaste': ev => this.onPaste(ev), - 'viewUnreadMessages': ev => this.viewUnreadMessages(ev) - })); - } - /** - * Insert a particular string value into the textarea of this chat box. - * @param {string} value - The value to be inserted. - * @param {(boolean|string)} [replace] - Whether an existing value - * should be replaced. If set to `true`, the entire textarea will - * be replaced with the new value. If set to a string, then only - * that string will be replaced *if* a position is also specified. - * @param {integer} [position] - The end index of the string to be - * replaced with the new value. - */ - - - insertIntoTextArea(value, replace = false, correcting = false, position) { - const textarea = this.querySelector('.chat-textarea'); - - if (correcting) { - message_form_u.addClass('correcting', textarea); - } else { - message_form_u.removeClass('correcting', textarea); - } - - if (replace) { - if (position && typeof replace == 'string') { - textarea.value = textarea.value.replace(new RegExp(replace, 'g'), (match, offset) => offset == position - replace.length ? value + ' ' : match); - } else { - textarea.value = value; - } - } else { - let existing = textarea.value; - - if (existing && existing[existing.length - 1] !== ' ') { - existing = existing + ' '; - } - - textarea.value = existing + value + ' '; - } - - const ev = document.createEvent('HTMLEvents'); - ev.initEvent('change', false, true); - textarea.dispatchEvent(ev); - message_form_u.placeCaretAtEnd(textarea); - } - - onMessageCorrecting(message) { - if (message.get('correcting')) { - this.insertIntoTextArea(message_form_u.prefixMentions(message), true, true); - } else { - const currently_correcting = this.model.messages.findWhere('correcting'); - - if (currently_correcting && currently_correcting !== message) { - this.insertIntoTextArea(message_form_u.prefixMentions(message), true, true); - } else { - this.insertIntoTextArea('', true, false); - } - } - } - - onEscapePressed(ev) { - ev.preventDefault(); - const idx = this.model.messages.findLastIndex('correcting'); - const message = idx >= 0 ? this.model.messages.at(idx) : null; - - if (message) { - message.save('correcting', false); - } - - this.insertIntoTextArea('', true, false); - } - - onPaste(ev) { - ev.stopPropagation(); - - if (ev.clipboardData.files.length !== 0) { - ev.preventDefault(); // Workaround for quirk in at least Firefox 60.7 ESR: - // It seems that pasted files disappear from the event payload after - // the event has finished, which apparently happens during async - // processing in sendFiles(). So we copy the array here. - - this.model.sendFiles(Array.from(ev.clipboardData.files)); - return; - } - - this.model.set({ - 'draft': ev.clipboardData.getData('text/plain') - }); - } - - onKeyUp(ev) { - this.model.set({ - 'draft': ev.target.value - }); - } - - onKeyDown(ev) { - if (ev.ctrlKey) { - // When ctrl is pressed, no chars are entered into the textarea. - return; - } - - if (!ev.shiftKey && !ev.altKey && !ev.metaKey) { - if (ev.keyCode === core_converse.keycodes.TAB) { - const value = message_form_u.getCurrentWord(ev.target, null, /(:.*?:)/g); - - if (value.startsWith(':')) { - ev.preventDefault(); - ev.stopPropagation(); - this.model.trigger('emoji-picker-autocomplete', ev.target, value); - } - } else if (ev.keyCode === core_converse.keycodes.FORWARD_SLASH) { - // Forward slash is used to run commands. Nothing to do here. - return; - } else if (ev.keyCode === core_converse.keycodes.ESCAPE) { - return this.onEscapePressed(ev, this); - } else if (ev.keyCode === core_converse.keycodes.ENTER) { - return this.onFormSubmitted(ev); - } else if (ev.keyCode === core_converse.keycodes.UP_ARROW && !ev.target.selectionEnd) { - const textarea = this.querySelector('.chat-textarea'); - - if (!textarea.value || message_form_u.hasClass('correcting', textarea)) { - return this.model.editEarlierMessage(); - } - } else if (ev.keyCode === core_converse.keycodes.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length && message_form_u.hasClass('correcting', this.querySelector('.chat-textarea'))) { - return this.model.editLaterMessage(); - } - } - - if ([core_converse.keycodes.SHIFT, core_converse.keycodes.META, core_converse.keycodes.META_RIGHT, core_converse.keycodes.ESCAPE, core_converse.keycodes.ALT].includes(ev.keyCode)) { - return; - } - - if (this.model.get('chat_state') !== shared_converse.COMPOSING) { - // Set chat state to composing if keyCode is not a forward-slash - // (which would imply an internal command and not a message). - this.model.setChatState(shared_converse.COMPOSING); - } - } - - parseMessageForCommands(text) { - // Wrap util so that we can override in the MUC message-form component - return parseMessageForCommands(this.model, text); - } - - async onFormSubmitted(ev) { - var _ev$preventDefault, _this$querySelector3; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - const textarea = this.querySelector('.chat-textarea'); - const message_text = textarea.value.trim(); - - if (api.settings.get('message_limit') && message_text.length > api.settings.get('message_limit') || !message_text.replace(/\s/g, '').length) { - return; - } - - if (!shared_converse.connection.authenticated) { - const err_msg = __('Sorry, the connection has been lost, and your message could not be sent'); - - api.alert('error', __('Error'), err_msg); - api.connection.reconnect(); - return; - } - - let spoiler_hint, - hint_el = {}; - - if (this.model.get('composing_spoiler')) { - hint_el = this.querySelector('form.sendXMPPMessage input.spoiler-hint'); - spoiler_hint = hint_el.value; - } - - message_form_u.addClass('disabled', textarea); - textarea.setAttribute('disabled', 'disabled'); - (_this$querySelector3 = this.querySelector('converse-emoji-dropdown')) === null || _this$querySelector3 === void 0 ? void 0 : _this$querySelector3.hideMenu(); - const is_command = this.parseMessageForCommands(message_text); - const message = is_command ? null : await this.model.sendMessage({ - 'body': message_text, - spoiler_hint - }); - - if (is_command || message) { - hint_el.value = ''; - textarea.value = ''; - message_form_u.removeClass('correcting', textarea); - textarea.style.height = 'auto'; - this.model.set({ - 'draft': '' - }); - } - - if (api.settings.get('view_mode') === 'overlayed') { - // XXX: Chrome flexbug workaround. The .chat-content area - // doesn't resize when the textarea is resized to its original size. - const chatview = shared_converse.chatboxviews.get(this.getAttribute('jid')); - - const msgs_container = chatview.querySelector('.chat-content__messages'); - msgs_container.parentElement.style.display = 'none'; - } - - textarea.removeAttribute('disabled'); - message_form_u.removeClass('disabled', textarea); - - if (api.settings.get('view_mode') === 'overlayed') { - // XXX: Chrome flexbug workaround. - const chatview = shared_converse.chatboxviews.get(this.getAttribute('jid')); - - const msgs_container = chatview.querySelector('.chat-content__messages'); - msgs_container.parentElement.style.display = ''; - } // Suppress events, otherwise superfluous CSN gets set - // immediately after the message, causing rate-limiting issues. - - - this.model.setChatState(shared_converse.ACTIVE, { - 'silent': true - }); - textarea.focus(); - } - -} -api.elements.define('converse-message-form', MessageForm); -;// CONCATENATED MODULE: ./src/plugins/chatview/templates/bottom-panel.js - - - -/* harmony default export */ const bottom_panel = (o => { - const unread_msgs = __('You have unread messages'); - - const message_limit = api.settings.get('message_limit'); - const show_call_button = api.settings.get('visible_toolbar_buttons').call; - const show_emoji_button = api.settings.get('visible_toolbar_buttons').emoji; - const show_send_button = api.settings.get('show_send_button'); - const show_spoiler_button = api.settings.get('visible_toolbar_buttons').spoiler; - const show_toolbar = api.settings.get('show_toolbar'); - return T` - ${o.model.ui.get('scrolled') && o.model.get('num_unread') ? T`
    o.viewUnreadMessages(ev)}>▼ ${unread_msgs} ▼
    ` : ''} - ${api.settings.get('show_toolbar') ? T` - ` : ''} - - `; -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/chatview/styles/chat-bottom-panel.scss -var chat_bottom_panel = __webpack_require__(4639); -;// CONCATENATED MODULE: ./src/plugins/chatview/styles/chat-bottom-panel.scss - - - - - - - - - - - -var chat_bottom_panel_options = {}; - -chat_bottom_panel_options.styleTagTransform = (styleTagTransform_default()); -chat_bottom_panel_options.setAttributes = (setAttributesWithoutAttributes_default()); - - chat_bottom_panel_options.insert = insertBySelector_default().bind(null, "head"); - -chat_bottom_panel_options.domAPI = (styleDomAPI_default()); -chat_bottom_panel_options.insertStyleElement = (insertStyleElement_default()); - -var chat_bottom_panel_update = injectStylesIntoStyleTag_default()(chat_bottom_panel/* default */.Z, chat_bottom_panel_options); - - - - - /* harmony default export */ const styles_chat_bottom_panel = (chat_bottom_panel/* default */.Z && chat_bottom_panel/* default.locals */.Z.locals ? chat_bottom_panel/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/chatview/bottom-panel.js -function bottom_panel_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - - - - - - -class ChatBottomPanel extends ElementView { - constructor() { - super(); - - bottom_panel_defineProperty(this, "events", { - 'click .send-button': 'sendButtonClicked', - 'click .toggle-clear': 'clearMessages' - }); - - this.debouncedRender = lodash_es_debounce(this.render, 100); - } - - async connectedCallback() { - super.connectedCallback(); - await this.initialize(); - this.render(); // don't call in initialize, since the MUCBottomPanel subclasses it - // and we want to render after it has finished as wel. - } - - async initialize() { - this.model = await api.chatboxes.get(this.getAttribute('jid')); - await this.model.initialized; - this.listenTo(this.model, 'change:num_unread', this.debouncedRender); - this.listenTo(this.model, 'emoji-picker-autocomplete', this.autocompleteInPicker); - this.addEventListener('focusin', ev => this.emitFocused(ev)); - this.addEventListener('focusout', ev => this.emitBlurred(ev)); - } - - render() { - V(bottom_panel({ - 'model': this.model, - 'viewUnreadMessages': ev => this.viewUnreadMessages(ev) - }), this); - } - - sendButtonClicked(ev) { - var _this$querySelector; - - (_this$querySelector = this.querySelector('converse-message-form')) === null || _this$querySelector === void 0 ? void 0 : _this$querySelector.onFormSubmitted(ev); - } - - viewUnreadMessages(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - this.model.ui.set({ - 'scrolled': false - }); - } - - emitFocused(ev) { - var _converse$chatboxview; - - (_converse$chatboxview = shared_converse.chatboxviews.get(this.getAttribute('jid'))) === null || _converse$chatboxview === void 0 ? void 0 : _converse$chatboxview.emitFocused(ev); - } - - emitBlurred(ev) { - var _converse$chatboxview2; - - (_converse$chatboxview2 = shared_converse.chatboxviews.get(this.getAttribute('jid'))) === null || _converse$chatboxview2 === void 0 ? void 0 : _converse$chatboxview2.emitBlurred(ev); - } - - onDrop(evt) { - if (evt.dataTransfer.files.length == 0) { - // There are no files to be dropped, so this isn’t a file - // transfer operation. - return; - } - - evt.preventDefault(); - this.model.sendFiles(evt.dataTransfer.files); - } - - onDragOver(ev) { - // eslint-disable-line class-methods-use-this - ev.preventDefault(); - } - - clearMessages(ev) { - var _ev$preventDefault2; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault2 = ev.preventDefault) === null || _ev$preventDefault2 === void 0 ? void 0 : _ev$preventDefault2.call(ev); - clearMessages(this.model); - } - - async autocompleteInPicker(input, value) { - await api.emojis.initialize(); - const emoji_picker = this.querySelector('converse-emoji-picker'); - - if (emoji_picker) { - emoji_picker.model.set({ - 'ac_position': input.selectionStart, - 'autocompleting': value, - 'query': value - }); - const emoji_dropdown = this.querySelector('converse-emoji-dropdown'); - emoji_dropdown === null || emoji_dropdown === void 0 ? void 0 : emoji_dropdown.showMenu(); - } - } - -} -api.elements.define('converse-chat-bottom-panel', ChatBottomPanel); -;// CONCATENATED MODULE: ./src/shared/chat/baseview.js - - - -class BaseChatView extends CustomElement { - static get properties() { - return { - jid: { - type: String - } - }; - } - - disconnectedCallback() { - super.disconnectedCallback(); - - shared_converse.chatboxviews.remove(this.jid, this); - } - - updated() { - if (this.model && this.jid !== this.model.get('jid')) { - this.stopListening(); - - shared_converse.chatboxviews.remove(this.model.get('jid'), this); - - delete this.model; - this.requestUpdate(); - this.initialize(); - } - } - - close(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - return this.model.close(ev); - } - - maybeFocus() { - api.settings.get('auto_focus') && this.focus(); - } - - focus() { - const textarea_el = this.getElementsByClassName('chat-textarea')[0]; - - if (textarea_el && document.activeElement !== textarea_el) { - textarea_el.focus(); - } - - return this; - } - - emitBlurred(ev) { - if (this.contains(document.activeElement) || this.contains(ev.relatedTarget)) { - // Something else in this chatbox is still focused - return; - } - /** - * Triggered when the focus has been removed from a particular chat. - * @event _converse#chatBoxBlurred - * @type { _converse.ChatBoxView | _converse.ChatRoomView } - * @example _converse.api.listen.on('chatBoxBlurred', (view, event) => { ... }); - */ - - - api.trigger('chatBoxBlurred', this, ev); - } - - emitFocused(ev) { - if (this.contains(ev.relatedTarget)) { - // Something else in this chatbox was already focused - return; - } - /** - * Triggered when the focus has been moved to a particular chat. - * @event _converse#chatBoxFocused - * @type { _converse.ChatBoxView | _converse.ChatRoomView } - * @example _converse.api.listen.on('chatBoxFocused', (view, event) => { ... }); - */ - - - api.trigger('chatBoxFocused', this, ev); - } - - getBottomPanel() { - if (this.model.get('type') === shared_converse.CHATROOMS_TYPE) { - return this.querySelector('converse-muc-bottom-panel'); - } else { - return this.querySelector('converse-chat-bottom-panel'); - } - } - - getMessageForm() { - if (this.model.get('type') === shared_converse.CHATROOMS_TYPE) { - return this.querySelector('converse-muc-message-form'); - } else { - return this.querySelector('converse-message-form'); - } - } - /** - * Scrolls the chat down. - * - * This method will always scroll the chat down, regardless of - * whether the user scrolled up manually or not. - * @param { Event } [ev] - An optional event that is the cause for needing to scroll down. - */ - - - scrollDown(ev) { - var _ev$preventDefault2, _ev$stopPropagation; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault2 = ev.preventDefault) === null || _ev$preventDefault2 === void 0 ? void 0 : _ev$preventDefault2.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation = ev.stopPropagation) === null || _ev$stopPropagation === void 0 ? void 0 : _ev$stopPropagation.call(ev); - - if (this.model.ui.get('scrolled')) { - this.model.ui.set({ - 'scrolled': false - }); - } - - onScrolledDown(this.model); - } - - onWindowStateChanged(data) { - if (data.state === 'visible') { - if (!this.model.isHidden()) { - this.model.clearUnreadMsgCounter(); - } - } else if (data.state === 'hidden') { - this.model.setChatState(shared_converse.INACTIVE, { - 'silent': true - }); - this.model.sendChatState(); - } - } - -} -;// CONCATENATED MODULE: ./src/plugins/chatview/templates/chat.js - - -/* harmony default export */ const chat = (o => T` -
    - - ${o.model ? T` - -
    -
    - - - ${o.show_help_messages ? T`
    -
    ` : ''} -
    - -
    - ` : ''} -
    -`); -;// CONCATENATED MODULE: ./src/plugins/chatview/chat.js -function chat_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - - - - -/** - * The view of an open/ongoing chat conversation. - * @class - * @namespace _converse.ChatBoxView - * @memberOf _converse - */ - -class ChatView extends BaseChatView { - constructor(...args) { - super(...args); - - chat_defineProperty(this, "length", 200); - } - - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - async initialize() { - shared_converse.chatboxviews.add(this.jid, this); - - this.model = shared_converse.chatboxes.get(this.jid); - this.listenTo(shared_converse, 'windowStateChanged', this.onWindowStateChanged); - this.listenTo(this.model, 'change:hidden', () => !this.model.get('hidden') && this.afterShown()); - this.listenTo(this.model, 'change:show_help_messages', this.requestUpdate); - await this.model.messages.fetched; - !this.model.get('hidden') && this.afterShown(); - /** - * Triggered once the {@link _converse.ChatBoxView} has been initialized - * @event _converse#chatBoxViewInitialized - * @type { _converse.HeadlinesBoxView } - * @example _converse.api.listen.on('chatBoxViewInitialized', view => { ... }); - */ - - api.trigger('chatBoxViewInitialized', this); - } - - render() { - return chat(Object.assign({ - 'model': this.model, - 'help_messages': this.getHelpMessages(), - 'show_help_messages': this.model.get('show_help_messages') - }, this.model.toJSON())); - } - - getHelpMessages() { - // eslint-disable-line class-methods-use-this - return [`/clear: ${__('Remove messages')}`, `/close: ${__('Close this chat')}`, `/me: ${__('Write in the third person')}`, `/help: ${__('Show this menu')}`]; - } - - showControlBox() { - var _converse$chatboxview; - - // eslint-disable-line class-methods-use-this - // Used in mobile view, to navigate back to the controlbox - (_converse$chatboxview = shared_converse.chatboxviews.get('controlbox')) === null || _converse$chatboxview === void 0 ? void 0 : _converse$chatboxview.show(); - } - - afterShown() { - this.model.setChatState(shared_converse.ACTIVE); - this.model.clearUnreadMsgCounter(); - this.maybeFocus(); - } - -} -api.elements.define('converse-chat', ChatView); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/chatview/styles/index.scss -var chatview_styles = __webpack_require__(9107); -;// CONCATENATED MODULE: ./src/plugins/chatview/styles/index.scss - - - - - - - - - - - -var styles_options = {}; - -styles_options.styleTagTransform = (styleTagTransform_default()); -styles_options.setAttributes = (setAttributesWithoutAttributes_default()); - - styles_options.insert = insertBySelector_default().bind(null, "head"); - -styles_options.domAPI = (styleDomAPI_default()); -styles_options.insertStyleElement = (insertStyleElement_default()); - -var styles_update = injectStylesIntoStyleTag_default()(chatview_styles/* default */.Z, styles_options); - - - - - /* harmony default export */ const plugins_chatview_styles = (chatview_styles/* default */.Z && chatview_styles/* default.locals */.Z.locals ? chatview_styles/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/chatview/index.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - - - -const { - Strophe: chatview_Strophe -} = core_converse.env; -core_converse.plugins.add('converse-chatview', { - /* Plugin dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. - * - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. By default it's - * false, which means these plugins are only loaded opportunistically. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ['converse-chatboxviews', 'converse-chat', 'converse-disco', 'converse-modal'], - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - api.settings.extend({ - 'auto_focus': true, - 'debounced_content_rendering': true, - 'embed_videos': true, - 'embed_audio': true, - 'filter_url_query_params': null, - 'image_urls_regex': null, - 'message_limit': 0, - 'muc_hats': ['xep317'], - 'show_images_inline': true, - 'show_message_avatar': true, - 'show_retraction_warning': true, - 'show_send_button': true, - 'show_toolbar': true, - 'time_format': 'HH:mm', - 'use_system_emojis': true, - 'visible_toolbar_buttons': { - 'call': false, - 'clear': true, - 'emoji': true, - 'spoiler': true - } - }); - shared_converse.ChatBoxView = ChatView; - api.listen.on('connected', () => api.disco.own.features.add(chatview_Strophe.NS.SPOILER)); - api.listen.on('chatBoxClosed', model => clearHistory(model.get('jid'))); - } - -}); -;// CONCATENATED MODULE: ./src/shared/components/brand-byline.js - - - -class ConverseBrandByline extends CustomElement { - render() { - // eslint-disable-line class-methods-use-this - const is_fullscreen = api.settings.get('view_mode') === 'fullscreen'; - return T` - ${is_fullscreen ? T` -

    ${shared_converse.VERSION_NAME}

    -

    - Open Source XMPP chat client - brought to you by Opkode -

    -

    - Translate - it into your own language -

    - ` : ''} - `; - } - -} -api.elements.define('converse-brand-byline', ConverseBrandByline); -;// CONCATENATED MODULE: ./src/shared/components/brand-logo.js - - - -class ConverseBrandLogo extends CustomElement { - render() { - // eslint-disable-line class-methods-use-this - const is_fullscreen = api.settings.get('view_mode') === 'fullscreen'; - return T` - - - - - converse.js - ${is_fullscreen ? T` - - ` : ''} - - - - `; - } - -} -api.elements.define('converse-brand-logo', ConverseBrandLogo); -;// CONCATENATED MODULE: ./src/shared/components/brand-heading.js - - - - - -class ConverseBrandHeading extends CustomElement { - render() { - // eslint-disable-line class-methods-use-this - return T` - - - `; - } - -} -api.elements.define('converse-brand-heading', ConverseBrandHeading); -;// CONCATENATED MODULE: ./src/plugins/controlbox/templates/loginpanel.js - - - - - - -const trust_checkbox = checked => { - const i18n_hint_trusted = __('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. ' + 'Please note, when using an untrusted device, OMEMO encryption is NOT available.'); - - const i18n_trusted = __('This is a trusted device'); - - return T` - - `; -}; - -const password_input = () => { - const i18n_password = __('Password'); - - return T` -
    - - -
    - `; -}; - -const register_link = () => { - const i18n_create_account = __("Create an account"); - - const i18n_hint_no_account = __("Don't have a chat account?"); - - return T` -
    -

    ${i18n_hint_no_account}

    -

    -
    - `; -}; - -const show_register_link = () => { - return shared_converse.allow_registration && !api.settings.get("auto_login") && shared_converse.pluggable.plugins["converse-register"].enabled(shared_converse); -}; - -const auth_fields = o => { - const i18n_login = __('Log in'); - - const i18n_xmpp_address = __("XMPP Address"); - - return T` -
    - - -
    - ${o.authentication !== o.EXTERNAL ? password_input() : ''} - ${o.show_trust_checkbox ? trust_checkbox(o.show_trust_checkbox === 'off' ? false : true) : ''} -
    - -
    - ${show_register_link() ? register_link(o) : ''} - `; -}; - -const form_fields = o => { - const i18n_disconnected = __('Disconnected'); - - const i18n_anon_login = __('Click here to log in anonymously'); - - return T` - ${o.authentication == o.LOGIN || o.authentication == o.EXTERNAL ? auth_fields(o) : ''} - ${o.authentication == o.ANONYMOUS ? T`` : ''} - ${o.authentication == o.PREBIND ? T`

    ${i18n_disconnected}

    ` : ''} - `; -}; - -/* harmony default export */ const loginpanel = (o => T` - -
    -
    - - -
    - ${shared_converse.CONNECTION_STATUS[o.connection_status] === 'CONNECTING' ? spinner({ - 'classes': 'hor_centered' -}) : form_fields(o)} -
    -`); -;// CONCATENATED MODULE: ./src/plugins/controlbox/loginpanel.js -function loginpanel_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - - - - - -const loginpanel_u = core_converse.env.utils; -const { - Strophe: loginpanel_Strophe -} = core_converse.env; -const REPORTABLE_STATUSES = [0, // ERROR' -1, // CONNECTING -2, // CONNFAIL -3, // AUTHENTICATING -4, // AUTHFAIL -7, // DISCONNECTING -10 // RECONNECTING -]; -const PRETTY_CONNECTION_STATUS = { - 0: 'Error', - 1: 'Connecting', - 2: 'Connection failure', - 3: 'Authenticating', - 4: 'Authentication failure', - 5: 'Connected', - 6: 'Disconnected', - 7: 'Disconnecting', - 8: 'Attached', - 9: 'Redirect', - 10: 'Reconnecting' -}; -const CONNECTION_STATUS_CSS_CLASS = { - 'Error': 'error', - 'Connecting': 'info', - 'Connection failure': 'error', - 'Authenticating': 'info', - 'Authentication failure': 'error', - 'Connected': 'info', - 'Disconnected': 'error', - 'Disconnecting': 'warn', - 'Attached': 'info', - 'Redirect': 'info', - 'Reconnecting': 'warn' -}; -const LoginPanelModel = Model.extend({ - defaults: { - // Passed-by-reference. Fine in this case because there's only one such model. - 'errors': [] - } -}); - -class LoginPanel extends ElementView { - constructor(...args) { - super(...args); - - loginpanel_defineProperty(this, "id", "converse-login-panel"); - - loginpanel_defineProperty(this, "className", 'controlbox-pane fade-in row no-gutters'); - - loginpanel_defineProperty(this, "events", { - 'submit form#converse-login': 'authenticate', - 'change input': 'validate' - }); - } - - initialize() { - this.model = new LoginPanelModel(); - this.listenTo(this.model, 'change', this.render); - this.listenTo(shared_converse.connfeedback, 'change', this.render); - this.render(); - this.initPopovers(); - } - - render() { - const connection_status = shared_converse.connfeedback.get('connection_status'); - - let feedback_class, pretty_status; - - if (REPORTABLE_STATUSES.includes(connection_status)) { - pretty_status = PRETTY_CONNECTION_STATUS[connection_status]; - feedback_class = CONNECTION_STATUS_CSS_CLASS[pretty_status]; - } - - V(loginpanel(Object.assign(this.model.toJSON(), { - '_converse': shared_converse, - 'ANONYMOUS': shared_converse.ANONYMOUS, - 'EXTERNAL': shared_converse.EXTERNAL, - 'LOGIN': shared_converse.LOGIN, - 'PREBIND': shared_converse.PREBIND, - 'auto_login': api.settings.get('auto_login'), - 'authentication': api.settings.get("authentication"), - 'connection_status': connection_status, - 'conn_feedback_class': feedback_class, - 'conn_feedback_subject': pretty_status, - 'conn_feedback_message': shared_converse.connfeedback.get('message'), - 'placeholder_username': (api.settings.get('locked_domain') || api.settings.get('default_domain')) && __('Username') || __('user@domain'), - 'show_trust_checkbox': api.settings.get('allow_user_trust_override') - })), this); - } - - initPopovers() { - Array.from(this.querySelectorAll('[data-title]')).forEach(el => { - new (bootstrap_native_default()).Popover(el, { - 'trigger': api.settings.get("view_mode") === 'mobile' && 'click' || 'hover', - 'dismissible': api.settings.get("view_mode") === 'mobile' && true || false, - 'container': this.parentElement.parentElement.parentElement - }); - }); - } - - validate() { - const form = this.querySelector('form'); - const jid_element = form.querySelector('input[name=jid]'); - - if (jid_element.value && !api.settings.get('locked_domain') && !api.settings.get('default_domain') && !loginpanel_u.isValidJID(jid_element.value)) { - jid_element.setCustomValidity(__('Please enter a valid XMPP address')); - return false; - } - - jid_element.setCustomValidity(''); - return true; - } - /** - * Authenticate the user based on a form submission event. - * @param { Event } ev - */ - - - authenticate(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - - if (api.settings.get("authentication") === shared_converse.ANONYMOUS) { - return this.connect(shared_converse.jid, null); - } - - if (!this.validate()) { - return; - } - - const form_data = new FormData(ev.target); - - shared_converse.config.save({ - 'trusted': form_data.get('trusted') && true || false - }); - - let jid = form_data.get('jid'); - - if (api.settings.get('locked_domain')) { - const last_part = '@' + api.settings.get('locked_domain'); - - if (jid.endsWith(last_part)) { - jid = jid.substr(0, jid.length - last_part.length); - } - - jid = loginpanel_Strophe.escapeNode(jid) + last_part; - } else if (api.settings.get('default_domain') && !jid.includes('@')) { - jid = jid + '@' + api.settings.get('default_domain'); - } - - this.connect(jid, form_data.get('password')); - } - - connect(jid, password) { - // eslint-disable-line class-methods-use-this - if (["converse/login", "converse/register"].includes(shared_converse.router.history.getFragment())) { - shared_converse.router.navigate('', { - 'replace': true - }); - } - - shared_converse.connection && shared_converse.connection.reset(); - api.user.login(jid, password); - } - -} - -api.elements.define('converse-login-panel', LoginPanel); -;// CONCATENATED MODULE: ./src/plugins/controlbox/utils.js - -const controlbox_utils_u = core_converse.env.utils; -function addControlBox() { - var _converse$chatboxview; - - const m = shared_converse.chatboxes.add(new shared_converse.ControlBox({ - 'id': 'controlbox' - })); - - (_converse$chatboxview = shared_converse.chatboxviews.get('controlbox')) === null || _converse$chatboxview === void 0 ? void 0 : _converse$chatboxview.setModel(); - return m; -} -function showControlBox(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - const controlbox = shared_converse.chatboxes.get('controlbox') || addControlBox(); - controlbox_utils_u.safeSave(controlbox, { - 'closed': false - }); -} -function navigateToControlBox(jid) { - showControlBox(); - - const model = shared_converse.chatboxes.get(jid); - - controlbox_utils_u.safeSave(model, { - 'hidden': true - }); -} -function disconnect() { - /* Upon disconnection, set connected to `false`, so that if - * we reconnect, "onConnected" will be called, - * to fetch the roster again and to send out a presence stanza. - */ - const view = shared_converse.chatboxviews.get('controlbox'); - - view.model.set({ - 'connected': false - }); - return view; -} -function controlbox_utils_clearSession() { - const chatboxviews = shared_converse === null || shared_converse === void 0 ? void 0 : shared_converse.chatboxviews; - const view = chatboxviews && chatboxviews.get('controlbox'); - - if (view) { - controlbox_utils_u.safeSave(view.model, { - 'connected': false - }); - - if (view !== null && view !== void 0 && view.controlbox_pane) { - view.controlbox_pane.remove(); - delete view.controlbox_pane; - } - } -} -function onChatBoxesFetched() { - const controlbox = shared_converse.chatboxes.get('controlbox') || addControlBox(); - controlbox.save({ - 'connected': true - }); -} -;// CONCATENATED MODULE: ./src/plugins/controlbox/templates/navback.js - - -/* harmony default export */ const navback = (jid => { - return T` navigateToControlBox(jid)}>`; -}); -;// CONCATENATED MODULE: ./src/plugins/controlbox/navback.js - - - - -class ControlBoxNavback extends CustomElement { - static get properties() { - return { - 'jid': { - type: String - } - }; - } - - render() { - return navback(this.jid); - } - -} - -api.elements.define('converse-controlbox-navback', ControlBoxNavback); -/* harmony default export */ const controlbox_navback = ((/* unused pure expression or super */ null && (ControlBoxNavback))); -;// CONCATENATED MODULE: ./src/plugins/controlbox/model.js - - -const { - dayjs: model_dayjs -} = core_converse.env; -/** - * The ControlBox is the section of the chat that contains the open groupchats, - * bookmarks and roster. - * - * In `overlayed` `view_mode` it's a box like the chat boxes, in `fullscreen` - * `view_mode` it's a left-aligned sidebar. - * @mixin - */ - -const ControlBox = Model.extend({ - defaults() { - return { - 'bookmarked': false, - 'box_id': 'controlbox', - 'chat_state': undefined, - 'closed': !api.settings.get('show_controlbox_by_default'), - 'num_unread': 0, - 'time_opened': model_dayjs(0).valueOf(), - 'type': shared_converse.CONTROLBOX_TYPE, - 'url': '' - }; - }, - - validate(attrs) { - if (attrs.type === shared_converse.CONTROLBOX_TYPE) { - if (api.settings.get('view_mode') === 'embedded' && api.settings.get('singleton')) { - return 'Controlbox not relevant in embedded view mode'; - } - - return; - } - - return shared_converse.ChatBox.prototype.validate.call(this, attrs); - }, - - maybeShow(force) { - if (!force && this.get('id') === 'controlbox') { - // Must return the chatbox - return this; - } - - return shared_converse.ChatBox.prototype.maybeShow.call(this, force); - }, - - onReconnection() { - this.save('connected', true); - } - -}); -/* harmony default export */ const controlbox_model = (ControlBox); -;// CONCATENATED MODULE: ./src/plugins/controlbox/templates/toggle.js - - - -/* harmony default export */ const toggle = (o => { - const i18n_toggle = api.connection.connected() ? __('Chat Contacts') : __('Toggle chat'); - return T`${i18n_toggle}`; -}); -;// CONCATENATED MODULE: ./src/plugins/controlbox/toggle.js - - - - - -class ControlBoxToggle extends CustomElement { - async connectedCallback() { - super.connectedCallback(); - await api.waitUntil('initialized'); - this.model = shared_converse.chatboxes.get('controlbox'); - this.listenTo(this.model, 'change:closed', () => this.requestUpdate()); - this.requestUpdate(); - } - - render() { - var _this$model; - - return toggle({ - 'onClick': showControlBox, - 'hide': !((_this$model = this.model) !== null && _this$model !== void 0 && _this$model.get('closed')) - }); - } - -} - -api.elements.define('converse-controlbox-toggle', ControlBoxToggle); -/* harmony default export */ const controlbox_toggle = (ControlBoxToggle); -;// CONCATENATED MODULE: ./src/plugins/controlbox/templates/controlbox.js - - -/* harmony default export */ const controlbox = (o => T` -
    - -
    - ${o.sticky_controlbox ? '' : T` - - `} -
    -
    -
    - ${o.connected ? T` - - -
    - - -
    - ${api.settings.get("authentication") === shared_converse.ANONYMOUS ? '' : T`
    `}` : o['active-form'] === 'register' ? T`` : T``} -
    -
    -
    -`); -;// CONCATENATED MODULE: ./src/plugins/controlbox/controlbox.js - - - - -const controlbox_u = core_converse.env.utils; -/** - * The ControlBox is the section of the chat that contains the open groupchats, - * bookmarks and roster. - * - * In `overlayed` `view_mode` it's a box like the chat boxes, in `fullscreen` - * `view_mode` it's a left-aligned sidebar. - */ - -class controlbox_ControlBox extends ElementView { - initialize() { - this.setModel(); - this.render(); - - shared_converse.chatboxviews.add('controlbox', this); - /** - * Triggered when the _converse.ControlBoxView has been initialized and therefore - * exists. The controlbox contains the login and register forms when the user is - * logged out and a list of the user's contacts and group chats when logged in. - * @event _converse#controlBoxInitialized - * @type { _converse.ControlBoxView } - * @example _converse.api.listen.on('controlBoxInitialized', view => { ... }); - */ - - - api.trigger('controlBoxInitialized', this); - } - - setModel() { - this.model = shared_converse.chatboxes.get('controlbox'); - this.initEventHandlers(); - } - - initEventHandlers() { - // Keep event handler registration in a separate method so that it can - // be called when a new controlbox is created and assigned to this - // element. - this.listenTo(this.model, 'change:active-form', this.render); - this.listenTo(this.model, 'change:connected', this.render); - this.listenTo(this.model, 'change:closed', () => !this.model.get('closed') && this.afterShown()); - } - - render() { - V(controlbox({ - 'sticky_controlbox': api.settings.get('sticky_controlbox'), - ...this.model.toJSON(), - 'close': ev => this.close(ev) - }), this); - } - - afterRender() { - if (this.model.get('connected') && this.model.get('closed') === undefined) { - this.model.set('closed', !api.settings.get('show_controlbox_by_default')); - } - } - - close(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - - if ((ev === null || ev === void 0 ? void 0 : ev.name) === 'closeAllChatBoxes' && (shared_converse.disconnection_cause !== shared_converse.LOGOUT || api.settings.get('show_controlbox_by_default'))) { - return; - } - - if (api.settings.get('sticky_controlbox')) { - return; - } - - controlbox_u.safeSave(this.model, { - 'closed': true - }); - api.trigger('controlBoxClosed', this); - return this; - } - - afterShown() { - /** - * Triggered once the controlbox has been opened - * @event _converse#controlBoxOpened - * @type {_converse.ControlBox} - */ - api.trigger('controlBoxOpened', this); - return this; - } - - showHelpMessages() { - // eslint-disable-line class-methods-use-this - return; - } - -} - -api.elements.define('converse-controlbox', controlbox_ControlBox); -/* harmony default export */ const controlbox_controlbox = (controlbox_ControlBox); -;// CONCATENATED MODULE: ./src/plugins/controlbox/api.js - -const { - u: controlbox_api_u -} = core_converse.env; -/* harmony default export */ const controlbox_api = ({ - /** - * The "controlbox" namespace groups methods pertaining to the - * controlbox view - * - * @namespace _converse.api.controlbox - * @memberOf _converse.api - */ - controlbox: { - /** - * Opens the controlbox - * @method _converse.api.controlbox.open - * @returns { Promise<_converse.ControlBox> } - */ - async open() { - await api.waitUntil('chatBoxesFetched'); - const model = (await api.chatboxes.get('controlbox')) || api.chatboxes.create('controlbox', {}, shared_converse.Controlbox); - controlbox_api_u.safeSave(model, { - 'closed': false - }); - return model; - }, - - /** - * Returns the controlbox view. - * @method _converse.api.controlbox.get - * @returns { View } View representing the controlbox - * @example const view = _converse.api.controlbox.get(); - */ - get() { - return shared_converse.chatboxviews.get('controlbox'); - } - - } -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/controlbox/styles/_controlbox.scss -var _controlbox = __webpack_require__(7581); -;// CONCATENATED MODULE: ./src/plugins/controlbox/styles/_controlbox.scss - - - - - - - - - - - -var _controlbox_options = {}; - -_controlbox_options.styleTagTransform = (styleTagTransform_default()); -_controlbox_options.setAttributes = (setAttributesWithoutAttributes_default()); - - _controlbox_options.insert = insertBySelector_default().bind(null, "head"); - -_controlbox_options.domAPI = (styleDomAPI_default()); -_controlbox_options.insertStyleElement = (insertStyleElement_default()); - -var _controlbox_update = injectStylesIntoStyleTag_default()(_controlbox/* default */.Z, _controlbox_options); - - - - - /* harmony default export */ const styles_controlbox = (_controlbox/* default */.Z && _controlbox/* default.locals */.Z.locals ? _controlbox/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/controlbox/index.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - - - - - - -core_converse.plugins.add('converse-controlbox', { - /* Plugin dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. - * - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. By default it's - * false, which means these plugins are only loaded opportunistically. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ['converse-modal', 'converse-chatboxes', 'converse-chat', 'converse-rosterview', 'converse-chatview'], - - enabled(_converse) { - return !_converse.api.settings.get('singleton'); - }, - - overrides: { - // Overrides mentioned here will be picked up by converse.js's - // plugin architecture they will replace existing methods on the - // relevant objects or classes. - // - // New functions which don't exist yet can also be added. - ChatBoxes: { - model(attrs, options) { - if (attrs && attrs.id == 'controlbox') { - return new controlbox_model(attrs, options); - } else { - return this.__super__.model.apply(this, arguments); - } - } - - } - }, - - initialize() { - api.settings.extend({ - allow_logout: true, - allow_user_trust_override: true, - default_domain: undefined, - locked_domain: undefined, - show_controlbox_by_default: false, - sticky_controlbox: false - }); - api.promises.add('controlBoxInitialized'); - Object.assign(api, controlbox_api); - shared_converse.ControlBoxView = controlbox_controlbox; - shared_converse.ControlBox = controlbox_model; - shared_converse.ControlBoxToggle = controlbox_toggle; - /******************** Event Handlers ********************/ - - api.listen.on('chatBoxesFetched', onChatBoxesFetched); - api.listen.on('cleanup', () => delete shared_converse.controlboxtoggle); - api.listen.on('clearSession', controlbox_utils_clearSession); - api.listen.on('will-reconnect', disconnect); - api.waitUntil('chatBoxViewsInitialized').then(addControlBox).catch(e => headless_log.fatal(e)); - } - -}); -;// CONCATENATED MODULE: ./src/plugins/dragresize/utils.js - -const { - u: dragresize_utils_u -} = core_converse.env; -function onStartVerticalResize(ev, trigger = true) { - if (!api.settings.get('allow_dragresize')) { - return true; - } - - ev.preventDefault(); // Record element attributes for mouseMove(). - - const flyout = dragresize_utils_u.ancestor(ev.target, '.box-flyout'); - const style = window.getComputedStyle(flyout); - const chatbox_el = flyout.parentElement; - chatbox_el.height = parseInt(style.height.replace(/px$/, ''), 10); - shared_converse.resizing = { - 'chatbox': chatbox_el, - 'direction': 'top' - }; - chatbox_el.prev_pageY = ev.pageY; - - if (trigger) { - /** - * Triggered once the user starts to vertically resize a {@link _converse.ChatBoxView} - * @event _converse#startVerticalResize - * @example _converse.api.listen.on('startVerticalResize', (view) => { ... }); - */ - api.trigger('startVerticalResize', chatbox_el); - } -} -function onStartHorizontalResize(ev, trigger = true) { - if (!api.settings.get('allow_dragresize')) { - return true; - } - - ev.preventDefault(); - const flyout = dragresize_utils_u.ancestor(ev.target, '.box-flyout'); - const style = window.getComputedStyle(flyout); - const chatbox_el = flyout.parentElement; - chatbox_el.width = parseInt(style.width.replace(/px$/, ''), 10); - shared_converse.resizing = { - 'chatbox': chatbox_el, - 'direction': 'left' - }; - chatbox_el.prev_pageX = ev.pageX; - - if (trigger) { - /** - * Triggered once the user starts to horizontally resize a {@link _converse.ChatBoxView} - * @event _converse#startHorizontalResize - * @example _converse.api.listen.on('startHorizontalResize', (view) => { ... }); - */ - api.trigger('startHorizontalResize', chatbox_el); - } -} -function onStartDiagonalResize(ev) { - onStartHorizontalResize(ev, false); - onStartVerticalResize(ev, false); - shared_converse.resizing.direction = 'topleft'; - /** - * Triggered once the user starts to diagonally resize a {@link _converse.ChatBoxView} - * @event _converse#startDiagonalResize - * @example _converse.api.listen.on('startDiagonalResize', (view) => { ... }); - */ - - api.trigger('startDiagonalResize', this); -} -/** - * Applies some resistance to `value` around the `default_value`. - * If value is close enough to `default_value`, then it is returned, otherwise - * `value` is returned. - * @param { Integer } value - * @param { Integer } default_value - * @returns { Integer } - */ - -function applyDragResistance(value, default_value) { - if (value === undefined) { - return undefined; - } else if (default_value === undefined) { - return value; - } - - const resistance = 10; - - if (value !== default_value && Math.abs(value - default_value) < resistance) { - return default_value; - } - - return value; -} -function onMouseMove(ev) { - if (!shared_converse.resizing || !api.settings.get('allow_dragresize')) { - return true; - } - - ev.preventDefault(); - - shared_converse.resizing.chatbox.resizeChatBox(ev); -} -function onMouseUp(ev) { - if (!shared_converse.resizing || !api.settings.get('allow_dragresize')) { - return true; - } - - ev.preventDefault(); - const height = applyDragResistance(shared_converse.resizing.chatbox.height, shared_converse.resizing.chatbox.model.get('default_height')); - const width = applyDragResistance(shared_converse.resizing.chatbox.width, shared_converse.resizing.chatbox.model.get('default_width')); - - if (api.connection.connected()) { - shared_converse.resizing.chatbox.model.save({ - 'height': height - }); - - shared_converse.resizing.chatbox.model.save({ - 'width': width - }); - } else { - shared_converse.resizing.chatbox.model.set({ - 'height': height - }); - - shared_converse.resizing.chatbox.model.set({ - 'width': width - }); - } - - shared_converse.resizing = null; -} -;// CONCATENATED MODULE: ./src/plugins/dragresize/templates/dragresize.js - - -/* harmony default export */ const dragresize = (() => T` -
    -
    -
    -`); -;// CONCATENATED MODULE: ./src/plugins/dragresize/components/dragresize.js - - - -class ConverseDragResize extends CustomElement { - render() { - // eslint-disable-line class-methods-use-this - return dragresize(); - } - -} - -customElements.define('converse-dragresize', ConverseDragResize); -;// CONCATENATED MODULE: ./src/plugins/dragresize/mixin.js - - - -const DragResizableMixin = { - initDragResize() { - var _converse$connection; - - const view = this; - const debouncedSetDimensions = lodash_es_debounce(() => view.setDimensions()); - window.addEventListener('resize', view.debouncedSetDimensions); - this.listenTo(this.model, 'destroy', () => window.removeEventListener('resize', debouncedSetDimensions)); // Determine and store the default box size. - // We need this information for the drag-resizing feature. - - const flyout = this.querySelector('.box-flyout'); - const style = window.getComputedStyle(flyout); - - if (this.model.get('height') === undefined) { - const height = parseInt(style.height.replace(/px$/, ''), 10); - const width = parseInt(style.width.replace(/px$/, ''), 10); - this.model.set('height', height); - this.model.set('default_height', height); - this.model.set('width', width); - this.model.set('default_width', width); - } - - const min_width = style['min-width']; - const min_height = style['min-height']; - this.model.set('min_width', min_width.endsWith('px') ? Number(min_width.replace(/px$/, '')) : 0); - this.model.set('min_height', min_height.endsWith('px') ? Number(min_height.replace(/px$/, '')) : 0); // Initialize last known mouse position - - this.prev_pageY = 0; - this.prev_pageX = 0; - - if ((_converse$connection = shared_converse.connection) !== null && _converse$connection !== void 0 && _converse$connection.connected) { - this.height = this.model.get('height'); - this.width = this.model.get('width'); - } - - return this; - }, - - resizeChatBox(ev) { - let diff; - - if (shared_converse.resizing.direction.indexOf('top') === 0) { - diff = ev.pageY - this.prev_pageY; - - if (diff) { - this.height = this.height - diff > (this.model.get('min_height') || 0) ? this.height - diff : this.model.get('min_height'); - this.prev_pageY = ev.pageY; - this.setChatBoxHeight(this.height); - } - } - - if (shared_converse.resizing.direction.includes('left')) { - diff = this.prev_pageX - ev.pageX; - - if (diff) { - this.width = this.width + diff > (this.model.get('min_width') || 0) ? this.width + diff : this.model.get('min_width'); - this.prev_pageX = ev.pageX; - this.setChatBoxWidth(this.width); - } - } - }, - - setDimensions() { - // Make sure the chat box has the right height and width. - this.adjustToViewport(); - this.setChatBoxHeight(this.model.get('height')); - this.setChatBoxWidth(this.model.get('width')); - }, - - setChatBoxHeight(height) { - if (height) { - height = applyDragResistance(height, this.model.get('default_height')) + 'px'; - } else { - height = ''; - } - - const flyout_el = this.querySelector('.box-flyout'); - - if (flyout_el !== null) { - flyout_el.style.height = height; - } - }, - - setChatBoxWidth(width) { - if (width) { - width = applyDragResistance(width, this.model.get('default_width')) + 'px'; - } else { - width = ''; - } - - this.style.width = width; - const flyout_el = this.querySelector('.box-flyout'); - - if (flyout_el !== null) { - flyout_el.style.width = width; - } - }, - - adjustToViewport() { - /* Event handler called when viewport gets resized. We remove - * custom width/height from chat boxes. - */ - const viewport_width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); - const viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); - - if (viewport_width <= 480) { - this.model.set('height', undefined); - this.model.set('width', undefined); - } else if (viewport_width <= this.model.get('width')) { - this.model.set('width', undefined); - } else if (viewport_height <= this.model.get('height')) { - this.model.set('height', undefined); - } - } - -}; -/* harmony default export */ const mixin = (DragResizableMixin); -;// CONCATENATED MODULE: ./src/plugins/dragresize/index.js -/** - * @module converse-dragresize - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - -core_converse.plugins.add('converse-dragresize', { - /* Plugin dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. - * - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. By default it's - * false, which means these plugins are only loaded opportunistically. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ['converse-chatview', 'converse-headlines-view', 'converse-muc-views'], - - enabled(_converse) { - return _converse.api.settings.get('view_mode') == 'overlayed'; - }, - - overrides: { - // Overrides mentioned here will be picked up by converse.js's - // plugin architecture they will replace existing methods on the - // relevant objects or classes. - ChatBox: { - initialize() { - const result = this.__super__.initialize.apply(this, arguments); - - const height = this.get('height'); - const width = this.get('width'); - const save = this.get('id') === 'controlbox' ? a => this.set(a) : a => this.save(a); - save({ - 'height': applyDragResistance(height, this.get('default_height')), - 'width': applyDragResistance(width, this.get('default_width')) - }); - return result; - } - - } - }, - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - api.settings.extend({ - 'allow_dragresize': true - }); - Object.assign(shared_converse.ChatBoxView.prototype, mixin); - Object.assign(shared_converse.ChatRoomView.prototype, mixin); - Object.assign(shared_converse.ControlBoxView.prototype, mixin); - /************************ BEGIN Event Handlers ************************/ - - function registerGlobalEventHandlers() { - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); - } - - function unregisterGlobalEventHandlers() { - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); - } - - api.listen.on('registeredGlobalEventHandlers', registerGlobalEventHandlers); - api.listen.on('unregisteredGlobalEventHandlers', unregisterGlobalEventHandlers); - api.listen.on('beforeShowingChatView', view => view.initDragResize().setDimensions()); - } - -}); -;// CONCATENATED MODULE: ./src/plugins/singleton.js -/** - * @module converse-singleton - * @copyright JC Brand - * @license Mozilla Public License (MPLv2) - * @description A plugin which restricts Converse to only one chat. - */ - -core_converse.plugins.add('converse-singleton', { - enabled(_converse) { - return _converse.api.settings.get("singleton"); - }, - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - api.settings.extend({ - 'allow_logout': false, - // No point in logging out when we have auto_login as true. - 'allow_muc_invitations': false, - // Doesn't make sense to allow because only - // roster contacts can be invited - 'hide_muc_server': true - }); - - if (!Array.isArray(api.settings.get('auto_join_rooms')) && !Array.isArray(api.settings.get('auto_join_private_chats'))) { - throw new Error("converse-singleton: auto_join_rooms must be an Array"); - } - - if (api.settings.get('auto_join_rooms').length > 1 || api.settings.get('auto_join_private_chats').length > 1) { - throw new Error("It doesn't make sense to have singleton set to true and " + "auto_join_rooms or auto_join_private_chats set to more then one, " + "since only one chat room may be open at any time."); - } - } - -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/fullscreen/styles/fullscreen.scss -var fullscreen = __webpack_require__(6752); -;// CONCATENATED MODULE: ./src/plugins/fullscreen/styles/fullscreen.scss - - - - - - - - - - - -var fullscreen_options = {}; - -fullscreen_options.styleTagTransform = (styleTagTransform_default()); -fullscreen_options.setAttributes = (setAttributesWithoutAttributes_default()); - - fullscreen_options.insert = insertBySelector_default().bind(null, "head"); - -fullscreen_options.domAPI = (styleDomAPI_default()); -fullscreen_options.insertStyleElement = (insertStyleElement_default()); - -var fullscreen_update = injectStylesIntoStyleTag_default()(fullscreen/* default */.Z, fullscreen_options); - - - - - /* harmony default export */ const styles_fullscreen = (fullscreen/* default */.Z && fullscreen/* default.locals */.Z.locals ? fullscreen/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/fullscreen/index.js -/** - * @module converse-fullscreen - * @license Mozilla Public License (MPLv2) - * @copyright 2020, the Converse.js contributors - */ - - - - - - -core_converse.plugins.add('converse-fullscreen', { - enabled(_converse) { - return _converse.isUniView(); - }, - - initialize() { - api.settings.extend({ - chatview_avatar_height: 50, - chatview_avatar_width: 50, - hide_open_bookmarks: true, - show_controlbox_by_default: true, - sticky_controlbox: true - }); - } - -}); -;// CONCATENATED MODULE: ./src/plugins/headlines-view/templates/chat-head.js - - - -/* harmony default export */ const templates_chat_head = (o => { - const tpl_standalone_btns = o => o.standalone_btns.reverse().map(b => until_o(b, '')); - - return T` -
    -
    - ${!shared_converse.api.settings.get("singleton") ? T`` : ''} -
    ${o.display_name}
    -
    -
    - ${o.dropdown_btns.length ? T`` : ''} - ${o.standalone_btns.length ? tpl_standalone_btns(o) : ''} -
    -
    - ${o.status ? T`

    ${o.status}

    ` : ''} - `; -}); -;// CONCATENATED MODULE: ./src/plugins/headlines-view/heading.js - - - - - - -class HeadlinesHeading extends ElementView { - async connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.getAttribute('jid')); - await this.model.initialized; - this.render(); - } - - async render() { - const tpl = await this.generateHeadingTemplate(); - V(tpl, this); - } - - async generateHeadingTemplate() { - const heading_btns = await this.getHeadingButtons(); - const standalone_btns = heading_btns.filter(b => b.standalone); - const dropdown_btns = heading_btns.filter(b => !b.standalone); - return templates_chat_head(Object.assign(this.model.toJSON(), { - 'display_name': this.model.getDisplayName(), - 'dropdown_btns': dropdown_btns.map(b => getHeadingDropdownItem(b)), - 'standalone_btns': standalone_btns.map(b => getHeadingStandaloneButton(b)) - })); - } - /** - * Returns a list of objects which represent buttons for the headlines header. - * @async - * @emits _converse#getHeadingButtons - * @method HeadlinesHeading#getHeadingButtons - */ - - - getHeadingButtons() { - const buttons = []; - - if (!api.settings.get('singleton')) { - buttons.push({ - 'a_class': 'close-chatbox-button', - 'handler': ev => this.close(ev), - 'i18n_text': __('Close'), - 'i18n_title': __('Close these announcements'), - 'icon_class': 'fa-times', - 'name': 'close', - 'standalone': api.settings.get('view_mode') === 'overlayed' - }); - } - - return shared_converse.api.hook('getHeadingButtons', this, buttons); - } - - close(ev) { - ev.preventDefault(); - this.model.close(); - } - -} -api.elements.define('converse-headlines-heading', HeadlinesHeading); -;// CONCATENATED MODULE: ./src/plugins/headlines-view/templates/headlines.js - - -/* harmony default export */ const headlines = (model => T` -
    - - ${model ? T` - - -
    -
    - -
    -
    ` : ''} -
    -`); -;// CONCATENATED MODULE: ./src/plugins/headlines-view/view.js - - - - -class HeadlinesView extends BaseChatView { - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - async initialize() { - shared_converse.chatboxviews.add(this.jid, this); - - this.model = shared_converse.chatboxes.get(this.jid); - this.model.disable_mam = true; // Don't do MAM queries for this box - - this.listenTo(shared_converse, 'windowStateChanged', this.onWindowStateChanged); - this.listenTo(this.model, 'change:hidden', () => this.afterShown()); - this.listenTo(this.model, 'destroy', this.remove); - this.listenTo(this.model.messages, 'add', this.requestUpdate); - this.listenTo(this.model.messages, 'remove', this.requestUpdate); - this.listenTo(this.model.messages, 'reset', this.requestUpdate); - await this.model.messages.fetched; - this.model.maybeShow(); - /** - * Triggered once the {@link _converse.HeadlinesBoxView} has been initialized - * @event _converse#headlinesBoxViewInitialized - * @type { _converse.HeadlinesBoxView } - * @example _converse.api.listen.on('headlinesBoxViewInitialized', view => { ... }); - */ - - api.trigger('headlinesBoxViewInitialized', this); - } - - render() { - return headlines(this.model); - } - - async close(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - - if (shared_converse.router.history.getFragment() === 'converse/chat?jid=' + this.model.get('jid')) { - shared_converse.router.navigate(''); - } - - await this.model.close(ev); - return this; - } - - getNotifications() { - // eslint-disable-line class-methods-use-this - // Override method in ChatBox. We don't show notifications for - // headlines boxes. - return []; - } - - afterShown() { - this.model.clearUnreadMsgCounter(); - } - -} - -api.elements.define('converse-headlines', HeadlinesView); -;// CONCATENATED MODULE: ./src/templates/headline_list.js - - -const tpl_headline_box = o => T` - -`; - -/* harmony default export */ const headline_list = (o => T` -
    -
    - ${o.headlineboxes.map(headlinebox => tpl_headline_box(Object.assign({ - headlinebox -}, o)))} -
    -
    -`); -;// CONCATENATED MODULE: ./src/plugins/headlines-view/templates/panel.js - - -/* harmony default export */ const panel = (o => T` -
    -
    - ${o.heading_headline} -
    -
    - ${headline_list(o)} -`); -;// CONCATENATED MODULE: ./src/plugins/headlines-view/panel.js -function panel_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - - -/** - * View which renders headlines section of the control box. - * @class - * @namespace _converse.HeadlinesPanel - * @memberOf _converse - */ - -class HeadlinesPanel extends ElementView { - constructor(...args) { - super(...args); - - panel_defineProperty(this, "events", { - 'click .open-headline': 'openHeadline' - }); - } - - initialize() { - this.model = shared_converse.chatboxes; - this.listenTo(this.model, 'add', this.renderIfHeadline); - this.listenTo(this.model, 'remove', this.renderIfHeadline); - this.listenTo(this.model, 'destroy', this.renderIfHeadline); - this.render(); - } - - toHTML() { - return panel({ - 'heading_headline': __('Announcements'), - 'headlineboxes': this.model.filter(m => m.get('type') === shared_converse.HEADLINES_TYPE), - 'open_title': __('Click to open this server message') - }); - } - - renderIfHeadline(model) { - return model && model.get('type') === shared_converse.HEADLINES_TYPE && this.render(); - } - - openHeadline(ev) { - // eslint-disable-line class-methods-use-this - ev.preventDefault(); - const jid = ev.target.getAttribute('data-headline-jid'); - - const chat = shared_converse.chatboxes.get(jid); - - chat.maybeShow(true); - } - -} -api.elements.define('converse-headlines-panel', HeadlinesPanel); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/headlines-view/styles/headlines.scss -var styles_headlines = __webpack_require__(115); -;// CONCATENATED MODULE: ./src/plugins/headlines-view/styles/headlines.scss - - - - - - - - - - - -var headlines_options = {}; - -headlines_options.styleTagTransform = (styleTagTransform_default()); -headlines_options.setAttributes = (setAttributesWithoutAttributes_default()); - - headlines_options.insert = insertBySelector_default().bind(null, "head"); - -headlines_options.domAPI = (styleDomAPI_default()); -headlines_options.insertStyleElement = (insertStyleElement_default()); - -var headlines_update = injectStylesIntoStyleTag_default()(styles_headlines/* default */.Z, headlines_options); - - - - - /* harmony default export */ const headlines_view_styles_headlines = (styles_headlines/* default */.Z && styles_headlines/* default.locals */.Z.locals ? styles_headlines/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/headlines-view/index.js -/** - * @module converse-headlines-view - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - -core_converse.plugins.add('converse-headlines-view', { - /* Plugin dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. - * - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. By default it's - * false, which means these plugins are only loaded opportunistically. - * - * NB: These plugins need to have already been loaded by the bundler - */ - dependencies: ['converse-headlines', 'converse-chatview'], - - initialize() { - shared_converse.HeadlinesPanel = HeadlinesPanel; - } - -}); -;// CONCATENATED MODULE: ./src/plugins/mam-views/templates/placeholder.js - - - -/* harmony default export */ const placeholder = (el => { - return el.model.get('fetching') ? spinner({ - 'classes': 'hor_centered' - }) : T` -
    -
    `; -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/mam-views/styles/placeholder.scss -var styles_placeholder = __webpack_require__(8859); -;// CONCATENATED MODULE: ./src/plugins/mam-views/styles/placeholder.scss - - - - - - - - - - - -var placeholder_options = {}; - -placeholder_options.styleTagTransform = (styleTagTransform_default()); -placeholder_options.setAttributes = (setAttributesWithoutAttributes_default()); - - placeholder_options.insert = insertBySelector_default().bind(null, "head"); - -placeholder_options.domAPI = (styleDomAPI_default()); -placeholder_options.insertStyleElement = (insertStyleElement_default()); - -var placeholder_update = injectStylesIntoStyleTag_default()(styles_placeholder/* default */.Z, placeholder_options); - - - - - /* harmony default export */ const mam_views_styles_placeholder = (styles_placeholder/* default */.Z && styles_placeholder/* default.locals */.Z.locals ? styles_placeholder/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/mam-views/placeholder.js - - - - - - -class Placeholder extends CustomElement { - static get properties() { - return { - 'model': { - type: Object - } - }; - } - - render() { - return placeholder(this); - } - - async fetchMissingMessages(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - this.model.set('fetching', true); - const options = { - 'before': this.model.get('before'), - 'start': this.model.get('start') - }; - await fetchArchivedMessages(this.model.collection.chatbox, options); - this.model.destroy(); - } - -} - -api.elements.define('converse-mam-placeholder', Placeholder); -;// CONCATENATED MODULE: ./src/plugins/mam-views/utils.js - - - - - -function getPlaceholderTemplate(message, tpl) { - if (message instanceof MAMPlaceholderMessage) { - return T``; - } else { - return tpl; - } -} -async function fetchMessagesOnScrollUp(view) { - if (view.model.ui.get('chat-content-spinner-top')) { - return; - } - - if (view.model.messages.length) { - const is_groupchat = view.model.get('type') === shared_converse.CHATROOMS_TYPE; - - const oldest_message = view.model.getOldestMessage(); - - if (oldest_message) { - const by_jid = is_groupchat ? view.model.get('jid') : shared_converse.bare_jid; - const stanza_id = oldest_message && oldest_message.get(`stanza_id ${by_jid}`); - view.model.ui.set('chat-content-spinner-top', true); - - try { - if (stanza_id) { - await fetchArchivedMessages(view.model, { - 'before': stanza_id - }); - } else { - await fetchArchivedMessages(view.model, { - 'end': oldest_message.get('time') - }); - } - } catch (e) { - headless_log.error(e); - view.model.ui.set('chat-content-spinner-top', false); - return; - } - - if (api.settings.get('allow_url_history_change')) { - shared_converse.router.history.navigate(`#${oldest_message.get('msgid')}`); - } - - setTimeout(() => view.model.ui.set('chat-content-spinner-top', false), 250); - } - } -} -;// CONCATENATED MODULE: ./src/plugins/mam-views/index.js -/** - * @description UI code XEP-0313 Message Archive Management - * @copyright 2021, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - -core_converse.plugins.add('converse-mam-views', { - dependencies: ['converse-mam', 'converse-chatview', 'converse-muc-views'], - - initialize() { - api.listen.on('chatBoxScrolledUp', fetchMessagesOnScrollUp); - api.listen.on('getMessageTemplate', getPlaceholderTemplate); - } - -}); -;// CONCATENATED MODULE: ./src/plugins/minimize/templates/trimmed_chat.js - - -/* harmony default export */ const trimmed_chat = (o => { - const i18n_tooltip = __('Click to restore this chat'); - - const close_color = o.type === 'chatroom' ? "var(--chatroom-head-color)" : "var(--chat-head-text-color)"; - return T` - `; -}); -;// CONCATENATED MODULE: ./src/plugins/minimize/utils.js - - -const minimize_utils_u = core_converse.env.utils; - -function getChatBoxWidth(view) { - if (view.model.get('id') === 'controlbox') { - // We return the width of the controlbox or its toggle, - // depending on which is visible. - if (minimize_utils_u.isVisible(view)) { - return minimize_utils_u.getOuterWidth(view, true); - } else { - return minimize_utils_u.getOuterWidth(shared_converse.controlboxtoggle.el, true); - } - } else if (!view.model.get('minimized') && minimize_utils_u.isVisible(view)) { - return minimize_utils_u.getOuterWidth(view, true); - } - - return 0; -} - -function getShownChats() { - return shared_converse.chatboxviews.filter(el => // The controlbox can take a while to close, - // so we need to check its state. That's why we checked the 'closed' state. - !el.model.get('minimized') && !el.model.get('closed') && minimize_utils_u.isVisible(el)); -} - -function getMinimizedWidth() { - var _converse$minimized_c; - - const minimized_el = (_converse$minimized_c = shared_converse.minimized_chats) === null || _converse$minimized_c === void 0 ? void 0 : _converse$minimized_c.el; - return shared_converse.chatboxes.pluck('minimized').includes(true) ? minimize_utils_u.getOuterWidth(minimized_el, true) : 0; -} - -function getBoxesWidth(newchat) { - const new_id = newchat ? newchat.model.get('id') : null; - const newchat_width = newchat ? minimize_utils_u.getOuterWidth(newchat.el, true) : 0; - return Object.values(shared_converse.chatboxviews.xget(new_id)).reduce((memo, view) => memo + getChatBoxWidth(view), newchat_width); -} -/** - * This method is called when a newly created chat box will be shown. - * It checks whether there is enough space on the page to show - * another chat box. Otherwise it minimizes the oldest chat box - * to create space. - * @private - * @method _converse.ChatBoxViews#trimChats - * @param { _converse.ChatBoxView|_converse.ChatRoomView|_converse.ControlBoxView|_converse.HeadlinesBoxView } [newchat] - */ - - -async function trimChats(newchat) { - var _converse$minimized_c2; - - if (shared_converse.isTestEnv() || api.settings.get('no_trimming') || !api.connection.connected() || api.settings.get("view_mode") !== 'overlayed') { - return; - } - - const shown_chats = getShownChats(); - - if (shown_chats.length <= 1) { - return; - } - - const body_width = minimize_utils_u.getOuterWidth(document.querySelector('body'), true); - - if (getChatBoxWidth(shown_chats[0]) === body_width) { - // If the chats shown are the same width as the body, - // then we're in responsive mode and the chats are - // fullscreen. In this case we don't trim. - return; - } - - await api.waitUntil('minimizedChatsInitialized'); - const minimized_el = (_converse$minimized_c2 = shared_converse.minimized_chats) === null || _converse$minimized_c2 === void 0 ? void 0 : _converse$minimized_c2.el; - - if (minimized_el) { - while (getMinimizedWidth() + getBoxesWidth(newchat) > body_width) { - const new_id = newchat ? newchat.model.get('id') : null; - const oldest_chat = getOldestMaximizedChat([new_id]); - - if (oldest_chat) { - // We hide the chat immediately, because waiting - // for the event to fire (and letting the - // ChatBoxView hide it then) causes race - // conditions. - const view = shared_converse.chatboxviews.get(oldest_chat.get('id')); - - if (view) { - view.hide(); - } - - minimize(oldest_chat); - } else { - break; - } - } - } -} - -function getOldestMaximizedChat(exclude_ids) { - // Get oldest view (if its id is not excluded) - exclude_ids.push('controlbox'); - let i = 0; - - let model = shared_converse.chatboxes.sort().at(i); - - while (exclude_ids.includes(model.get('id')) || model.get('minimized') === true) { - i++; - model = shared_converse.chatboxes.at(i); - - if (!model) { - return null; - } - } - - return model; -} - -function addMinimizeButtonToChat(view, buttons) { - const data = { - 'a_class': 'toggle-chatbox-button', - 'handler': ev => minimize(ev, view.model), - 'i18n_text': __('Minimize'), - 'i18n_title': __('Minimize this chat'), - 'icon_class': "fa-minus", - 'name': 'minimize', - 'standalone': shared_converse.api.settings.get("view_mode") === 'overlayed' - }; - const names = buttons.map(t => t.name); - const idx = names.indexOf('close'); - return idx > -1 ? [...buttons.slice(0, idx), data, ...buttons.slice(idx)] : [data, ...buttons]; -} -function addMinimizeButtonToMUC(view, buttons) { - const data = { - 'a_class': 'toggle-chatbox-button', - 'handler': ev => minimize(ev, view.model), - 'i18n_text': __('Minimize'), - 'i18n_title': __('Minimize this groupchat'), - 'icon_class': "fa-minus", - 'name': 'minimize', - 'standalone': shared_converse.api.settings.get("view_mode") === 'overlayed' - }; - const names = buttons.map(t => t.name); - const idx = names.indexOf('signout'); - return idx > -1 ? [...buttons.slice(0, idx), data, ...buttons.slice(idx)] : [data, ...buttons]; -} -function maximize(ev, chatbox) { - if (ev !== null && ev !== void 0 && ev.preventDefault) { - ev.preventDefault(); - } else { - chatbox = ev; - } - - minimize_utils_u.safeSave(chatbox, { - 'hidden': false, - 'minimized': false, - 'time_opened': new Date().getTime() - }); -} -function minimize(ev, model) { - if (ev !== null && ev !== void 0 && ev.preventDefault) { - ev.preventDefault(); - } else { - model = ev; - } - - model.setChatState(shared_converse.INACTIVE); - minimize_utils_u.safeSave(model, { - 'hidden': true, - 'minimized': true, - 'time_minimized': new Date().toISOString() - }); -} -/** - * Handler which gets called when a {@link _converse#ChatBox} has it's - * `minimized` property set to false. - * - * Will trigger {@link _converse#chatBoxMaximized} - * @returns {_converse.ChatBoxView|_converse.ChatRoomView} - */ - -function onMaximized(model) { - if (!model.isScrolledUp()) { - model.clearUnreadMsgCounter(); - } - - model.setChatState(shared_converse.ACTIVE); - /** - * Triggered when a previously minimized chat gets maximized - * @event _converse#chatBoxMaximized - * @type { _converse.ChatBoxView } - * @example _converse.api.listen.on('chatBoxMaximized', view => { ... }); - */ - - api.trigger('chatBoxMaximized', model); -} -/** - * Handler which gets called when a {@link _converse#ChatBox} has it's - * `minimized` property set to true. - * - * Will trigger {@link _converse#chatBoxMinimized} - * @returns {_converse.ChatBoxView|_converse.ChatRoomView} - */ - - -function onMinimized(model) { - /** - * Triggered when a previously maximized chat gets Minimized - * @event _converse#chatBoxMinimized - * @type { _converse.ChatBoxView } - * @example _converse.api.listen.on('chatBoxMinimized', view => { ... }); - */ - api.trigger('chatBoxMinimized', model); -} - -function onMinimizedChanged(model) { - if (model.get('minimized')) { - onMinimized(model); - } else { - onMaximized(model); - } -} -;// CONCATENATED MODULE: ./src/plugins/minimize/components/minimized-chat.js - - - - -class MinimizedChat extends CustomElement { - static get properties() { - return { - model: { - type: Object - }, - title: { - type: String - }, - type: { - type: String - }, - num_unread: { - type: Number - } - }; - } - - render() { - const data = { - 'close': ev => this.close(ev), - 'num_unread': this.num_unread, - 'restore': ev => this.restore(ev), - 'title': this.title, - 'type': this.type - }; - return trimmed_chat(data); - } - - close(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - this.model.close(); - } - - restore(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - maximize(this.model); - } - -} -api.elements.define('converse-minimized-chat', MinimizedChat); -;// CONCATENATED MODULE: ./src/plugins/minimize/toggle.js - -const MinimizedChatsToggle = Model.extend({ - defaults: { - 'collapsed': false - } -}); -/* harmony default export */ const minimize_toggle = (MinimizedChatsToggle); -;// CONCATENATED MODULE: ./src/plugins/minimize/templates/chats-panel.js - - -/* harmony default export */ const chats_panel = (o => T``); -;// CONCATENATED MODULE: ./src/plugins/minimize/view.js - - - - - -class MinimizedChats extends CustomElement { - constructor() { - super(); - this.initialize(); - } - - async initialize() { - this.model = shared_converse.chatboxes; - await this.initToggle(); - this.listenTo(this.minchats, 'change:collapsed', this.requestUpdate); - this.listenTo(this.model, 'add', this.requestUpdate); - this.listenTo(this.model, 'change:fullname', this.requestUpdate); - this.listenTo(this.model, 'change:jid', this.requestUpdate); - this.listenTo(this.model, 'change:minimized', this.requestUpdate); - this.listenTo(this.model, 'change:name', this.requestUpdate); - this.listenTo(this.model, 'change:num_unread', this.requestUpdate); - this.listenTo(this.model, 'remove', this.requestUpdate); - this.listenTo(shared_converse, 'connected', this.requestUpdate); - this.listenTo(shared_converse, 'reconnected', this.requestUpdate); - this.listenTo(shared_converse, 'disconnected', this.requestUpdate); - } - - render() { - const chats = this.model.where({ - 'minimized': true - }); - const num_unread = chats.reduce((acc, chat) => acc + chat.get('num_unread'), 0); - const num_minimized = chats.reduce((acc, chat) => acc + (chat.get('minimized') ? 1 : 0), 0); - const collapsed = this.minchats.get('collapsed'); - const data = { - chats, - num_unread, - num_minimized, - collapsed - }; - - data.toggle = ev => this.toggle(ev); - - return chats_panel(data); - } - - async initToggle() { - const id = `converse.minchatstoggle-${shared_converse.bare_jid}`; - this.minchats = new minimize_toggle({ - id - }); - initStorage(this.minchats, id, 'session'); - await new Promise(resolve => this.minchats.fetch({ - 'success': resolve, - 'error': resolve - })); - } - - toggle(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - this.minchats.save({ - 'collapsed': !this.minchats.get('collapsed') - }); - } - -} -api.elements.define('converse-minimized-chats', MinimizedChats); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/minimize/styles/minimize.scss -var styles_minimize = __webpack_require__(7926); -;// CONCATENATED MODULE: ./src/plugins/minimize/styles/minimize.scss - - - - - - - - - - - -var minimize_options = {}; - -minimize_options.styleTagTransform = (styleTagTransform_default()); -minimize_options.setAttributes = (setAttributesWithoutAttributes_default()); - - minimize_options.insert = insertBySelector_default().bind(null, "head"); - -minimize_options.domAPI = (styleDomAPI_default()); -minimize_options.insertStyleElement = (insertStyleElement_default()); - -var minimize_update = injectStylesIntoStyleTag_default()(styles_minimize/* default */.Z, minimize_options); - - - - - /* harmony default export */ const minimize_styles_minimize = (styles_minimize/* default */.Z && styles_minimize/* default.locals */.Z.locals ? styles_minimize/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/minimize/index.js -/** - * @module converse-minimize - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - - -const { - dayjs: minimize_dayjs -} = core_converse.env; -core_converse.plugins.add('converse-minimize', { - /* Optional dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. They are called "optional" because they might not be - * available, in which case any overrides applicable to them will be - * ignored. - * - * It's possible however to make optional dependencies non-optional. - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. - * - * NB: These plugins need to have already been loaded via require.js. - */ - dependencies: ["converse-chatview", "converse-controlbox", "converse-muc-views", "converse-headlines-view", "converse-dragresize"], - - enabled(_converse) { - return _converse.api.settings.get("view_mode") === 'overlayed'; - }, - - overrides: { - // Overrides mentioned here will be picked up by converse.js's - // plugin architecture they will replace existing methods on the - // relevant objects or classes. - // - // New functions which don't exist yet can also be added. - ChatBox: { - initialize() { - this.__super__.initialize.apply(this, arguments); - - this.on('change:hidden', m => !m.get('hidden') && maximize(this), this); - - if (this.get('id') === 'controlbox') { - return; - } - - this.save({ - 'minimized': this.get('minimized') || false, - 'time_minimized': this.get('time_minimized') || minimize_dayjs() - }); - }, - - maybeShow(force) { - if (!force && this.get('minimized')) { - // Must return the chatbox - return this; - } - - return this.__super__.maybeShow.apply(this, arguments); - }, - - isHidden() { - return this.__super__.isHidden.call(this) || this.get('minimized'); - } - - }, - ChatBoxView: { - isNewMessageHidden() { - return this.model.get('minimized') || this.__super__.isNewMessageHidden.apply(this, arguments); - }, - - setChatBoxHeight(height) { - if (!this.model.get('minimized')) { - return this.__super__.setChatBoxHeight.call(this, height); - } - }, - - setChatBoxWidth(width) { - if (!this.model.get('minimized')) { - return this.__super__.setChatBoxWidth.call(this, width); - } - } - - } - }, - - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by Converse.js's plugin machinery. - */ - api.settings.extend({ - 'no_trimming': false - }); - api.promises.add('minimizedChatsInitialized'); - shared_converse.MinimizedChatsToggle = minimize_toggle; - shared_converse.MinimizedChats = MinimizedChats; - shared_converse.minimize = {}; - shared_converse.minimize.trimChats = trimChats; - shared_converse.minimize.minimize = minimize; - shared_converse.minimize.maximize = maximize; - - function onChatInitialized(model) { - model.on('change:minimized', () => onMinimizedChanged(model)); - } - /************************ BEGIN Event Handlers ************************/ - - - api.listen.on('chatBoxViewInitialized', view => shared_converse.minimize.trimChats(view)); - api.listen.on('chatRoomViewInitialized', view => shared_converse.minimize.trimChats(view)); - api.listen.on('chatBoxMaximized', view => shared_converse.minimize.trimChats(view)); - api.listen.on('controlBoxOpened', view => shared_converse.minimize.trimChats(view)); - api.listen.on('chatBoxInitialized', onChatInitialized); - api.listen.on('chatRoomInitialized', onChatInitialized); - api.listen.on('getHeadingButtons', (view, buttons) => { - if (view.model.get('type') === shared_converse.CHATROOMS_TYPE) { - return addMinimizeButtonToMUC(view, buttons); - } else { - return addMinimizeButtonToChat(view, buttons); - } - }); - const debouncedTrimChats = lodash_es_debounce(() => shared_converse.minimize.trimChats(), 250); - api.listen.on('registeredGlobalEventHandlers', () => window.addEventListener("resize", debouncedTrimChats)); - api.listen.on('unregisteredGlobalEventHandlers', () => window.removeEventListener("resize", debouncedTrimChats)); - } - -}); -;// CONCATENATED MODULE: ./src/shared/autocomplete/utils.js - -const autocomplete_utils_u = core_converse.env.utils; -const utils_helpers = { - getElement(expr, el) { - return typeof expr === 'string' ? (el || document).querySelector(expr) : expr || null; - }, - - bind(element, o) { - if (element) { - for (var event in o) { - if (!Object.prototype.hasOwnProperty.call(o, event)) { - continue; - } - - const callback = o[event]; - event.split(/\s+/).forEach(event => element.addEventListener(event, callback)); - } - } - }, - - unbind(element, o) { - if (element) { - for (var event in o) { - if (!Object.prototype.hasOwnProperty.call(o, event)) { - continue; - } - - const callback = o[event]; - event.split(/\s+/).forEach(event => element.removeEventListener(event, callback)); - } - } - }, - - regExpEscape(s) { - return s.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); - }, - - isMention(word, ac_triggers) { - return ac_triggers.includes(word[0]) || autocomplete_utils_u.isMentionBoundary(word[0]) && ac_triggers.includes(word[1]); - } - -}; -const FILTER_CONTAINS = function (text, input) { - return RegExp(utils_helpers.regExpEscape(input.trim()), 'i').test(text); -}; -const FILTER_STARTSWITH = function (text, input) { - return RegExp('^' + utils_helpers.regExpEscape(input.trim()), 'i').test(text); -}; - -const SORT_BY_LENGTH = function (a, b) { - if (a.length !== b.length) { - return a.length - b.length; - } - - return a < b ? -1 : 1; -}; - -const SORT_BY_QUERY_POSITION = function (a, b) { - const query = a.query.toLowerCase(); - const x = a.label.toLowerCase().indexOf(query); - const y = b.label.toLowerCase().indexOf(query); - - if (x === y) { - return SORT_BY_LENGTH(a, b); - } - - return (x === -1 ? Infinity : x) < (y === -1 ? Infinity : y) ? -1 : 1; -}; -const ITEM = (text, input) => { - input = input.trim(); - const element = document.createElement('li'); - element.setAttribute('aria-selected', 'false'); - const regex = new RegExp('(' + input + ')', 'ig'); - const parts = input ? text.split(regex) : [text]; - parts.forEach(txt => { - if (input && txt.match(regex)) { - const match = document.createElement('mark'); - match.textContent = txt; - element.appendChild(match); - } else { - element.appendChild(document.createTextNode(txt)); - } - }); - return element; -}; -;// CONCATENATED MODULE: ./src/shared/autocomplete/suggestion.js -/** - * An autocomplete suggestion - */ -class Suggestion extends String { - /** - * @param { Any } data - The auto-complete data. Ideally an object e.g. { label, value }, - * which specifies the value and human-presentable label of the suggestion. - * @param { string } query - The query string being auto-completed - */ - constructor(data, query) { - super(); - const o = Array.isArray(data) ? { - label: data[0], - value: data[1] - } : typeof data === 'object' && 'label' in data && 'value' in data ? data : { - label: data, - value: data - }; - this.label = o.label || o.value; - this.value = o.value; - this.query = query; - } - - get lenth() { - return this.label.length; - } - - toString() { - return '' + this.label; - } - - valueOf() { - return this.toString(); - } - -} - -/* harmony default export */ const suggestion = (Suggestion); -;// CONCATENATED MODULE: ./src/shared/autocomplete/autocomplete.js -/** - * @copyright Lea Verou and the Converse.js contributors - * @description - * Started as a fork of Lea Verou's "Awesomplete" - * https://leaverou.github.io/awesomplete/ - * @license Mozilla Public License (MPLv2) - */ - - - - -const autocomplete_u = core_converse.env.utils; -class AutoComplete { - constructor(el, config = {}) { - this.suggestions = []; - this.is_opened = false; - - if (autocomplete_u.hasClass('suggestion-box', el)) { - this.container = el; - } else { - this.container = el.querySelector('.suggestion-box'); - } - - this.input = this.container.querySelector('.suggestion-box__input'); - this.input.setAttribute("aria-autocomplete", "list"); - this.ul = this.container.querySelector('.suggestion-box__results'); - this.status = this.container.querySelector('.suggestion-box__additions'); - Object.assign(this, { - 'match_current_word': false, - // Match only the current word, otherwise all input is matched - 'ac_triggers': [], - // Array of keys (`ev.key`) values that will trigger auto-complete - 'include_triggers': [], - // Array of trigger keys which should be included in the returned value - 'min_chars': 2, - 'max_items': 10, - 'auto_evaluate': true, - // Should evaluation happen automatically without any particular key as trigger? - 'auto_first': false, - // Should the first element be automatically selected? - 'data': a => a, - 'filter': FILTER_CONTAINS, - 'sort': config.sort === false ? false : SORT_BY_QUERY_POSITION, - 'item': ITEM - }, config); - this.index = -1; - this.bindEvents(); - - if (this.input.hasAttribute("list")) { - this.list = "#" + this.input.getAttribute("list"); - this.input.removeAttribute("list"); - } else { - this.list = this.input.getAttribute("data-list") || config.list || []; - } - } - - bindEvents() { - // Bind events - const input = { - "blur": () => this.close({ - 'reason': 'blur' - }) - }; - - if (this.auto_evaluate) { - input["input"] = () => this.evaluate(); - } - - this._events = { - 'input': input, - 'form': { - "submit": () => this.close({ - 'reason': 'submit' - }) - }, - 'ul': { - "mousedown": ev => this.onMouseDown(ev), - "mouseover": ev => this.onMouseOver(ev) - } - }; - utils_helpers.bind(this.input, this._events.input); - utils_helpers.bind(this.input.form, this._events.form); - utils_helpers.bind(this.ul, this._events.ul); - } - - set list(list) { - if (Array.isArray(list) || typeof list === "function") { - this._list = list; - } else if (typeof list === "string" && list.includes(",")) { - this._list = list.split(/\s*,\s*/); - } else { - var _helpers$getElement; - - // Element or CSS selector - const children = ((_helpers$getElement = utils_helpers.getElement(list)) === null || _helpers$getElement === void 0 ? void 0 : _helpers$getElement.children) || []; - this._list = Array.from(children).filter(el => !el.disabled).map(el => { - const text = el.textContent.trim(); - const value = el.value || text; - const label = el.label || text; - return value !== "" ? { - label, - value - } : null; - }).filter(i => i); - } - - if (document.activeElement === this.input) { - this.evaluate(); - } - } - - get list() { - return this._list; - } - - get selected() { - return this.index > -1; - } - - get opened() { - return this.is_opened; - } - - close(o) { - if (!this.opened) { - return; - } - - this.ul.setAttribute("hidden", ""); - this.is_opened = false; - this.index = -1; - this.trigger("suggestion-box-close", o || {}); - } - - insertValue(suggestion) { - if (this.match_current_word) { - autocomplete_u.replaceCurrentWord(this.input, suggestion.value); - } else { - this.input.value = suggestion.value; - } - } - - open() { - this.ul.removeAttribute("hidden"); - this.is_opened = true; - - if (this.auto_first && this.index === -1) { - this.goto(0); - } - - this.trigger("suggestion-box-open"); - } - - destroy() { - //remove events from the input and its form - utils_helpers.unbind(this.input, this._events.input); - utils_helpers.unbind(this.input.form, this._events.form); - this.input.removeAttribute("aria-autocomplete"); - } - - next() { - const count = this.ul.children.length; - this.goto(this.index < count - 1 ? this.index + 1 : count ? 0 : -1); - } - - previous() { - const count = this.ul.children.length, - pos = this.index - 1; - this.goto(this.selected && pos !== -1 ? pos : count - 1); - } - - goto(i) { - // Should not be used directly, highlights specific item without any checks! - const list = this.ul.children; - - if (this.selected) { - list[this.index].setAttribute("aria-selected", "false"); - } - - this.index = i; - - if (i > -1 && list.length > 0) { - list[i].setAttribute("aria-selected", "true"); - list[i].focus(); - this.status.textContent = list[i].textContent; // scroll to highlighted element in case parent's height is fixed - - this.ul.scrollTop = list[i].offsetTop - this.ul.clientHeight + list[i].clientHeight; - this.trigger("suggestion-box-highlight", { - 'text': this.suggestions[this.index] - }); - } - } - - select(selected) { - if (selected) { - this.index = autocomplete_u.siblingIndex(selected); - } else { - selected = this.ul.children[this.index]; - } - - if (selected) { - const suggestion = this.suggestions[this.index]; - this.insertValue(suggestion); - this.close({ - 'reason': 'select' - }); - this.auto_completing = false; - this.trigger("suggestion-box-selectcomplete", { - 'text': suggestion - }); - } - } - - onMouseOver(ev) { - const li = autocomplete_u.ancestor(ev.target, 'li'); - - if (li) { - this.goto(Array.prototype.slice.call(this.ul.children).indexOf(li)); - } - } - - onMouseDown(ev) { - if (ev.button !== 0) { - return; // Only select on left click - } - - const li = autocomplete_u.ancestor(ev.target, 'li'); - - if (li) { - ev.preventDefault(); - this.select(li, ev.target); - } - } - - onKeyDown(ev) { - if (this.opened) { - if ([core_converse.keycodes.ENTER, core_converse.keycodes.TAB].includes(ev.keyCode) && this.selected) { - ev.preventDefault(); - ev.stopPropagation(); - this.select(); - return true; - } else if (ev.keyCode === core_converse.keycodes.ESCAPE) { - this.close({ - 'reason': 'esc' - }); - return true; - } else if ([core_converse.keycodes.UP_ARROW, core_converse.keycodes.DOWN_ARROW].includes(ev.keyCode)) { - ev.preventDefault(); - ev.stopPropagation(); - this[ev.keyCode === core_converse.keycodes.UP_ARROW ? "previous" : "next"](); - return true; - } - } - - if ([core_converse.keycodes.SHIFT, core_converse.keycodes.META, core_converse.keycodes.META_RIGHT, core_converse.keycodes.ESCAPE, core_converse.keycodes.ALT].includes(ev.keyCode)) { - return; - } - - if (this.ac_triggers.includes(ev.key)) { - if (ev.key === "Tab") { - ev.preventDefault(); - } - - this.auto_completing = true; - } else if (ev.key === "Backspace") { - const word = autocomplete_u.getCurrentWord(ev.target, ev.target.selectionEnd - 1); - - if (utils_helpers.isMention(word, this.ac_triggers)) { - this.auto_completing = true; - } - } - } - - async evaluate(ev) { - const selecting = this.selected && ev && (ev.keyCode === core_converse.keycodes.UP_ARROW || ev.keyCode === core_converse.keycodes.DOWN_ARROW); - - if (!this.auto_evaluate && !this.auto_completing || selecting) { - return; - } - - const list = typeof this._list === "function" ? await this._list() : this._list; - - if (list.length === 0) { - return; - } - - let value = this.match_current_word ? autocomplete_u.getCurrentWord(this.input) : this.input.value; - const contains_trigger = utils_helpers.isMention(value, this.ac_triggers); - - if (contains_trigger) { - this.auto_completing = true; - - if (!this.include_triggers.includes(ev.key)) { - value = autocomplete_u.isMentionBoundary(value[0]) ? value.slice('2') : value.slice('1'); - } - } - - if ((contains_trigger || value.length) && value.length >= this.min_chars) { - this.index = -1; // Populate list with options that match - - this.ul.innerHTML = ""; - this.suggestions = list.map(item => new suggestion(this.data(item, value), value)).filter(item => this.filter(item, value)); - - if (this.sort !== false) { - this.suggestions = this.suggestions.sort(this.sort); - } - - this.suggestions = this.suggestions.slice(0, this.max_items); - this.suggestions.forEach(text => this.ul.appendChild(this.item(text, value))); - - if (this.ul.children.length === 0) { - this.close({ - 'reason': 'nomatches' - }); - } else { - this.open(); - } - } else { - this.close({ - 'reason': 'nomatches' - }); - - if (!contains_trigger) { - this.auto_completing = false; - } - } - } - -} // Make it an event emitter - -Object.assign(AutoComplete.prototype, Events); -/* harmony default export */ const autocomplete = (AutoComplete); -;// CONCATENATED MODULE: ./src/shared/autocomplete/component.js - - - - - -class AutoCompleteComponent extends CustomElement { - static get properties() { - return { - 'getAutoCompleteList': { - type: Function - }, - 'auto_evaluate': { - type: Boolean - }, - 'auto_first': { - type: Boolean - }, - // Should the first element be automatically selected? - 'filter': { - type: String - }, - 'include_triggers': { - type: String - }, - 'min_chars': { - type: Number - }, - 'name': { - type: String - }, - 'placeholder': { - type: String - }, - 'triggers': { - type: String - } - }; - } - - constructor() { - super(); - this.auto_evaluate = true; // Should evaluation happen automatically without any particular key as trigger? - - this.auto_first = false; // Should the first element be automatically selected? - - this.filter = 'contains'; - this.include_triggers = ''; // Space separated chars which should be included in the returned value - - this.match_current_word = false; // Match only the current word, otherwise all input is matched - - this.max_items = 10; - this.min_chars = 1; - this.triggers = ''; // String of space separated chars - } - - render() { - return T` -
    - - - -
    - `; - } - - firstUpdated() { - this.auto_complete = new autocomplete(this.firstElementChild, { - 'ac_triggers': this.triggers.split(' '), - 'auto_evaluate': this.auto_evaluate, - 'auto_first': this.auto_first, - 'filter': this.filter == 'contains' ? FILTER_CONTAINS : FILTER_STARTSWITH, - 'include_triggers': [], - 'list': () => this.getAutoCompleteList(), - 'match_current_word': true, - 'max_items': this.max_items, - 'min_chars': this.min_chars - }); - this.auto_complete.on('suggestion-box-selectcomplete', () => this.auto_completing = false); - } - - onKeyDown(ev) { - this.auto_complete.onKeyDown(ev); - } - - onKeyUp(ev) { - this.auto_complete.evaluate(ev); - } - -} -api.elements.define('converse-autocomplete', AutoCompleteComponent); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/shared/autocomplete/styles/_autocomplete.scss -var _autocomplete = __webpack_require__(8481); -;// CONCATENATED MODULE: ./src/shared/autocomplete/styles/_autocomplete.scss - - - - - - - - - - - -var _autocomplete_options = {}; - -_autocomplete_options.styleTagTransform = (styleTagTransform_default()); -_autocomplete_options.setAttributes = (setAttributesWithoutAttributes_default()); - - _autocomplete_options.insert = insertBySelector_default().bind(null, "head"); - -_autocomplete_options.domAPI = (styleDomAPI_default()); -_autocomplete_options.insertStyleElement = (insertStyleElement_default()); - -var _autocomplete_update = injectStylesIntoStyleTag_default()(_autocomplete/* default */.Z, _autocomplete_options); - - - - - /* harmony default export */ const styles_autocomplete = (_autocomplete/* default */.Z && _autocomplete/* default.locals */.Z.locals ? _autocomplete/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/shared/autocomplete/index.js - - - - - -shared_converse.FILTER_CONTAINS = FILTER_CONTAINS; -shared_converse.FILTER_STARTSWITH = FILTER_STARTSWITH; -shared_converse.AutoComplete = autocomplete; -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/ad-hoc-command-form.js - - -/* harmony default export */ const ad_hoc_command_form = ((o, command) => { - const i18n_hide = __('Hide'); - - const i18n_run = __('Execute'); - - return T` -
    - ${command.alert ? T`` : ''} -
    - - - -

    ${command.instructions}

    - ${command.fields} -
    -
    - - -
    -
    - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/ad-hoc-command.js - - -/* harmony default export */ const ad_hoc_command = ((o, command) => T` -
  • - - ${command.node === o.showform ? ad_hoc_command_form(o, command) : ''} -
  • -`); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/moderator-tools.js - - - - -function getRoleHelpText(role) { - if (role === 'moderator') { - return __("Moderators are privileged users who can change the roles of other users (except those with admin or owner affiliations."); - } else if (role === 'participant') { - return __("The default role, implies that you can read and write messages."); - } else if (role == 'visitor') { - return __("Visitors aren't allowed to write messages in a moderated multi-user chat."); - } -} - -function getAffiliationHelpText(aff) { - if (aff === 'owner') { - return __("Owner is the highest affiliation. Owners can modify roles and affiliations of all other users."); - } else if (aff === 'admin') { - return __("Admin is the 2nd highest affiliation. Admins can modify roles and affiliations of all other users except owners."); - } else if (aff === 'outcast') { - return __("To ban a user, you give them the affiliation of \"outcast\"."); - } -} - -const role_option = o => T` - -`; - -const affiliation_option = o => T` - -`; - -const tpl_set_role_form = o => { - const i18n_change_role = __('Change role'); - - const i18n_new_role = __('New Role'); - - const i18n_reason = __('Reason'); - - return T` - - `; -}; - -const role_form_toggle = o => T` - - - `; - -const role_list_item = o => T` -
  • -
      -
    • -
      JID: ${o.item.jid}
      -
    • -
    • -
      Nickname: ${o.item.nick}
      -
    • -
    • -
      Role: ${o.item.role} ${o.assignable_roles.length ? role_form_toggle(o) : ''}
      - ${o.assignable_roles.length ? tpl_set_role_form(o) : ''} -
    • -
    -
  • -`; - -const tpl_set_affiliation_form = o => { - const i18n_change_affiliation = __('Change affiliation'); - - const i18n_new_affiliation = __('New affiliation'); - - const i18n_reason = __('Reason'); - - return T` - - `; -}; - -const affiliation_form_toggle = o => T` - - - `; - -const affiliation_list_item = o => T` -
  • -
      -
    • -
      JID: ${o.item.jid}
      -
    • -
    • -
      Nickname: ${o.item.nick}
      -
    • -
    • -
      Affiliation: ${o.item.affiliation} ${o.assignable_affiliations.length ? affiliation_form_toggle(o) : ''}
      - ${o.assignable_affiliations.length ? tpl_set_affiliation_form(o) : ''} -
    • -
    -
  • -`; - -const tpl_navigation = () => T` - -`; - -/* harmony default export */ const moderator_tools = (o => { - const i18n_affiliation = __('Affiliation'); - - const i18n_no_users_with_aff = __('No users with that affiliation found.'); - - const i18n_no_users_with_role = __('No users with that role found.'); - - const i18n_filter = __('Type here to filter the search results'); - - const i18n_role = __('Role'); - - const i18n_show_users = __('Show users'); - - const i18n_helptext_role = __("Roles are assigned to users to grant or deny them certain abilities in a multi-user chat. " + "They're assigned either explicitly or implicitly as part of an affiliation. " + "A role that's not due to an affiliation, is only valid for the duration of the user's session."); - - const i18n_helptext_affiliation = __("An affiliation is a long-lived entitlement which typically implies a certain role and which " + "grants privileges and responsibilities. For example admins and owners automatically have the " + "moderator role."); - - const show_both_tabs = o.queryable_roles.length && o.queryable_affiliations.length; - return T` - ${o.alert_message ? T`` : ''} - ${show_both_tabs ? tpl_navigation() : ''} - -
    - - ${o.queryable_affiliations.length ? T` -
    -
    -

    ${i18n_helptext_affiliation}

    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - ${Array.isArray(o.users_with_affiliation) && o.users_with_affiliation.length > 5 ? T`` : ''} -
    -
    - - ${getAffiliationHelpText(o.affiliation) ? T`

    ${getAffiliationHelpText(o.affiliation)}

    ` : ''} -
    -
    -
    -
      - ${o.loading_users_with_affiliation ? T`
    • ${spinner()}
    • ` : ''} - ${Array.isArray(o.users_with_affiliation) && o.users_with_affiliation.length === 0 ? T`
    • ${i18n_no_users_with_aff}
    • ` : ''} - - ${o.users_with_affiliation instanceof Error ? T`
    • ${o.users_with_affiliation.message}
    • ` : (o.users_with_affiliation || []).map(item => (item.nick || item.jid).match(new RegExp(o.affiliations_filter, 'i')) ? affiliation_list_item(Object.assign({ - item - }, o)) : '')} -
    -
    -
    ` : ''} - - ${o.queryable_roles.length ? T` -
    -
    -

    ${i18n_helptext_role}

    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - ${Array.isArray(o.users_with_role) && o.users_with_role.length > 5 ? T`` : ''} -
    -
    - - ${getRoleHelpText(o.role) ? T`

    ${getRoleHelpText(o.role)}

    ` : ''} -
    -
    -
    -
      - ${o.loading_users_with_role ? T`
    • ${spinner()}
    • ` : ''} - ${o.users_with_role && o.users_with_role.length === 0 ? T`
    • ${i18n_no_users_with_role}
    • ` : ''} - ${(o.users_with_role || []).map(item => item.nick.match(o.roles_filter) ? role_list_item(Object.assign({ - item - }, o)) : '')} -
    -
    -
    ` : ''} -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/modtools.js - - - - - - - - - -const { - Strophe: modtools_Strophe, - sizzle: modtools_sizzle, - u: modtools_u -} = core_converse.env; -class ModeratorTools extends CustomElement { - static get properties() { - return { - affiliation: { - type: String - }, - affiliations_filter: { - type: String, - attribute: false - }, - alert_message: { - type: String, - attribute: false - }, - alert_type: { - type: String, - attribute: false - }, - jid: { - type: String - }, - muc: { - type: Object, - attribute: false - }, - role: { - type: String - }, - roles_filter: { - type: String, - attribute: false - }, - users_with_affiliation: { - type: Array, - attribute: false - }, - users_with_role: { - type: Array, - attribute: false - } - }; - } - - constructor() { - super(); - this.affiliation = ''; - this.affiliations_filter = ''; - this.role = ''; - this.roles_filter = ''; - } - - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - updated(changed) { - changed.has('role') && this.onSearchRoleChange(); - changed.has('affiliation') && this.onSearchAffiliationChange(); - changed.has('jid') && changed.get('jid') && this.initialize(); - } - - async initialize() { - this.initialized = getOpenPromise(); - const muc = await api.rooms.get(this.jid); - await muc.initialized; - this.muc = muc; - this.initialized.resolve(); - } - - render() { - var _this$muc; - - if ((_this$muc = this.muc) !== null && _this$muc !== void 0 && _this$muc.occupants) { - const occupant = this.muc.occupants.findWhere({ - 'jid': shared_converse.bare_jid - }); - return moderator_tools({ - 'affiliations_filter': this.affiliations_filter, - 'alert_message': this.alert_message, - 'alert_type': this.alert_type, - 'assignAffiliation': ev => this.assignAffiliation(ev), - 'assignRole': ev => this.assignRole(ev), - 'assignable_affiliations': getAssignableAffiliations(occupant), - 'assignable_roles': getAssignableRoles(occupant), - 'filterAffiliationResults': ev => this.filterAffiliationResults(ev), - 'filterRoleResults': ev => this.filterRoleResults(ev), - 'loading_users_with_affiliation': this.loading_users_with_affiliation, - 'queryAffiliation': ev => this.queryAffiliation(ev), - 'queryRole': ev => this.queryRole(ev), - 'queryable_affiliations': AFFILIATIONS.filter(a => !api.settings.get('modtools_disable_query').includes(a)), - 'queryable_roles': ROLES.filter(a => !api.settings.get('modtools_disable_query').includes(a)), - 'roles_filter': this.roles_filter, - 'switchTab': ev => this.switchTab(ev), - 'toggleForm': ev => this.toggleForm(ev), - 'users_with_affiliation': this.users_with_affiliation, - 'users_with_role': this.users_with_role - }); - } else { - return ''; - } - } - - async onSearchAffiliationChange() { - if (!this.affiliation) { - return; - } - - await this.initialized; - this.clearAlert(); - this.loading_users_with_affiliation = true; - this.users_with_affiliation = null; - - if (this.shouldFetchAffiliationsList()) { - const result = await getAffiliationList(this.affiliation, this.jid); - - if (result instanceof Error) { - this.alert(result.message, 'danger'); - this.users_with_affiliation = []; - } else { - this.users_with_affiliation = result; - } - } else { - this.users_with_affiliation = this.muc.getOccupantsWithAffiliation(this.affiliation); - } - - this.loading_users_with_affiliation = false; - } - - async onSearchRoleChange() { - if (!this.role) { - return; - } - - await this.initialized; - this.clearAlert(); - this.users_with_role = this.muc.getOccupantsWithRole(this.role); - } - - shouldFetchAffiliationsList() { - const affiliation = this.affiliation; - - if (affiliation === 'none') { - return false; - } - - const chatroom = this.muc; - const auto_fetched_affs = chatroom.occupants.getAutoFetchedAffiliationLists(); - - if (auto_fetched_affs.includes(affiliation)) { - return false; - } else { - return true; - } - } - - toggleForm(ev) { - // eslint-disable-line class-methods-use-this - ev.stopPropagation(); - ev.preventDefault(); - const toggle = modtools_u.ancestor(ev.target, '.toggle-form'); - const form_class = toggle.getAttribute('data-form'); - const form = modtools_u.ancestor(toggle, '.list-group-item').querySelector(`.${form_class}`); - - if (modtools_u.hasClass('hidden', form)) { - modtools_u.removeClass('hidden', form); - } else { - modtools_u.addClass('hidden', form); - } - } - - filterRoleResults(ev) { - this.roles_filter = ev.target.value; - this.render(); - } - - filterAffiliationResults(ev) { - this.affiliations_filter = ev.target.value; - } - - queryRole(ev) { - ev.stopPropagation(); - ev.preventDefault(); - const data = new FormData(ev.target); - const role = data.get('role'); - this.role = null; - this.role = role; - } - - queryAffiliation(ev) { - ev.stopPropagation(); - ev.preventDefault(); - const data = new FormData(ev.target); - const affiliation = data.get('affiliation'); - this.affiliation = null; - this.affiliation = affiliation; - } - - alert(message, type) { - this.alert_message = message; - this.alert_type = type; - } - - clearAlert() { - this.alert_message = undefined; - this.alert_type = undefined; - } - - async assignAffiliation(ev) { - ev.stopPropagation(); - ev.preventDefault(); - this.clearAlert(); - const data = new FormData(ev.target); - const affiliation = data.get('affiliation'); - const attrs = { - 'jid': data.get('jid'), - 'reason': data.get('reason') - }; - const current_affiliation = this.affiliation; - const muc_jid = this.muc.get('jid'); - - try { - await setAffiliation(affiliation, muc_jid, [attrs]); - } catch (e) { - if (e === null) { - this.alert(__('Timeout error while trying to set the affiliation'), 'danger'); - } else if (modtools_sizzle(`not-allowed[xmlns="${modtools_Strophe.NS.STANZAS}"]`, e).length) { - this.alert(__("Sorry, you're not allowed to make that change"), 'danger'); - } else { - this.alert(__('Sorry, something went wrong while trying to set the affiliation'), 'danger'); - } - - headless_log.error(e); - return; - } - - await this.muc.occupants.fetchMembers(); - this.affiliation = null; - this.affiliation = current_affiliation; - this.alert(__('Affiliation changed'), 'primary'); - } - - assignRole(ev) { - ev.stopPropagation(); - ev.preventDefault(); - this.clearAlert(); - const data = new FormData(ev.target); - const occupant = this.muc.getOccupant(data.get('jid') || data.get('nick')); - const role = data.get('role'); - const reason = data.get('reason'); - const current_role = this.role; - this.muc.setRole(occupant, role, reason, () => { - this.alert(__('Role changed'), 'primary'); - this.role = null; - this.role = current_role; - }, e => { - if (modtools_sizzle(`not-allowed[xmlns="${modtools_Strophe.NS.STANZAS}"]`, e).length) { - this.alert(__("You're not allowed to make that change"), 'danger'); - } else { - this.alert(__('Sorry, something went wrong while trying to set the role'), 'danger'); - - if (modtools_u.isErrorObject(e)) { - headless_log.error(e); - } - } - }); - } - -} -api.elements.define('converse-modtools', ModeratorTools); -;// CONCATENATED MODULE: ./src/plugins/muc-views/modals/templates/moderator-tools.js - - - -/* harmony default export */ const templates_moderator_tools = (o => { - const i18n_moderator_tools = __('Moderator Tools'); - - return T` - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/modals/moderator-tools.js - - - -const ModeratorToolsModal = base.extend({ - id: "converse-modtools-modal", - persistent: true, - - initialize(attrs) { - this.jid = attrs.jid; - this.affiliation = attrs.affiliation; - base.prototype.initialize.apply(this, arguments); - }, - - toHTML() { - return templates_moderator_tools(this); - } - -}); -/* harmony default export */ const modals_moderator_tools = (ModeratorToolsModal); -;// CONCATENATED MODULE: ./src/plugins/muc-views/utils.js - - - - - - - - -const { - Strophe: muc_views_utils_Strophe, - $pres: muc_views_utils_$pres, - $iq: muc_views_utils_$iq, - sizzle: muc_views_utils_sizzle, - u: muc_views_utils_u -} = core_converse.env; -const COMMAND_TO_AFFILIATION = { - 'admin': 'admin', - 'ban': 'outcast', - 'member': 'member', - 'owner': 'owner', - 'revoke': 'none' -}; -const COMMAND_TO_ROLE = { - 'deop': 'participant', - 'kick': 'none', - 'mute': 'visitor', - 'op': 'moderator', - 'voice': 'participant' -}; -function utils_clearHistory(jid) { - if (shared_converse.router.history.getFragment() === `converse/room?jid=${jid}`) { - shared_converse.router.navigate(''); - } -} -async function destroyMUC(model) { - const messages = [__('Are you sure you want to destroy this groupchat?')]; - let fields = [{ - 'name': 'challenge', - 'label': __('Please enter the XMPP address of this groupchat to confirm'), - 'challenge': model.get('jid'), - 'placeholder': __('name@example.org'), - 'required': true - }, { - 'name': 'reason', - 'label': __('Optional reason for destroying this groupchat'), - 'placeholder': __('Reason') - }, { - 'name': 'newjid', - 'label': __('Optional XMPP address for a new groupchat that replaces this one'), - 'placeholder': __('replacement@example.org') - }]; - - try { - var _fields$filter$pop, _fields$filter$pop2; - - fields = await api.confirm(__('Confirm'), messages, fields); - const reason = (_fields$filter$pop = fields.filter(f => f.name === 'reason').pop()) === null || _fields$filter$pop === void 0 ? void 0 : _fields$filter$pop.value; - const newjid = (_fields$filter$pop2 = fields.filter(f => f.name === 'newjid').pop()) === null || _fields$filter$pop2 === void 0 ? void 0 : _fields$filter$pop2.value; - return model.sendDestroyIQ(reason, newjid).then(() => model.close()); - } catch (e) { - headless_log.error(e); - } -} - -function setMUCDomain(domain, controlboxview) { - controlboxview.querySelector('converse-rooms-list').model.save('muc_domain', muc_views_utils_Strophe.getDomainFromJid(domain)); -} - -function setMUCDomainFromDisco(controlboxview) { - /* Check whether service discovery for the user's domain - * returned MUC information and use that to automatically - * set the MUC domain in the "Add groupchat" modal. - */ - function featureAdded(feature) { - if (!feature) { - return; - } - - if (feature.get('var') === muc_views_utils_Strophe.NS.MUC) { - feature.entity.getIdentity('conference', 'text').then(identity => { - if (identity) { - setMUCDomain(feature.get('from'), controlboxview); - } - }); - } - } - - api.waitUntil('discoInitialized').then(() => { - api.listen.on('serviceDiscovered', featureAdded); // Features could have been added before the controlbox was - // initialized. We're only interested in MUC - - shared_converse.disco_entities.each(entity => featureAdded(entity.features.findWhere({ - 'var': muc_views_utils_Strophe.NS.MUC - }))); - }).catch(e => headless_log.error(e)); -} - -function fetchAndSetMUCDomain(controlboxview) { - if (controlboxview.model.get('connected')) { - if (!controlboxview.querySelector('converse-rooms-list').model.get('muc_domain')) { - if (api.settings.get('muc_domain') === undefined) { - setMUCDomainFromDisco(controlboxview); - } else { - setMUCDomain(api.settings.get('muc_domain'), controlboxview); - } - } - } -} -function getNicknameRequiredTemplate(model) { - const jid = model.get('jid'); - - if (api.settings.get('muc_show_logs_before_join')) { - return T``; - } else { - return T``; - } -} -function getChatRoomBodyTemplate(o) { - const view = o.model.session.get('view'); - const jid = o.model.get('jid'); - const RS = core_converse.ROOMSTATUS; - const conn_status = o.model.session.get('connection_status'); - - if (view === core_converse.MUC.VIEWS.CONFIG) { - return T``; - } else if (view === core_converse.MUC.VIEWS.BOOKMARK) { - return T``; - } else { - return T` - ${conn_status == RS.PASSWORD_REQUIRED ? T`` : ''} - ${conn_status == RS.ENTERED ? T`` : ''} - ${conn_status == RS.CONNECTING ? spinner() : ''} - ${conn_status == RS.NICKNAME_REQUIRED ? getNicknameRequiredTemplate(o.model) : ''} - ${conn_status == RS.DISCONNECTED ? T`` : ''} - ${conn_status == RS.BANNED ? T`` : ''} - ${conn_status == RS.DESTROYED ? T`` : ''} - `; - } -} -function getAutoCompleteListItem(text, input) { - input = input.trim(); - const element = document.createElement('li'); - element.setAttribute('aria-selected', 'false'); - - if (api.settings.get('muc_mention_autocomplete_show_avatar')) { - const img = document.createElement('img'); - let dataUri = 'data:' + shared_converse.DEFAULT_IMAGE_TYPE + ';base64,' + shared_converse.DEFAULT_IMAGE; - - if (shared_converse.vcards) { - const vcard = shared_converse.vcards.findWhere({ - 'nickname': text - }); - - if (vcard) dataUri = 'data:' + vcard.get('image_type') + ';base64,' + vcard.get('image'); - } - - img.setAttribute('src', dataUri); - img.setAttribute('width', '22'); - img.setAttribute('class', 'avatar avatar-autocomplete'); - element.appendChild(img); - } - - const regex = new RegExp('(' + input + ')', 'ig'); - const parts = input ? text.split(regex) : [text]; - parts.forEach(txt => { - if (input && txt.match(regex)) { - const match = document.createElement('mark'); - match.textContent = txt; - element.appendChild(match); - } else { - element.appendChild(document.createTextNode(txt)); - } - }); - return element; -} -async function getAutoCompleteList() { - const models = [...(await api.rooms.get()), ...(await api.contacts.get())]; - const jids = [...new Set(models.map(o => muc_views_utils_Strophe.getDomainFromJid(o.get('jid'))))]; - return jids; -} -async function fetchCommandForm(command) { - const node = command.node; - const jid = command.jid; - const stanza = muc_views_utils_$iq({ - 'type': 'set', - 'to': jid - }).c('command', { - 'xmlns': muc_views_utils_Strophe.NS.ADHOC, - 'node': node, - 'action': 'execute' - }); - - try { - var _sizzle$pop; - - const iq = await api.sendIQ(stanza); - const cmd_el = muc_views_utils_sizzle(`command[xmlns="${muc_views_utils_Strophe.NS.ADHOC}"]`, iq).pop(); - command.sessionid = cmd_el.getAttribute('sessionid'); - command.instructions = (_sizzle$pop = muc_views_utils_sizzle('x[type="form"][xmlns="jabber:x:data"] instructions', cmd_el).pop()) === null || _sizzle$pop === void 0 ? void 0 : _sizzle$pop.textContent; - command.fields = muc_views_utils_sizzle('x[type="form"][xmlns="jabber:x:data"] field', cmd_el).map(f => muc_views_utils_u.xForm2TemplateResult(f, cmd_el)); - } catch (e) { - if (e === null) { - headless_log.error(`Error: timeout while trying to execute command for ${jid}`); - } else { - headless_log.error(`Error while trying to execute command for ${jid}`); - headless_log.error(e); - } - - command.fields = []; - } -} - -function setRole(muc, command, args, required_affiliations = [], required_roles = []) { - const role = COMMAND_TO_ROLE[command]; - - if (!role) { - throw Error(`ChatRoomView#setRole called with invalid command: ${command}`); - } - - if (!muc.verifyAffiliations(required_affiliations) || !muc.verifyRoles(required_roles)) { - return false; - } - - if (!muc.validateRoleOrAffiliationChangeArgs(command, args)) { - return false; - } - - const nick_or_jid = muc.getNickOrJIDFromCommandArgs(args); - - if (!nick_or_jid) { - return false; - } - - const reason = args.split(nick_or_jid, 2)[1].trim(); // We're guaranteed to have an occupant due to getNickOrJIDFromCommandArgs - - const occupant = muc.getOccupant(nick_or_jid); - muc.setRole(occupant, role, reason, undefined, e => muc.onCommandError(e)); - return true; -} - -function verifyAndSetAffiliation(muc, command, args, required_affiliations) { - const affiliation = COMMAND_TO_AFFILIATION[command]; - - if (!affiliation) { - throw Error(`verifyAffiliations called with invalid command: ${command}`); - } - - if (!muc.verifyAffiliations(required_affiliations)) { - return false; - } - - if (!muc.validateRoleOrAffiliationChangeArgs(command, args)) { - return false; - } - - const nick_or_jid = muc.getNickOrJIDFromCommandArgs(args); - - if (!nick_or_jid) { - return false; - } - - let jid; - const reason = args.split(nick_or_jid, 2)[1].trim(); - const occupant = muc.getOccupant(nick_or_jid); - - if (occupant) { - jid = occupant.get('jid'); - } else { - if (muc_views_utils_u.isValidJID(nick_or_jid)) { - jid = nick_or_jid; - } else { - const message = __("Couldn't find a participant with that nickname. " + 'They might have left the groupchat.'); - - muc.createMessage({ - message, - 'type': 'error' - }); - return; - } - } - - const attrs = { - jid, - reason - }; - - if (occupant && api.settings.get('auto_register_muc_nickname')) { - attrs['nick'] = occupant.get('nick'); - } - - setAffiliation(affiliation, muc.get('jid'), [attrs]).then(() => muc.occupants.fetchMembers()).catch(err => muc.onCommandError(err)); -} - -function showModeratorToolsModal(muc, affiliation) { - if (!muc.verifyRoles(['moderator'])) { - return; - } - - let modal = api.modal.get(modals_moderator_tools.id); - - if (modal) { - modal.affiliation = affiliation; - modal.render(); - } else { - modal = api.modal.create(modals_moderator_tools, { - affiliation, - 'jid': muc.get('jid') - }); - } - - modal.show(); -} -function parseMessageForMUCCommands(muc, text) { - if (api.settings.get('muc_disable_slash_commands') && !Array.isArray(api.settings.get('muc_disable_slash_commands'))) { - return parseMessageForCommands(muc, text); - } - - text = text.replace(/^\s*/, ''); - const command = (text.match(/^\/([a-zA-Z]*) ?/) || ['']).pop().toLowerCase(); - - if (!command) { - return false; - } - - const args = text.slice(('/' + command).length + 1).trim(); - - if (!muc.getAllowedCommands().includes(command)) { - return false; - } - - switch (command) { - case 'admin': - { - verifyAndSetAffiliation(muc, command, args, ['owner']); - break; - } - - case 'ban': - { - verifyAndSetAffiliation(muc, command, args, ['admin', 'owner']); - break; - } - - case 'modtools': - { - showModeratorToolsModal(muc, args); - break; - } - - case 'deop': - { - // FIXME: /deop only applies to setting a moderators - // role to "participant" (which only admin/owner can - // do). Moderators can however set non-moderator's role - // to participant (e.g. visitor => participant). - // Currently we don't distinguish between these two - // cases. - setRole(muc, command, args, ['admin', 'owner']); - break; - } - - case 'destroy': - { - if (!muc.verifyAffiliations(['owner'])) { - break; - } - - destroyMUC(muc).catch(e => muc.onCommandError(e)); - break; - } - - case 'help': - { - muc.set({ - 'show_help_messages': false - }, { - 'silent': true - }); - muc.set({ - 'show_help_messages': true - }); - break; - } - - case 'kick': - { - setRole(muc, command, args, [], ['moderator']); - break; - } - - case 'mute': - { - setRole(muc, command, args, [], ['moderator']); - break; - } - - case 'member': - { - verifyAndSetAffiliation(muc, command, args, ['admin', 'owner']); - break; - } - - case 'nick': - { - if (!muc.verifyRoles(['visitor', 'participant', 'moderator'])) { - break; - } else if (args.length === 0) { - // e.g. Your nickname is "coolguy69" - const message = __('Your nickname is "%1$s"', muc.get('nick')); - - muc.createMessage({ - message, - 'type': 'error' - }); - } else { - const jid = muc_views_utils_Strophe.getBareJidFromJid(muc.get('jid')); - api.send(muc_views_utils_$pres({ - from: shared_converse.connection.jid, - to: `${jid}/${args}`, - id: muc_views_utils_u.getUniqueId() - }).tree()); - } - - break; - } - - case 'owner': - verifyAndSetAffiliation(muc, command, args, ['owner']); - break; - - case 'op': - { - setRole(muc, command, args, ['admin', 'owner']); - break; - } - - case 'register': - { - if (args.length > 1) { - muc.createMessage({ - 'message': __('Error: invalid number of arguments'), - 'type': 'error' - }); - } else { - muc.registerNickname().then(err_msg => { - err_msg && muc.createMessage({ - 'message': err_msg, - 'type': 'error' - }); - }); - } - - break; - } - - case 'revoke': - { - verifyAndSetAffiliation(muc, command, args, ['admin', 'owner']); - break; - } - - case 'topic': - case 'subject': - muc.setSubject(args); - break; - - case 'voice': - { - setRole(muc, command, args, [], ['moderator']); - break; - } - - default: - return parseMessageForCommands(muc, text); - } - - return true; -} -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/ad-hoc.js - - - - -/* harmony default export */ const ad_hoc = (o => { - const i18n_choose_service = __('On which entity do you want to run commands?'); - - const i18n_choose_service_instructions = __('Certain XMPP services and entities allow privileged users to execute ad-hoc commands on them.'); - - const i18n_commands_found = __('Commands found'); - - const i18n_fetch_commands = __('List available commands'); - - const i18n_jid_placeholder = __('XMPP Address'); - - const i18n_no_commands_found = __('No commands found'); - - return T` - ${o.alert ? T`` : ''} -
    -
    - -
    -
    - -
    - ${o.view === 'list-commands' ? T` -
    -
      -
    • ${o.commands.length ? i18n_commands_found : i18n_no_commands_found}:
    • - ${o.commands.map(cmd => ad_hoc_command(o, cmd))} -
    -
    ` : ''} - -
    - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/adhoc-commands.js - - - - - - - -const { - Strophe: adhoc_commands_Strophe, - $iq: adhoc_commands_$iq, - sizzle: adhoc_commands_sizzle, - u: adhoc_commands_u -} = core_converse.env; -class AdHocCommands extends CustomElement { - static get properties() { - return { - 'alert': { - type: String - }, - 'alert_type': { - type: String - }, - 'nonce': { - type: String - }, - // Used to force re-rendering - 'showform': { - type: String - }, - 'view': { - type: String - } - }; - } - - constructor() { - super(); - this.view = 'choose-service'; - this.showform = ''; - this.commands = []; - } - - render() { - return ad_hoc({ - 'alert': this.alert, - 'alert_type': this.alert_type, - 'commands': this.commands, - 'fetchCommands': ev => this.fetchCommands(ev), - 'hideCommandForm': ev => this.hideCommandForm(ev), - 'runCommand': ev => this.runCommand(ev), - 'showform': this.showform, - 'toggleCommandForm': ev => this.toggleCommandForm(ev), - 'view': this.view - }); - } - - async fetchCommands(ev) { - ev.preventDefault(); - delete this.alert_type; - delete this.alert; - const form_data = new FormData(ev.target); - const jid = form_data.get('jid').trim(); - let supported; - - try { - supported = await api.disco.supports(adhoc_commands_Strophe.NS.ADHOC, jid); - } catch (e) { - headless_log.error(e); - } - - if (supported) { - try { - this.commands = await api.adhoc.getCommands(jid); - this.view = 'list-commands'; - } catch (e) { - headless_log.error(e); - this.alert_type = 'danger'; - this.alert = __('Sorry, an error occurred while looking for commands on that entity.'); - this.commands = []; - headless_log.error(e); - return; - } - } else { - this.alert_type = 'danger'; - this.alert = __("The specified entity doesn't support ad-hoc commands"); - } - } - - async toggleCommandForm(ev) { - ev.preventDefault(); - const node = ev.target.getAttribute('data-command-node'); - const cmd = this.commands.filter(c => c.node === node)[0]; - this.showform !== node && (await fetchCommandForm(cmd)); - this.showform = node; - } - - hideCommandForm(ev) { - ev.preventDefault(); - this.showform = ''; - } - - async runCommand(ev) { - ev.preventDefault(); - const form_data = new FormData(ev.target); - const jid = form_data.get('command_jid').trim(); - const node = form_data.get('command_node').trim(); - const cmd = this.commands.filter(c => c.node === node)[0]; - cmd.alert = null; - this.nonce = adhoc_commands_u.getUniqueId(); - const inputs = adhoc_commands_sizzle(':input:not([type=button]):not([type=submit])', ev.target); - const config_array = inputs.filter(i => !['command_jid', 'command_node'].includes(i.getAttribute('name'))).map(adhoc_commands_u.webForm2xForm).filter(n => n); - const iq = adhoc_commands_$iq({ - to: jid, - type: "set" - }).c("command", { - 'sessionid': cmd.sessionid, - 'node': cmd.node, - 'xmlns': adhoc_commands_Strophe.NS.ADHOC - }).c("x", { - xmlns: adhoc_commands_Strophe.NS.XFORM, - type: "submit" - }); - config_array.forEach(node => iq.cnode(node).up()); - let result; - - try { - result = await api.sendIQ(iq); - } catch (e) { - cmd.alert_type = 'danger'; - cmd.alert = __('Sorry, an error occurred while trying to execute the command. See the developer console for details'); - headless_log.error('Error while trying to execute an ad-hoc command'); - headless_log.error(e); - } - - if (result) { - var _result$querySelector; - - cmd.alert = (_result$querySelector = result.querySelector('note')) === null || _result$querySelector === void 0 ? void 0 : _result$querySelector.textContent; - } else { - cmd.alert = 'Done'; - } - - cmd.alert_type = 'primary'; - this.nonce = adhoc_commands_u.getUniqueId(); - } - -} -api.elements.define('converse-adhoc-commands', AdHocCommands); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/message-form.js - - - - -/* harmony default export */ const templates_message_form = (o => { - const label_message = o.composing_spoiler ? __('Hidden message') : __('Message'); - - const label_spoiler_hint = __('Optional hint'); - - const show_send_button = api.settings.get('show_send_button'); - return T` - -
    - -
    - - - -
    -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/message-form.js - - - - -class MUCMessageForm extends MessageForm { - toHTML() { - var _this$querySelector, _this$querySelector2; - - return templates_message_form(Object.assign(this.model.toJSON(), { - 'hint_value': (_this$querySelector = this.querySelector('.spoiler-hint')) === null || _this$querySelector === void 0 ? void 0 : _this$querySelector.value, - 'message_value': (_this$querySelector2 = this.querySelector('.chat-textarea')) === null || _this$querySelector2 === void 0 ? void 0 : _this$querySelector2.value, - 'onChange': ev => this.model.set({ - 'draft': ev.target.value - }), - 'onDrop': ev => this.onDrop(ev), - 'onKeyDown': ev => this.onKeyDown(ev), - 'onKeyUp': ev => this.onKeyUp(ev), - 'onPaste': ev => this.onPaste(ev), - 'scrolled': this.model.ui.get('scrolled'), - 'viewUnreadMessages': ev => this.viewUnreadMessages(ev) - })); - } - - afterRender() { - const entered = this.model.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED; - const can_edit = entered && !(this.model.features.get('moderated') && this.model.getOwnRole() === 'visitor'); - - if (entered && can_edit) { - this.initMentionAutoComplete(); - } - } - - initMentionAutoComplete() { - this.mention_auto_complete = new shared_converse.AutoComplete(this, { - 'auto_first': true, - 'auto_evaluate': false, - 'min_chars': api.settings.get('muc_mention_autocomplete_min_chars'), - 'match_current_word': true, - 'list': () => this.getAutoCompleteList(), - 'filter': api.settings.get('muc_mention_autocomplete_filter') == 'contains' ? shared_converse.FILTER_CONTAINS : shared_converse.FILTER_STARTSWITH, - 'ac_triggers': ['Tab', '@'], - 'include_triggers': [], - 'item': getAutoCompleteListItem - }); - this.mention_auto_complete.on('suggestion-box-selectcomplete', () => this.auto_completing = false); - } - - parseMessageForCommands(text) { - return parseMessageForMUCCommands(this.model, text); - } - - getAutoCompleteList() { - return this.model.getAllKnownNicknames().map(nick => ({ - 'label': nick, - 'value': `@${nick}` - })); - } - - onKeyDown(ev) { - if (this.mention_auto_complete.onKeyDown(ev)) { - return; - } - - super.onKeyDown(ev); - } - - onKeyUp(ev) { - this.mention_auto_complete.evaluate(ev); - super.onKeyUp(ev); - } - -} -api.elements.define('converse-muc-message-form', MUCMessageForm); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-nickname-form.js - - - - -function submitNickname(ev, model) { - ev.preventDefault(); - const nick = ev.target.nick.value.trim(); - nick && model.join(nick); -} - -/* harmony default export */ const muc_nickname_form = (model => { - const i18n_nickname = __('Nickname'); - - const i18n_join = __('Enter groupchat'); - - const i18n_heading = api.settings.get('muc_show_logs_before_join') ? __('Choose a nickname to enter') : __('Please choose your nickname'); - const validation_message = model.get('nickname_validation_message'); - return T` -
    submitNickname(ev, model)}> -
    -
    - -

    ${validation_message}

    - -
    -
    - -
    -
    -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-bottom-panel.js - - - - - - - -const tpl_can_edit = o => { - const unread_msgs = __('You have unread messages'); - - const message_limit = api.settings.get('message_limit'); - const show_call_button = api.settings.get('visible_toolbar_buttons').call; - const show_emoji_button = api.settings.get('visible_toolbar_buttons').emoji; - const show_send_button = api.settings.get('show_send_button'); - const show_spoiler_button = api.settings.get('visible_toolbar_buttons').spoiler; - const show_toolbar = api.settings.get('show_toolbar'); - return T` - ${o.model.ui.get('scrolled') && o.model.get('num_unread') ? T`
    o.viewUnreadMessages(ev)}>▼ ${unread_msgs} ▼
    ` : ''} - ${show_toolbar ? T` - ` : ''} - `; -}; - -/* harmony default export */ const muc_bottom_panel = (o => { - const unread_msgs = __('You have unread messages'); - - const conn_status = o.model.session.get('connection_status'); - - const i18n_not_allowed = __("You're not allowed to send messages in this room"); - - if (conn_status === core_converse.ROOMSTATUS.ENTERED) { - return T` - ${o.model.ui.get('scrolled') && o.model.get('num_unread_general') ? T`
    o.viewUnreadMessages(ev)}>▼ ${unread_msgs} ▼
    ` : ''} - ${o.can_edit ? tpl_can_edit(o) : T`${i18n_not_allowed}`}`; - } else if (conn_status == core_converse.ROOMSTATUS.NICKNAME_REQUIRED) { - if (api.settings.get('muc_show_logs_before_join')) { - return T`${muc_nickname_form(o.model)}`; - } - } else { - return ''; - } -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/muc-views/styles/muc-bottom-panel.scss -var styles_muc_bottom_panel = __webpack_require__(2490); -;// CONCATENATED MODULE: ./src/plugins/muc-views/styles/muc-bottom-panel.scss - - - - - - - - - - - -var muc_bottom_panel_options = {}; - -muc_bottom_panel_options.styleTagTransform = (styleTagTransform_default()); -muc_bottom_panel_options.setAttributes = (setAttributesWithoutAttributes_default()); - - muc_bottom_panel_options.insert = insertBySelector_default().bind(null, "head"); - -muc_bottom_panel_options.domAPI = (styleDomAPI_default()); -muc_bottom_panel_options.insertStyleElement = (insertStyleElement_default()); - -var muc_bottom_panel_update = injectStylesIntoStyleTag_default()(styles_muc_bottom_panel/* default */.Z, muc_bottom_panel_options); - - - - - /* harmony default export */ const muc_views_styles_muc_bottom_panel = (styles_muc_bottom_panel/* default */.Z && styles_muc_bottom_panel/* default.locals */.Z.locals ? styles_muc_bottom_panel/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/muc-views/bottom-panel.js -function muc_views_bottom_panel_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - - - - -class MUCBottomPanel extends ChatBottomPanel { - constructor(...args) { - super(...args); - - muc_views_bottom_panel_defineProperty(this, "events", { - 'click .hide-occupants': 'hideOccupants', - 'click .send-button': 'sendButtonClicked' - }); - } - - async initialize() { - await super.initialize(); - this.listenTo(this.model, 'change:hidden_occupants', this.debouncedRender); - this.listenTo(this.model, 'change:num_unread_general', this.debouncedRender); - this.listenTo(this.model.features, 'change:moderated', this.debouncedRender); - this.listenTo(this.model.occupants, 'add', this.renderIfOwnOccupant); - this.listenTo(this.model.occupants, 'change:role', this.renderIfOwnOccupant); - this.listenTo(this.model.session, 'change:connection_status', this.debouncedRender); - } - - render() { - const entered = this.model.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED; - const can_edit = entered && !(this.model.features.get('moderated') && this.model.getOwnRole() === 'visitor'); - V(muc_bottom_panel({ - can_edit, - entered, - 'model': this.model, - 'is_groupchat': true, - 'viewUnreadMessages': ev => this.viewUnreadMessages(ev) - }), this); - } - - renderIfOwnOccupant(o) { - o.get('jid') === shared_converse.bare_jid && this.debouncedRender(); - } - - sendButtonClicked(ev) { - var _this$querySelector; - - (_this$querySelector = this.querySelector('converse-message-form')) === null || _this$querySelector === void 0 ? void 0 : _this$querySelector.onFormSubmitted(ev); - } - - hideOccupants(ev) { - var _ev$preventDefault, _ev$stopPropagation; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation = ev.stopPropagation) === null || _ev$stopPropagation === void 0 ? void 0 : _ev$stopPropagation.call(ev); - this.model.save({ - 'hidden_occupants': true - }); - } - -} -api.elements.define('converse-muc-bottom-panel', MUCBottomPanel); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/occupant.js - - - -const occupant_title = o => { - const i18n_moderator_hint = __('This user is a moderator.'); - - const i18n_participant_hint = __('This user can send messages in this groupchat.'); - - const i18n_visitor_hint = __('This user can NOT send messages in this groupchat.'); - - const spaced_jid = `${o.jid} ` || ''; - - if (o.role === "moderator") { - return `${spaced_jid}${i18n_moderator_hint} ${o.hint_occupant}`; - } else if (o.role === "participant") { - return `${spaced_jid}${i18n_participant_hint} ${o.hint_occupant}`; - } else if (o.role === "visitor") { - return `${spaced_jid}${i18n_visitor_hint} ${o.hint_occupant}`; - } else if (!["visitor", "participant", "moderator"].includes(o.role)) { - return `${spaced_jid}${o.hint_occupant}`; - } -}; - -/* harmony default export */ const muc_views_templates_occupant = (o => { - const i18n_owner = __('Owner'); - - const i18n_admin = __('Admin'); - - const i18n_member = __('Member'); - - const i18n_moderator = __('Moderator'); - - const i18n_visitor = __('Visitor'); - - return T` -
  • -
    -
    -
    -
    -
    - ${o.nick || o.jid} - - ${o.affiliation === "owner" ? T`${i18n_owner}` : ''} - ${o.affiliation === "admin" ? T`${i18n_admin}` : ''} - ${o.affiliation === "member" ? T`${i18n_member}` : ''} - ${o.role === "moderator" ? T`${i18n_moderator}` : ''} - ${o.role === "visitor" ? T`${i18n_visitor}` : ''} - -
    -
    -
  • - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-sidebar.js - - - -const PRETTY_CHAT_STATUS = { - 'offline': 'Offline', - 'unavailable': 'Unavailable', - 'xa': 'Extended Away', - 'away': 'Away', - 'dnd': 'Do not disturb', - 'chat': 'Chattty', - 'online': 'Online' -}; -/* harmony default export */ const muc_sidebar = (o => { - const i18n_occupant_hint = occupant => __('Click to mention %1$s in your message.', occupant.get('nick')); - - const i18n_participants = __('Participants'); - - const occupant_tpls = o.occupants.map(occupant => { - return muc_views_templates_occupant(Object.assign({ - 'jid': '', - 'hint_show': PRETTY_CHAT_STATUS[occupant.get('show')], - 'hint_occupant': i18n_occupant_hint(occupant), - 'onOccupantClicked': o.onOccupantClicked - }, occupant.toJSON())); - }); - return T` -
    - -
    - ${i18n_participants} -
    -
    -
    -
      ${occupant_tpls}
    - `; -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/muc-views/styles/muc-occupants.scss -var muc_occupants = __webpack_require__(1107); -;// CONCATENATED MODULE: ./src/plugins/muc-views/styles/muc-occupants.scss - - - - - - - - - - - -var muc_occupants_options = {}; - -muc_occupants_options.styleTagTransform = (styleTagTransform_default()); -muc_occupants_options.setAttributes = (setAttributesWithoutAttributes_default()); - - muc_occupants_options.insert = insertBySelector_default().bind(null, "head"); - -muc_occupants_options.domAPI = (styleDomAPI_default()); -muc_occupants_options.insertStyleElement = (insertStyleElement_default()); - -var muc_occupants_update = injectStylesIntoStyleTag_default()(muc_occupants/* default */.Z, muc_occupants_options); - - - - - /* harmony default export */ const styles_muc_occupants = (muc_occupants/* default */.Z && muc_occupants/* default.locals */.Z.locals ? muc_occupants/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/muc-views/sidebar.js - - - - - -const { - u: sidebar_u -} = core_converse.env; -class MUCSidebar extends CustomElement { - static get properties() { - return { - jid: { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.jid); - this.listenTo(this.model.occupants, 'add', this.requestUpdate); - this.listenTo(this.model.occupants, 'remove', this.requestUpdate); - this.listenTo(this.model.occupants, 'change', this.requestUpdate); - this.model.initialized.then(() => this.requestUpdate()); - } - - render() { - const tpl = muc_sidebar(Object.assign(this.model.toJSON(), { - 'occupants': [...this.model.occupants.models], - 'closeSidebar': ev => this.closeSidebar(ev), - 'onOccupantClicked': ev => this.onOccupantClicked(ev) - })); - return tpl; - } - - closeSidebar(ev) { - var _ev$preventDefault, _ev$stopPropagation; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - ev === null || ev === void 0 ? void 0 : (_ev$stopPropagation = ev.stopPropagation) === null || _ev$stopPropagation === void 0 ? void 0 : _ev$stopPropagation.call(ev); - sidebar_u.safeSave(this.model, { - 'hidden_occupants': true - }); - } - - onOccupantClicked(ev) { - var _ev$preventDefault2; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault2 = ev.preventDefault) === null || _ev$preventDefault2 === void 0 ? void 0 : _ev$preventDefault2.call(ev); - - const chatview = shared_converse.chatboxviews.get(this.getAttribute('jid')); - - chatview === null || chatview === void 0 ? void 0 : chatview.getBottomPanel().insertIntoTextArea(`@${ev.target.textContent}`); - } - -} -api.elements.define('converse-muc-sidebar', MUCSidebar); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-chatarea.js - - - - - - -/* harmony default export */ const muc_chatarea = (o => { - var _o$model; - - return T` -
    -
    - - - ${(_o$model = o.model) !== null && _o$model !== void 0 && _o$model.get('show_help_messages') ? T`
    -
    ` : ''} -
    - -
    - - ${o.model ? T` - ` : ''} -`; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/chatarea.js - - - - -const { - u: chatarea_u -} = core_converse.env; -class MUCChatArea extends CustomElement { - static get properties() { - return { - jid: { - type: String - }, - show_help_messages: { - type: Boolean - }, - type: { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - async initialize() { - this.model = await api.rooms.get(this.jid); - this.listenTo(this.model, 'change:show_help_messages', () => this.requestUpdate()); - this.listenTo(this.model, 'change:hidden_occupants', () => this.requestUpdate()); - this.listenTo(this.model.session, 'change:connection_status', () => this.requestUpdate()); // Bind so that we can pass it to addEventListener and removeEventListener - - this.onMouseMove = this._onMouseMove.bind(this); - this.onMouseUp = this._onMouseUp.bind(this); - this.requestUpdate(); // Make sure we render again after the model has been attached - } - - render() { - return muc_chatarea({ - 'getHelpMessages': () => this.getHelpMessages(), - 'jid': this.jid, - 'model': this.model, - 'onMousedown': ev => this.onMousedown(ev), - 'show_send_button': shared_converse.show_send_button, - 'shouldShowSidebar': () => this.shouldShowSidebar(), - 'type': this.type - }); - } - - shouldShowSidebar() { - return !this.model.get('hidden_occupants') && this.model.session.get('connection_status') === core_converse.ROOMSTATUS.ENTERED; - } - - getHelpMessages() { - const setting = api.settings.get('muc_disable_slash_commands'); - const disabled_commands = Array.isArray(setting) ? setting : []; - return [`/admin: ${__("Change user's affiliation to admin")}`, `/ban: ${__('Ban user by changing their affiliation to outcast')}`, `/clear: ${__('Clear the chat area')}`, `/close: ${__('Close this groupchat')}`, `/deop: ${__('Change user role to participant')}`, `/destroy: ${__('Remove this groupchat')}`, `/help: ${__('Show this menu')}`, `/kick: ${__('Kick user from groupchat')}`, `/me: ${__('Write in 3rd person')}`, `/member: ${__('Grant membership to a user')}`, `/modtools: ${__('Opens up the moderator tools GUI')}`, `/mute: ${__("Remove user's ability to post messages")}`, `/nick: ${__('Change your nickname')}`, `/op: ${__('Grant moderator role to user')}`, `/owner: ${__('Grant ownership of this groupchat')}`, `/register: ${__('Register your nickname')}`, `/revoke: ${__("Revoke the user's current affiliation")}`, `/subject: ${__('Set groupchat subject')}`, `/topic: ${__('Set groupchat subject (alias for /subject)')}`, `/voice: ${__('Allow muted user to post messages')}`].filter(line => disabled_commands.every(c => !line.startsWith(c + '<', 9))).filter(line => this.model.getAllowedCommands().some(c => line.startsWith(c + '<', 9))); - } - - onMousedown(ev) { - if (chatarea_u.hasClass('dragresize-occupants-left', ev.target)) { - this.onStartResizeOccupants(ev); - } - } - - onStartResizeOccupants(ev) { - this.resizing = true; - this.addEventListener('mousemove', this.onMouseMove); - this.addEventListener('mouseup', this.onMouseUp); - const sidebar_el = this.querySelector('converse-muc-sidebar'); - const style = window.getComputedStyle(sidebar_el); - this.width = parseInt(style.width.replace(/px$/, ''), 10); - this.prev_pageX = ev.pageX; - } - - _onMouseMove(ev) { - if (this.resizing) { - ev.preventDefault(); - const delta = this.prev_pageX - ev.pageX; - this.resizeSidebarView(delta, ev.pageX); - this.prev_pageX = ev.pageX; - } - } - - _onMouseUp(ev) { - if (this.resizing) { - ev.preventDefault(); - this.resizing = false; - this.removeEventListener('mousemove', this.onMouseMove); - this.removeEventListener('mouseup', this.onMouseUp); - const sidebar_el = this.querySelector('converse-muc-sidebar'); - const element_position = sidebar_el.getBoundingClientRect(); - const occupants_width = this.calculateSidebarWidth(element_position, 0); - chatarea_u.safeSave(this.model, { - occupants_width - }); - } - } - - calculateSidebarWidth(element_position, delta) { - let occupants_width = element_position.width + delta; - const room_width = this.clientWidth; // keeping display in boundaries - - if (occupants_width < room_width * 0.2) { - // set pixel to 20% width - occupants_width = room_width * 0.2; - this.is_minimum = true; - } else if (occupants_width > room_width * 0.75) { - // set pixel to 75% width - occupants_width = room_width * 0.75; - this.is_maximum = true; - } else if (room_width - occupants_width < 250) { - // resize occupants if chat-area becomes smaller than 250px (min-width property set in css) - occupants_width = room_width - 250; - this.is_maximum = true; - } else { - this.is_maximum = false; - this.is_minimum = false; - } - - return occupants_width; - } - - resizeSidebarView(delta, current_mouse_position) { - const sidebar_el = this.querySelector('converse-muc-sidebar'); - const element_position = sidebar_el.getBoundingClientRect(); - - if (this.is_minimum) { - this.is_minimum = element_position.left < current_mouse_position; - } else if (this.is_maximum) { - this.is_maximum = element_position.left > current_mouse_position; - } else { - const occupants_width = this.calculateSidebarWidth(element_position, delta); - sidebar_el.style.flex = '0 0 ' + occupants_width + 'px'; - } - } - -} -api.elements.define('converse-muc-chatarea', MUCChatArea); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-config-form.js - - - - -const { - sizzle: muc_config_form_sizzle -} = core_converse.env; -const muc_config_form_u = core_converse.env.utils; -/* harmony default export */ const muc_config_form = (o => { - const whitelist = api.settings.get('roomconfig_whitelist'); - const config_stanza = o.model.session.get('config_stanza'); - let fields = []; - let instructions = ''; - let title; - - if (config_stanza) { - var _stanza$querySelector, _stanza$querySelector2; - - const stanza = muc_config_form_u.toStanza(config_stanza); - fields = muc_config_form_sizzle('field', stanza); - - if (whitelist.length) { - fields = fields.filter(f => whitelist.includes(f.getAttribute('var'))); - } - - const password_protected = o.model.features.get('passwordprotected'); - const options = { - 'new_password': !password_protected, - 'fixed_username': o.model.get('jid') - }; - fields = fields.map(f => muc_config_form_u.xForm2TemplateResult(f, stanza, options)); - instructions = (_stanza$querySelector = stanza.querySelector('instructions')) === null || _stanza$querySelector === void 0 ? void 0 : _stanza$querySelector.textContent; - title = (_stanza$querySelector2 = stanza.querySelector('title')) === null || _stanza$querySelector2 === void 0 ? void 0 : _stanza$querySelector2.textContent; - } else { - title = __('Loading configuration form'); - } - - const i18n_save = __('Save'); - - const i18n_cancel = __('Cancel'); - - return T` -
    - -
    - ${title} - ${title !== instructions ? T`

    ${instructions}

    ` : ''} - ${fields.length ? fields : spinner({ - 'classes': 'hor_centered' - })} -
    - ${fields.length ? T` -
    - - -
    ` : ''} -
    - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/config-form.js - - - - - -const { - sizzle: config_form_sizzle -} = core_converse.env; -const config_form_u = core_converse.env.utils; - -class MUCConfigForm extends CustomElement { - static get properties() { - return { - 'jid': { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.jid); - this.listenTo(this.model.features, 'change:passwordprotected', this.requestUpdate); - this.listenTo(this.model.session, 'change:config_stanza', this.requestUpdate); - this.getConfig(); - } - - render() { - return muc_config_form({ - 'model': this.model, - 'closeConfigForm': ev => this.closeForm(ev), - 'submitConfigForm': ev => this.submitConfigForm(ev) - }); - } - - async getConfig() { - const iq = await this.model.fetchRoomConfiguration(); - this.model.session.set('config_stanza', iq.outerHTML); - } - - async submitConfigForm(ev) { - ev.preventDefault(); - const inputs = config_form_sizzle(':input:not([type=button]):not([type=submit])', ev.target); - const config_array = inputs.map(config_form_u.webForm2xForm).filter(f => f); - - try { - await this.model.sendConfiguration(config_array); - } catch (e) { - headless_log.error(e); - - const message = __("Sorry, an error occurred while trying to submit the config form.") + " " + __("Check your browser's developer console for details."); - - api.alert('error', __('Error'), message); - } - - await this.model.refreshDiscoInfo(); - this.closeForm(); - } - - closeForm(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - this.model.session.set('view', null); - } - -} - -api.elements.define('converse-muc-config-form', MUCConfigForm); -/* harmony default export */ const config_form = ((/* unused pure expression or super */ null && (MUCConfigForm))); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-destroyed.js - - - -const tpl_moved = o => { - const i18n_moved = __('The conversation has moved to a new address. Click the link below to enter.'); - - return T` -

    ${i18n_moved}

    - `; -}; - -/* harmony default export */ const muc_destroyed = (o => { - const i18n_non_existent = __('This groupchat no longer exists'); - - const i18n_reason = __('The following reason was given: "%1$s"', o.reason || ''); - - return T` -
    -

    ${i18n_non_existent}

    -
    - ${o.reason ? T`

    ${i18n_reason}

    ` : ''} - ${o.moved_jid ? tpl_moved(o) : ''} - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/destroyed.js - - - - -class MUCDestroyed extends CustomElement { - static get properties() { - return { - 'jid': { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.jid); - } - - render() { - const reason = this.model.get('destroyed_reason'); - const moved_jid = this.model.get('moved_jid'); - return muc_destroyed({ - moved_jid, - reason, - 'onSwitch': ev => this.onSwitch(ev) - }); - } - - async onSwitch(ev) { - ev.preventDefault(); - const moved_jid = this.model.get('moved_jid'); - const room = await api.rooms.get(moved_jid, {}, true); - room.maybeShow(true); - this.model.destroy(); - } - -} - -api.elements.define('converse-muc-destroyed', MUCDestroyed); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-disconnect.js - -/* harmony default export */ const muc_disconnect = (messages => { - return T` -
    -

    ${messages[0]}

    - ${messages.slice(1).map(m => T`

    ${m}

    `)} -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/disconnected.js - - - - - -class MUCDisconnected extends CustomElement { - static get properties() { - return { - 'jid': { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.jid); - } - - render() { - const message = this.model.session.get('disconnection_message'); - - if (!message) { - return; - } - - const messages = [message]; - const actor = this.model.session.get('disconnection_actor'); - - if (actor) { - messages.push(__('This action was done by %1$s.', actor)); - } - - const reason = this.model.session.get('disconnection_reason'); - - if (reason) { - messages.push(__('The reason given is: "%1$s".', reason)); - } - - return muc_disconnect(messages); - } - -} - -api.elements.define('converse-muc-disconnected', MUCDisconnected); -;// CONCATENATED MODULE: ./src/modals/templates/muc-invite.js - - - -/* harmony default export */ const muc_invite = (o => { - const i18n_invite = __('Invite'); - - const i18n_invite_heading = __('Invite someone to this groupchat'); - - const i18n_jid_placeholder = __('user@example.org'); - - const i18n_error_message = __('Please enter a valid XMPP address'); - - const i18n_invite_label = __('XMPP Address'); - - const i18n_reason = __('Optional reason for the invitation'); - - return T` - - `; -}); -;// CONCATENATED MODULE: ./src/modals/muc-invite.js - - - - -const muc_invite_u = core_converse.env.utils; -/* harmony default export */ const modals_muc_invite = (base.extend({ - id: "muc-invite-modal", - - initialize() { - base.prototype.initialize.apply(this, arguments); - this.listenTo(this.model, 'change', this.render); - this.initInviteWidget(); - }, - - toHTML() { - return muc_invite(Object.assign(this.model.toJSON(), { - 'submitInviteForm': ev => this.submitInviteForm(ev) - })); - }, - - initInviteWidget() { - if (this.invite_auto_complete) { - this.invite_auto_complete.destroy(); - } - - const list = shared_converse.roster.map(i => ({ - 'label': i.getDisplayName(), - 'value': i.get('jid') - })); - - const el = this.el.querySelector('.suggestion-box').parentElement; - this.invite_auto_complete = new shared_converse.AutoComplete(el, { - 'min_chars': 1, - 'list': list - }); - }, - - submitInviteForm(ev) { - ev.preventDefault(); // TODO: Add support for sending an invite to multiple JIDs - - const data = new FormData(ev.target); - const jid = data.get('invitee_jids'); - const reason = data.get('reason'); - - if (muc_invite_u.isValidJID(jid)) { - // TODO: Create and use API here - this.chatroomview.model.directInvite(jid, reason); - this.modal.hide(); - } else { - this.model.set({ - 'invalid_invite_jid': true - }); - } - } - -})); -;// CONCATENATED MODULE: ./src/modals/templates/muc-details.js - - - - - -const subject = o => { - const i18n_topic = __('Topic'); - - const i18n_topic_author = __('Topic author'); - - return T` -

    ${i18n_topic}: ${o.subject.text}

    -

    ${i18n_topic_author}: ${o.subject && o.subject.author}

    - `; -}; - -/* harmony default export */ const muc_details = (o => { - const i18n_address = __('Groupchat XMPP address'); - - const i18n_archiving = __('Message archiving'); - - const i18n_archiving_help = __('Messages are archived on the server'); - - const i18n_desc = __('Description'); - - const i18n_features = __('Features'); - - const i18n_hidden = __('Hidden'); - - const i18n_hidden_help = __('This groupchat is not publicly searchable'); - - const i18n_members_help = __('This groupchat is restricted to members only'); - - const i18n_members_only = __('Members only'); - - const i18n_moderated = __('Moderated'); - - const i18n_moderated_help = __('Participants entering this groupchat need to request permission to write'); - - const i18n_name = __('Name'); - - const i18n_no_pass_help = __('This groupchat does not require a password upon entry'); - - const i18n_no_password_required = __('No password required'); - - const i18n_not_anonymous = __('Not anonymous'); - - const i18n_not_anonymous_help = __('All other groupchat participants can see your XMPP address'); - - const i18n_not_moderated = __('Not moderated'); - - const i18n_not_moderated_help = __('Participants entering this groupchat can write right away'); - - const i18n_online_users = __('Online users'); - - const i18n_open = __('Open'); - - const i18n_open_help = __('Anyone can join this groupchat'); - - const i18n_password_help = __('This groupchat requires a password before entry'); - - const i18n_password_protected = __('Password protected'); - - const i18n_persistent = __('Persistent'); - - const i18n_persistent_help = __('This groupchat persists even if it\'s unoccupied'); - - const i18n_public = __('Public'); - - const i18n_semi_anon = __('Semi-anonymous'); - - const i18n_semi_anon_help = __('Only moderators can see your XMPP address'); - - const i18n_temporary = __('Temporary'); - - const i18n_temporary_help = __('This groupchat will disappear once the last person leaves'); - - return T` - - `; -}); -;// CONCATENATED MODULE: ./src/modals/muc-details.js - - - -/* harmony default export */ const modals_muc_details = (base.extend({ - id: "muc-details-modal", - - initialize() { - base.prototype.initialize.apply(this, arguments); - this.listenTo(this.model, 'change', this.render); - this.listenTo(this.model.features, 'change', this.render); - this.listenTo(this.model.occupants, 'add', this.render); - this.listenTo(this.model.occupants, 'change', this.render); - }, - - toHTML() { - return muc_details(Object.assign(this.model.toJSON(), { - 'config': this.model.config.toJSON(), - 'display_name': __('Groupchat info for %1$s', this.model.getDisplayName()), - 'features': this.model.features.toJSON(), - 'num_occupants': this.model.occupants.length - })); - } - -})); -;// CONCATENATED MODULE: ./src/shared/components/rich-text.js - - - -/** - * The RichText custom element allows you to parse transform text into rich DOM elements. - * @example - */ - -class rich_text_RichText extends CustomElement { - static get properties() { - /** - * @typedef { Object } RichTextComponentProperties - * @property { Boolean } embed_audio - * Whether URLs that point to audio files should render as audio players. - * @property { Boolean } embed_videos - * Whether URLs that point to video files should render as video players. - * @property { Array } mentions - An array of objects representing chat mentions - * @property { String } nick - The current user's nickname, relevant for mentions - * @property { Number } offset - The text offset, in case this is a nested RichText element. - * @property { Function } onImgClick - * @property { Function } onImgLoad - * @property { Boolean } render_styling - * Whether XEP-0393 message styling hints should be rendered - * @property { Boolean } show_images - * Whether URLs that point to image files should render as images - * @property { Boolean } hide_media_urls - * If media URLs are rendered as media, then this option determines - * whether the original URL is also still shown or not. - * Only relevant in conjunction with `show_images`, `embed_audio` and `embed_videos`. - * @property { Boolean } show_me_message - * Whether text that starts with /me should be rendered in the 3rd person. - * @property { String } text - The text that will get transformed. - */ - return { - embed_audio: { - type: Boolean - }, - embed_videos: { - type: Boolean - }, - mentions: { - type: Array - }, - nick: { - type: String - }, - offset: { - type: Number - }, - onImgClick: { - type: Function - }, - onImgLoad: { - type: Function - }, - render_styling: { - type: Boolean - }, - show_images: { - type: Boolean - }, - hide_media_urls: { - type: Boolean - }, - show_me_message: { - type: Boolean - }, - text: { - type: String - } - }; - } - - constructor() { - super(); - this.embed_audio = false; - this.embed_videos = false; - this.hide_media_urls = false; - this.mentions = []; - this.offset = 0; - this.render_styling = false; - this.show_image_urls = true; - this.show_images = false; - this.show_me_message = false; - } - - render() { - const options = { - embed_audio: this.embed_audio, - embed_videos: this.embed_videos, - nick: this.nick, - onImgClick: this.onImgClick, - onImgLoad: this.onImgLoad, - render_styling: this.render_styling, - show_images: this.show_images, - show_me_message: this.show_me_message, - hide_media_urls: this.hide_media_urls - }; - return rich_text(this.text, this.offset, this.mentions, options); - } - -} -api.elements.define('converse-rich-text', rich_text_RichText); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-head.js - - - - - - - -const tpl_standalone_btns = o => o.standalone_btns.reverse().map(b => until_o(b, '')); - -/* harmony default export */ const muc_head = (o => { - const i18n_hide_topic = __('Hide the groupchat topic'); - - const i18n_bookmarked = __('This groupchat is bookmarked'); - - const subject = o.subject ? o.subject.text : ''; - const show_subject = subject && !o.subject_hidden; - return T` -
    - ${!shared_converse.api.settings.get("singleton") ? T`` : ''} -
    ${o.title} - ${o.bookmarked ? T`` : ''} -
    -
    - ${o.standalone_btns.length ? tpl_standalone_btns(o) : ''} - ${o.dropdown_btns.length ? T`` : ''} -
    -
    - ${show_subject ? T`

    - -

    ` : ''} - `; -}); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/muc-views/styles/muc-head.scss -var styles_muc_head = __webpack_require__(679); -;// CONCATENATED MODULE: ./src/plugins/muc-views/styles/muc-head.scss - - - - - - - - - - - -var muc_head_options = {}; - -muc_head_options.styleTagTransform = (styleTagTransform_default()); -muc_head_options.setAttributes = (setAttributesWithoutAttributes_default()); - - muc_head_options.insert = insertBySelector_default().bind(null, "head"); - -muc_head_options.domAPI = (styleDomAPI_default()); -muc_head_options.insertStyleElement = (insertStyleElement_default()); - -var muc_head_update = injectStylesIntoStyleTag_default()(styles_muc_head/* default */.Z, muc_head_options); - - - - - /* harmony default export */ const muc_views_styles_muc_head = (styles_muc_head/* default */.Z && styles_muc_head/* default.locals */.Z.locals ? styles_muc_head/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/muc-views/heading.js - - - - - - - - - - - - -class MUCHeading extends ElementView { - async connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.getAttribute('jid')); - this.debouncedRender = lodash_es_debounce(this.render, 100); - this.listenTo(this.model, 'change', this.debouncedRender); - const user_settings = await shared_converse.api.user.settings.getModel(); - this.listenTo(user_settings, 'change:mucs_with_hidden_subject', this.debouncedRender); - await this.model.initialized; - this.listenTo(this.model.features, 'change:open', this.debouncedRender); - this.model.occupants.forEach(o => this.onOccupantAdded(o)); - this.listenTo(this.model.occupants, 'add', this.onOccupantAdded); - this.listenTo(this.model.occupants, 'change:affiliation', this.onOccupantAffiliationChanged); - this.render(); - } - - async render() { - const tpl = await this.generateHeadingTemplate(); - V(tpl, this); - } - - onOccupantAdded(occupant) { - if (occupant.get('jid') === shared_converse.bare_jid) { - this.debouncedRender(); - } - } - - onOccupantAffiliationChanged(occupant) { - if (occupant.get('jid') === shared_converse.bare_jid) { - this.debouncedRender(); - } - } - - showRoomDetailsModal(ev) { - ev.preventDefault(); - api.modal.show(modals_muc_details, { - 'model': this.model - }, ev); - } - - showInviteModal(ev) { - ev.preventDefault(); - api.modal.show(modals_muc_invite, { - 'model': new Model(), - 'chatroomview': this - }, ev); - } - - toggleTopic(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - this.model.toggleSubjectHiddenState(); - } - - getAndRenderConfigurationForm() { - this.model.session.set('view', core_converse.MUC.VIEWS.CONFIG); - } - - close(ev) { - ev.preventDefault(); - this.model.close(); - } - - destroy(ev) { - ev.preventDefault(); - destroyMUC(this.model); - } - /** - * Returns a list of objects which represent buttons for the groupchat header. - * @emits _converse#getHeadingButtons - */ - - - getHeadingButtons(subject_hidden) { - const buttons = []; - buttons.push({ - 'i18n_text': __('Details'), - 'i18n_title': __('Show more information about this groupchat'), - 'handler': ev => this.showRoomDetailsModal(ev), - 'a_class': 'show-muc-details-modal', - 'icon_class': 'fa-info-circle', - 'name': 'details' - }); - - if (this.model.getOwnAffiliation() === 'owner') { - buttons.push({ - 'i18n_text': __('Configure'), - 'i18n_title': __('Configure this groupchat'), - 'handler': () => this.getAndRenderConfigurationForm(), - 'a_class': 'configure-chatroom-button', - 'icon_class': 'fa-wrench', - 'name': 'configure' - }); - } - - if (this.model.invitesAllowed()) { - buttons.push({ - 'i18n_text': __('Invite'), - 'i18n_title': __('Invite someone to join this groupchat'), - 'handler': ev => this.showInviteModal(ev), - 'a_class': 'open-invite-modal', - 'icon_class': 'fa-user-plus', - 'name': 'invite' - }); - } - - const subject = this.model.get('subject'); - - if (subject && subject.text) { - buttons.push({ - 'i18n_text': subject_hidden ? __('Show topic') : __('Hide topic'), - 'i18n_title': subject_hidden ? __('Show the topic message in the heading') : __('Hide the topic in the heading'), - 'handler': ev => this.toggleTopic(ev), - 'a_class': 'hide-topic', - 'icon_class': 'fa-minus-square', - 'name': 'toggle-topic' - }); - } - - const conn_status = this.model.session.get('connection_status'); - - if (conn_status === core_converse.ROOMSTATUS.ENTERED) { - const allowed_commands = this.model.getAllowedCommands(); - - if (allowed_commands.includes('modtools')) { - buttons.push({ - 'i18n_text': __('Moderate'), - 'i18n_title': __('Moderate this groupchat'), - 'handler': () => showModeratorToolsModal(this.model), - 'a_class': 'moderate-chatroom-button', - 'icon_class': 'fa-user-cog', - 'name': 'moderate' - }); - } - - if (allowed_commands.includes('destroy')) { - buttons.push({ - 'i18n_text': __('Destroy'), - 'i18n_title': __('Remove this groupchat'), - 'handler': ev => this.destroy(ev), - 'a_class': 'destroy-chatroom-button', - 'icon_class': 'fa-trash', - 'name': 'destroy' - }); - } - } - - if (!api.settings.get('singleton')) { - buttons.push({ - 'i18n_text': __('Leave'), - 'i18n_title': __('Leave and close this groupchat'), - 'handler': async ev => { - ev.stopPropagation(); - const messages = [__('Are you sure you want to leave this groupchat?')]; - const result = await api.confirm(__('Confirm'), messages); - result && this.close(ev); - }, - 'a_class': 'close-chatbox-button', - 'standalone': api.settings.get('view_mode') === 'overlayed', - 'icon_class': 'fa-sign-out-alt', - 'name': 'signout' - }); - } - - const chatview = shared_converse.chatboxviews.get(this.getAttribute('jid')); - - if (chatview) { - return shared_converse.api.hook('getHeadingButtons', chatview, buttons); - } else { - return buttons; // Happens during tests - } - } - /** - * Returns the groupchat heading TemplateResult to be rendered. - */ - - - async generateHeadingTemplate() { - const subject_hidden = await this.model.isSubjectHidden(); - const heading_btns = await this.getHeadingButtons(subject_hidden); - const standalone_btns = heading_btns.filter(b => b.standalone); - const dropdown_btns = heading_btns.filter(b => !b.standalone); - return muc_head(Object.assign(this.model.toJSON(), { - _converse: shared_converse, - subject_hidden, - 'dropdown_btns': dropdown_btns.map(b => getHeadingDropdownItem(b)), - 'standalone_btns': standalone_btns.map(b => getHeadingStandaloneButton(b)), - 'title': this.model.getDisplayName() - })); - } - -} -api.elements.define('converse-muc-heading', MUCHeading); -;// CONCATENATED MODULE: ./src/plugins/muc-views/nickname-form.js - - - - -class MUCNicknameForm extends CustomElement { - static get properties() { - return { - 'jid': { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.jid); - } - - render() { - return muc_nickname_form(this.model); - } - -} - -api.elements.define('converse-muc-nickname-form', MUCNicknameForm); -/* harmony default export */ const nickname_form = ((/* unused pure expression or super */ null && (MUCNicknameForm))); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-password-form.js - - -/* harmony default export */ const muc_password_form = (o => { - const i18n_heading = __('This groupchat requires a password'); - - const i18n_password = __('Password: '); - - const i18n_submit = __('Submit'); - - return T` -
    -
    - -

    ${o.validation_message}

    - - -
    -
    - -
    -
    - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/password-form.js - - - - -class MUCPasswordForm extends CustomElement { - static get properties() { - return { - 'jid': { - type: String - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.model = shared_converse.chatboxes.get(this.jid); - this.listenTo(this.model, 'change:password_validation_message', this.render); - this.render(); - } - - render() { - return muc_password_form({ - 'jid': this.model.get('jid'), - 'submitPassword': ev => this.submitPassword(ev), - 'validation_message': this.model.get('password_validation_message') - }); - } - - submitPassword(ev) { - ev.preventDefault(); - const password = this.querySelector('input[type=password]').value; - this.model.join(this.model.get('nick'), password); - this.model.set('password_validation_message', null); - } - -} - -api.elements.define('converse-muc-password-form', MUCPasswordForm); -/* harmony default export */ const password_form = ((/* unused pure expression or super */ null && (MUCPasswordForm))); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc.js - - - - - - - - - -/* harmony default export */ const templates_muc = (o => { - return T` -
    - - ${o.model ? T` - - -
    ${getChatRoomBodyTemplate(o)}
    - ` : ''} -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/muc.js -function muc_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - -class MUCView extends BaseChatView { - constructor(...args) { - super(...args); - - muc_defineProperty(this, "length", 300); - - muc_defineProperty(this, "is_chatroom", true); - } - - connectedCallback() { - super.connectedCallback(); - this.initialize(); - } - - async initialize() { - this.model = await api.rooms.get(this.jid); - - shared_converse.chatboxviews.add(this.jid, this); - - this.setAttribute('id', this.model.get('box_id')); - this.listenTo(shared_converse, 'windowStateChanged', this.onWindowStateChanged); - this.listenTo(this.model, 'change:composing_spoiler', this.requestUpdateMessageForm); - this.listenTo(this.model.session, 'change:connection_status', this.onConnectionStatusChanged); - this.listenTo(this.model.session, 'change:view', this.requestUpdate); - this.onConnectionStatusChanged(); - this.model.maybeShow(); - /** - * Triggered once a { @link _converse.ChatRoomView } has been opened - * @event _converse#chatRoomViewInitialized - * @type { _converse.ChatRoomView } - * @example _converse.api.listen.on('chatRoomViewInitialized', view => { ... }); - */ - - api.trigger('chatRoomViewInitialized', this); - } - - render() { - return templates_muc({ - 'model': this.model - }); - } - - onConnectionStatusChanged() { - const conn_status = this.model.session.get('connection_status'); - - if (conn_status === core_converse.ROOMSTATUS.CONNECTING) { - this.model.session.save({ - 'disconnection_actor': undefined, - 'disconnection_message': undefined, - 'disconnection_reason': undefined - }); - this.model.save({ - 'moved_jid': undefined, - 'password_validation_message': undefined, - 'reason': undefined - }); - } - - this.requestUpdate(); - } - -} -api.elements.define('converse-muc', MUCView); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/muc-views/styles/index.scss -var muc_views_styles = __webpack_require__(1557); -;// CONCATENATED MODULE: ./src/plugins/muc-views/styles/index.scss - - - - - - - - - - - -var muc_views_styles_options = {}; - -muc_views_styles_options.styleTagTransform = (styleTagTransform_default()); -muc_views_styles_options.setAttributes = (setAttributesWithoutAttributes_default()); - - muc_views_styles_options.insert = insertBySelector_default().bind(null, "head"); - -muc_views_styles_options.domAPI = (styleDomAPI_default()); -muc_views_styles_options.insertStyleElement = (insertStyleElement_default()); - -var muc_views_styles_update = injectStylesIntoStyleTag_default()(muc_views_styles/* default */.Z, muc_views_styles_options); - - - - - /* harmony default export */ const plugins_muc_views_styles = (muc_views_styles/* default */.Z && muc_views_styles/* default.locals */.Z.locals ? muc_views_styles/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/muc-views/index.js -/** - * @copyright 2020, the Converse.js contributors - * @description XEP-0045 Multi-User Chat Views - * @license Mozilla Public License (MPLv2) - */ - - - - - - - -core_converse.MUC.VIEWS = { - CONFIG: 'config-form', - BOOKMARK: 'bookmark-form' -}; -core_converse.plugins.add('converse-muc-views', { - /* Dependencies are other plugins which might be - * overridden or relied upon, and therefore need to be loaded before - * this plugin. They are "optional" because they might not be - * available, in which case any overrides applicable to them will be - * ignored. - * - * NB: These plugins need to have already been loaded via require.js. - * - * It's possible to make these dependencies "non-optional". - * If the setting "strict_plugin_dependencies" is set to true, - * an error will be raised if the plugin is not found. - */ - dependencies: ['converse-modal', 'converse-controlbox', 'converse-chatview'], - - initialize() { - const { - _converse - } = this; // Configuration values for this plugin - // ==================================== - // Refer to docs/source/configuration.rst for explanations of these - // configuration settings. - - api.settings.extend({ - 'auto_list_rooms': false, - 'cache_muc_messages': true, - 'locked_muc_nickname': false, - 'modtools_disable_query': [], - 'muc_disable_slash_commands': false, - 'muc_mention_autocomplete_filter': 'contains', - 'muc_mention_autocomplete_min_chars': 0, - 'muc_mention_autocomplete_show_avatar': true, - 'muc_roomid_policy': null, - 'muc_roomid_policy_hint': null, - 'roomconfig_whitelist': [], - 'show_retraction_warning': true, - 'visible_toolbar_buttons': { - 'toggle_occupants': true - } - }); - _converse.ChatRoomView = MUCView; - api.listen.on('clearsession', () => { - const view = _converse.chatboxviews.get('controlbox'); - - if (view && view.roomspanel) { - view.roomspanel.model.destroy(); - view.roomspanel.remove(); - delete view.roomspanel; - } - }); - api.listen.on('controlBoxInitialized', view => { - if (!api.settings.get('allow_muc')) { - return; - } - - fetchAndSetMUCDomain(view); - view.model.on('change:connected', () => fetchAndSetMUCDomain(view)); - }); - api.listen.on('chatBoxClosed', model => { - if (model.get('type') === _converse.CHATROOMS_TYPE) { - utils_clearHistory(model.get('jid')); - } - }); - } - -}); -// EXTERNAL MODULE: ./node_modules/favico.js-slevomat/favico.js -var favico = __webpack_require__(2329); -var favico_default = /*#__PURE__*/__webpack_require__.n(favico); -;// CONCATENATED MODULE: ./src/plugins/notifications/utils.js - - - - - -const { - Strophe: notifications_utils_Strophe -} = core_converse.env; -const supports_html5_notification = ('Notification' in window); -core_converse.env.Favico = (favico_default()); -let favicon; -function isMessageToHiddenChat(attrs) { - var _converse$chatboxes$g; - - return shared_converse.isTestEnv() || (((_converse$chatboxes$g = shared_converse.chatboxes.get(attrs.from)) === null || _converse$chatboxes$g === void 0 ? void 0 : _converse$chatboxes$g.isHidden()) ?? false); -} -function areDesktopNotificationsEnabled() { - return shared_converse.isTestEnv() || supports_html5_notification && api.settings.get('show_desktop_notifications') && Notification.permission === 'granted'; -} -function clearFavicon() { - var _navigator$clearAppBa, _navigator; - - favicon = null; - (_navigator$clearAppBa = (_navigator = navigator).clearAppBadge) === null || _navigator$clearAppBa === void 0 ? void 0 : _navigator$clearAppBa.call(_navigator).catch(e => headless_log.error("Could not clear unread count in app badge " + e)); -} -function updateUnreadFavicon() { - if (api.settings.get('show_tab_notifications')) { - var _navigator$setAppBadg, _navigator2; - - favicon = favicon ?? new core_converse.env.Favico({ - type: 'circle', - animation: 'pop' - }); - const chats = shared_converse.chatboxes.models; - const num_unread = chats.reduce((acc, chat) => acc + (chat.get('num_unread') || 0), 0); - favicon.badge(num_unread); - (_navigator$setAppBadg = (_navigator2 = navigator).setAppBadge) === null || _navigator$setAppBadg === void 0 ? void 0 : _navigator$setAppBadg.call(_navigator2, num_unread).catch(e => headless_log.error("Could set unread count in app badge - " + e)); - } -} - -function isReferenced(references, muc_jid, nick) { - const check = r => [shared_converse.bare_jid, `${muc_jid}/${nick}`].includes(r.uri.replace(/^xmpp:/, '')); - - return references.reduce((acc, r) => acc || check(r), false); -} -/** - * Is this a group message for which we should notify the user? - * @private - * @param { MUCMessageAttributes } attrs - */ - - -async function shouldNotifyOfGroupMessage(attrs) { - if (!(attrs !== null && attrs !== void 0 && attrs.body) && !(attrs !== null && attrs !== void 0 && attrs.message)) { - // attrs.message is used by 'info' messages - return false; - } - - const jid = attrs.from; - const muc_jid = attrs.from_muc; - const notify_all = api.settings.get('notify_all_room_messages'); - - const room = shared_converse.chatboxes.get(muc_jid); - - const resource = notifications_utils_Strophe.getResourceFromJid(jid); - const sender = resource && notifications_utils_Strophe.unescapeNode(resource) || ''; - let is_mentioned = false; - const nick = room.get('nick'); - - if (api.settings.get('notify_nicknames_without_references')) { - is_mentioned = new RegExp(`\\b${nick}\\b`).test(attrs.body); - } - - const is_not_mine = sender !== nick; - const should_notify_user = notify_all === true || Array.isArray(notify_all) && notify_all.includes(muc_jid) || isReferenced(attrs.references, muc_jid, nick) || is_mentioned; - - if (is_not_mine && !!should_notify_user) { - /** - * *Hook* which allows plugins to run further logic to determine - * whether a notification should be sent out for this message. - * @event _converse#shouldNotifyOfGroupMessage - * @example - * api.listen.on('shouldNotifyOfGroupMessage', (should_notify) => { - * return should_notify && flurb === floob; - * }); - */ - const should_notify = await api.hook('shouldNotifyOfGroupMessage', attrs, true); - return should_notify; - } - - return false; -} - -async function shouldNotifyOfInfoMessage(attrs) { - if (!attrs.from_muc) { - return false; - } - - const room = await api.rooms.get(attrs.from_muc); - - if (!room) { - return false; - } - - const nick = room.get('nick'); - const muc_jid = attrs.from_muc; - const notify_all = api.settings.get('notify_all_room_messages'); - return notify_all === true || Array.isArray(notify_all) && notify_all.includes(muc_jid) || isReferenced(attrs.references, muc_jid, nick); -} -/** - * @private - * @async - * @method shouldNotifyOfMessage - * @param { MessageData|MUCMessageData } data - */ - - -function shouldNotifyOfMessage(data) { - const { - attrs - } = data; - - if (!attrs || attrs.is_forwarded) { - return false; - } - - if (attrs['type'] === 'groupchat') { - return shouldNotifyOfGroupMessage(attrs); - } else if (attrs['type'] === 'info') { - return shouldNotifyOfInfoMessage(attrs); - } else if (attrs.is_headline) { - // We want to show notifications for headline messages. - return isMessageToHiddenChat(attrs); - } - - const is_me = notifications_utils_Strophe.getBareJidFromJid(attrs.from) === shared_converse.bare_jid; - - return !isEmptyMessage(attrs) && !is_me && (api.settings.get('show_desktop_notifications') === 'all' || isMessageToHiddenChat(attrs)); -} - -function showFeedbackNotification(data) { - if (data.klass === 'error' || data.klass === 'warn') { - const n = new Notification(data.subject, { - body: data.message, - lang: shared_converse.locale, - icon: shared_converse.notification_icon - }); - setTimeout(n.close.bind(n), 5000); - } -} -/** - * Creates an HTML5 Notification to inform of a change in a - * contact's chat state. - */ - -function showChatStateNotification(contact) { - if (shared_converse.chatstate_notification_blacklist.includes(contact.jid)) { - // Don't notify if the user is being ignored. - return; - } - - const chat_state = contact.presence.get('show'); - let message = null; - - if (chat_state === 'offline') { - message = __('has gone offline'); - } else if (chat_state === 'away') { - message = __('has gone away'); - } else if (chat_state === 'dnd') { - message = __('is busy'); - } else if (chat_state === 'online') { - message = __('has come online'); - } - - if (message === null) { - return; - } - - const n = new Notification(contact.getDisplayName(), { - body: message, - lang: shared_converse.locale, - icon: shared_converse.notification_icon - }); - setTimeout(() => n.close(), 5000); -} -/** - * Shows an HTML5 Notification with the passed in message - * @private - * @param { MessageData|MUCMessageData } data - */ - - -function showMessageNotification(data) { - const { - attrs - } = data; - - if (attrs.is_error) { - return; - } - - if (!areDesktopNotificationsEnabled()) { - return; - } - - let title, roster_item; - const full_from_jid = attrs.from; - const from_jid = notifications_utils_Strophe.getBareJidFromJid(full_from_jid); - - if (attrs.type == 'info') { - title = attrs.message; - } else if (attrs.type === 'headline') { - if (!from_jid.includes('@') || api.settings.get('allow_non_roster_messaging')) { - title = __('Notification from %1$s', from_jid); - } else { - return; - } - } else if (!from_jid.includes('@')) { - // workaround for Prosody which doesn't give type "headline" - title = __('Notification from %1$s', from_jid); - } else if (attrs.type === 'groupchat') { - title = __('%1$s says', notifications_utils_Strophe.getResourceFromJid(full_from_jid)); - } else { - if (shared_converse.roster === undefined) { - headless_log.error('Could not send notification, because roster is undefined'); - return; - } - - roster_item = shared_converse.roster.get(from_jid); - - if (roster_item !== undefined) { - title = __('%1$s says', roster_item.getDisplayName()); - } else { - if (api.settings.get('allow_non_roster_messaging')) { - title = __('%1$s says', from_jid); - } else { - return; - } - } - } - - let body; - - if (attrs.type == 'info') { - body = attrs.reason; - } else { - body = attrs.is_encrypted ? attrs.plaintext : attrs.body; - - if (!body) { - return; - } - } - - const n = new Notification(title, { - 'body': body, - 'lang': shared_converse.locale, - 'icon': api.settings.get('notification_icon'), - 'requireInteraction': !shared_converse.notification_delay - }); - - if (api.settings.get('notification_delay')) { - setTimeout(() => n.close(), api.settings.get('notification_delay')); - } - - n.onclick = function (event) { - event.preventDefault(); - window.focus(); - - const chat = shared_converse.chatboxes.get(from_jid); - - chat.maybeShow(true); - }; -} - -function playSoundNotification() { - if (api.settings.get('play_sounds') && window.Audio !== undefined) { - const audioOgg = new Audio(api.settings.get('sounds_path') + 'msg_received.ogg'); - const canPlayOgg = audioOgg.canPlayType('audio/ogg'); - - if (canPlayOgg === 'probably') { - return audioOgg.play(); - } - - const audioMp3 = new Audio(api.settings.get('sounds_path') + 'msg_received.mp3'); - const canPlayMp3 = audioMp3.canPlayType('audio/mp3'); - - if (canPlayMp3 === 'probably') { - audioMp3.play(); - } else if (canPlayOgg === 'maybe') { - audioOgg.play(); - } else if (canPlayMp3 === 'maybe') { - audioMp3.play(); - } - } -} -/** - * Event handler for the on('message') event. Will call methods - * to play sounds and show HTML5 notifications. - */ - - -async function handleMessageNotification(data) { - if (!(await shouldNotifyOfMessage(data))) { - return false; - } - /** - * Triggered when a notification (sound or HTML5 notification) for a new - * message has will be made. - * @event _converse#messageNotification - * @type { MessageData|MUCMessageData} - * @example _converse.api.listen.on('messageNotification', data => { ... }); - */ - - - api.trigger('messageNotification', data); - playSoundNotification(); - showMessageNotification(data); -} -function handleFeedback(data) { - if (areDesktopNotificationsEnabled(true)) { - showFeedbackNotification(data); - } -} -/** - * Event handler for on('contactPresenceChanged'). - * Will show an HTML5 notification to indicate that the chat status has changed. - */ - -function handleChatStateNotification(contact) { - if (areDesktopNotificationsEnabled() && api.settings.get('show_chat_state_notifications')) { - showChatStateNotification(contact); - } -} - -function showContactRequestNotification(contact) { - const n = new Notification(contact.getDisplayName(), { - body: __('wants to be your contact'), - lang: shared_converse.locale, - icon: shared_converse.notification_icon - }); - setTimeout(() => n.close(), 5000); -} - -function handleContactRequestNotification(contact) { - if (areDesktopNotificationsEnabled(true)) { - showContactRequestNotification(contact); - } -} -function requestPermission() { - if (supports_html5_notification && !['denied', 'granted'].includes(Notification.permission)) { - // Ask user to enable HTML5 notifications - Notification.requestPermission(); - } -} -;// CONCATENATED MODULE: ./src/plugins/notifications/index.js -/** - * @module converse-notification - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - -core_converse.plugins.add('converse-notification', { - dependencies: ['converse-chatboxes'], - - initialize() { - api.settings.extend({ - // ^ a list of JIDs to ignore concerning chat state notifications - chatstate_notification_blacklist: [], - notification_delay: 5000, - notification_icon: 'logo/conversejs-filled.svg', - notify_all_room_messages: false, - notify_nicknames_without_references: false, - play_sounds: true, - show_chat_state_notifications: false, - show_desktop_notifications: true, - show_tab_notifications: true, - sounds_path: api.settings.get('assets_path') + '/sounds/' - }); - /************************ Event Handlers ************************/ - - api.listen.on('clearSession', clearFavicon); // Needed for tests - - api.waitUntil('chatBoxesInitialized').then(() => shared_converse.chatboxes.on('change:num_unread', updateUnreadFavicon)); - api.listen.on('pluginsInitialized', function () { - // We only register event handlers after all plugins are - // registered, because other plugins might override some of our - // handlers. - api.listen.on('contactRequest', handleContactRequestNotification); - api.listen.on('contactPresenceChanged', handleChatStateNotification); - api.listen.on('message', handleMessageNotification); - api.listen.on('feedback', handleFeedback); - api.listen.on('connected', requestPermission); - }); - } - -}); -;// CONCATENATED MODULE: ./src/modals/templates/user-settings.js - - - - - - - -const user_settings_tpl_navigation = o => { - const i18n_about = __('About'); - - const i18n_commands = __('Commands'); - - return T` - - `; -}; - -/* harmony default export */ const templates_user_settings = (o => { - const i18n_modal_title = __('Settings'); - - const first_subtitle = __('%1$s Open Source %2$s XMPP chat client brought to you by %3$s Opkode %2$s', '', '', ''); - - const second_subtitle = __('%1$s Translate %2$s it into your own language', '', ''); - - const show_client_info = api.settings.get('show_client_info'); - const allow_adhoc_commands = api.settings.get('allow_adhoc_commands'); - const show_both_tabs = show_client_info && allow_adhoc_commands; - return T` - -`; -}); -;// CONCATENATED MODULE: ./src/modals/user-settings.js - - - -let user_settings_converse; - -/* harmony default export */ const modals_user_settings = (base.extend({ - id: "converse-client-info-modal", - - initialize(settings) { - user_settings_converse = settings._converse; - base.prototype.initialize.apply(this, arguments); - }, - - toHTML() { - return templates_user_settings(Object.assign(this.model.toJSON(), this.model.vcard.toJSON(), { - 'version_name': user_settings_converse.VERSION_NAME - })); - } - -})); -;// CONCATENATED MODULE: ./src/plugins/profile/templates/profile.js - - - -/* harmony default export */ const profile = (o => { - const i18n_logout = __('Log out'); - - const i18n_change_status = __('Click to change your chat status'); - - const i18n_details = __('Show details about this chat client'); - - const show_settings_button = api.settings.get('show_client_info') || api.settings.get('allow_adhoc_commands'); - return T` -
    -
    - - - - ${o.fullname} - ${show_settings_button ? T`` : ''} - ${api.settings.get('allow_logout') ? T`` : ''} -
    - -
    -`; -}); -;// CONCATENATED MODULE: ./src/plugins/profile/statusview.js - - - - - - - -function getPrettyStatus(stat) { - if (stat === 'chat') { - return __('online'); - } else if (stat === 'dnd') { - return __('busy'); - } else if (stat === 'xa') { - return __('away for long'); - } else if (stat === 'away') { - return __('away'); - } else if (stat === 'offline') { - return __('offline'); - } else { - return __(stat) || __('online'); - } -} - -class ProfileView extends ElementViewWithAvatar { - async initialize() { - this.model = shared_converse.xmppstatus; - this.listenTo(this.model, "change", this.render); - await api.waitUntil('VCardsInitialized'); - this.listenTo(this.model.vcard, "change", this.render); - this.render(); - } - - render() { - const chat_status = this.model.get('status') || 'offline'; - V(profile(Object.assign(this.model.toJSON(), this.model.vcard.toJSON(), { - chat_status, - 'fullname': this.model.vcard.get('fullname') || shared_converse.bare_jid, - "showUserSettingsModal": ev => this.showUserSettingsModal(ev), - 'status_message': this.model.get('status_message') || __("I am %1$s", getPrettyStatus(chat_status)), - 'logout': this.logout, - 'showStatusChangeModal': () => this.showStatusChangeModal(), - 'showProfileModal': () => this.showProfileModal() - })), this); - this.renderAvatar(); - } - - showProfileModal(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - api.modal.show(shared_converse.ProfileModal, { - model: this.model - }, ev); - } - - showStatusChangeModal(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - api.modal.show(shared_converse.ChatStatusModal, { - model: this.model - }, ev); - } - - showUserSettingsModal(ev) { - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - api.modal.show(modals_user_settings, { - model: this.model, - _converse: shared_converse - }, ev); - } - - logout(ev) { - // eslint-disable-line class-methods-use-this - ev === null || ev === void 0 ? void 0 : ev.preventDefault(); - const result = confirm(__("Are you sure you want to log out?")); - - if (result === true) { - api.user.logout(); - } - } - -} - -api.elements.define('converse-user-profile', ProfileView); -;// CONCATENATED MODULE: ./src/modals/templates/chat-status.js - - -/* harmony default export */ const chat_status = (o => T` - -`); -;// CONCATENATED MODULE: ./src/modals/chat-status.js - - - - -const chat_status_u = core_converse.env.utils; -const ChatStatusModal = base.extend({ - id: "modal-status-change", - events: { - "submit form#set-xmpp-status": "onFormSubmitted", - "click .clear-input": "clearStatusMessage" - }, - - toHTML() { - return chat_status(Object.assign(this.model.toJSON(), this.model.vcard.toJSON(), { - 'label_away': __('Away'), - 'label_busy': __('Busy'), - 'label_cancel': __('Cancel'), - 'label_close': __('Close'), - 'label_custom_status': __('Custom status'), - 'label_offline': __('Offline'), - 'label_online': __('Online'), - 'label_save': __('Save'), - 'label_xa': __('Away for long'), - 'modal_title': __('Change chat status'), - 'placeholder_status_message': __('Personal status message') - })); - }, - - afterRender() { - this.el.addEventListener('shown.bs.modal', () => { - this.el.querySelector('input[name="status_message"]').focus(); - }, false); - }, - - clearStatusMessage(ev) { - if (ev && ev.preventDefault) { - ev.preventDefault(); - chat_status_u.hideElement(this.el.querySelector('.clear-input')); - } - - const roster_filter = this.el.querySelector('input[name="status_message"]'); - roster_filter.value = ''; - }, - - onFormSubmitted(ev) { - ev.preventDefault(); - const data = new FormData(ev.target); - this.model.save({ - 'status_message': data.get('status_message'), - 'status': data.get('chat_status') - }); - this.modal.hide(); - } - -}); -shared_converse.ChatStatusModal = ChatStatusModal; -/* harmony default export */ const modals_chat_status = ((/* unused pure expression or super */ null && (ChatStatusModal))); -;// CONCATENATED MODULE: ./src/shared/components/image-picker.js - - - - - - -const i18n_profile_picture = __('Your profile picture'); - -class ImagePicker extends CustomElement { - static get properties() { - return { - 'height': { - type: Number - }, - 'image': { - type: String - }, - 'width': { - type: Number - } - }; - } - - render() { - const avatar_data = { - 'height': this.height, - 'image': this.image, - 'width': this.width - }; - return T` - - ${renderAvatar(avatar_data)} - - - `; - } - - openFileSelection(ev) { - ev.preventDefault(); - this.querySelector('input[type="file"]').click(); - } - - updateFilePreview(ev) { - const file = ev.target.files[0]; - const reader = new FileReader(); - - reader.onloadend = () => this.image = reader.result; - - reader.readAsDataURL(file); - } - -} -api.elements.define('converse-image-picker', ImagePicker); -;// CONCATENATED MODULE: ./src/modals/templates/profile.js - - - - - - -const profile_u = core_converse.env.utils; - -const fingerprint = o => T` - ${profile_u.formatFingerprint(o.view.current_device.get('bundle').fingerprint)}`; - -const device_with_fingerprint = o => { - const i18n_fingerprint_checkbox_label = __('Checkbox for selecting the following fingerprint'); - - return T` -
  • - -
  • - `; -}; - -const device_without_fingerprint = o => { - const i18n_device_without_fingerprint = __('Device without a fingerprint'); - - const i18n_fingerprint_checkbox_label = __('Checkbox for selecting the following device'); - - return T` -
  • - -
  • - `; -}; - -const device_item = o => T` - ${o.device.get('bundle') && o.device.get('bundle').fingerprint ? device_with_fingerprint(o) : device_without_fingerprint(o)} -`; - -const device_list = o => { - var _o$view$other_devices; - - const i18n_other_devices = __('Other OMEMO-enabled devices'); - - const i18n_other_devices_label = __('Checkbox to select fingerprints of all other OMEMO devices'); - - const i18n_remove_devices = __('Remove checked devices and close'); - - const i18n_select_all = __('Select all'); - - return T` -
      -
    • - -
    • - ${(_o$view$other_devices = o.view.other_devices) === null || _o$view$other_devices === void 0 ? void 0 : _o$view$other_devices.map(device => device_item(Object.assign({ - device - }, o)))} -
    -
    - `; -}; // TODO: this needs to go as a component into the OMEMO plugin folder - - -const omemo_page = o => { - var _o$view$other_devices2; - - const i18n_fingerprint = __("This device's OMEMO fingerprint"); - - const i18n_generate = __('Generate new keys and fingerprint'); - - return T` -
    -
    -
      -
    • ${i18n_fingerprint}
    • -
    • - ${o.view.current_device && o.view.current_device.get('bundle') && o.view.current_device.get('bundle').fingerprint ? fingerprint(o) : spinner()} -
    • -
    -
    - -
    - ${(_o$view$other_devices2 = o.view.other_devices) !== null && _o$view$other_devices2 !== void 0 && _o$view$other_devices2.length ? device_list(o) : ''} -
    -
    `; -}; - -/* harmony default export */ const templates_profile = (o => { - const heading_profile = __('Your Profile'); - - const i18n_email = __('Email'); - - const i18n_fullname = __('Full Name'); - - const i18n_jid = __('XMPP Address'); - - const i18n_nickname = __('Nickname'); - - const i18n_role = __('Role'); - - const i18n_save = __('Save and close'); - - const i18n_role_help = __('Use commas to separate multiple roles. Your roles are shown next to your name on your chat messages.'); - - const i18n_url = __('URL'); - - const i18n_omemo = __('OMEMO'); - - const i18n_profile = __('Profile'); - - const navigation = o.view.current_device ? T`` : ''; - return T` - - `; -}); -;// CONCATENATED MODULE: ./src/modals/profile.js - - - - - - -const { - sizzle: profile_sizzle -} = converse.env; -const ProfileModal = base.extend({ - id: "user-profile-modal", - events: { - 'submit .profile-form': 'onFormSubmitted' - }, - - initialize() { - this.listenTo(this.model, 'change', this.render); - base.prototype.initialize.apply(this, arguments); - /** - * Triggered when the _converse.ProfileModal has been created and initialized. - * @event _converse#profileModalInitialized - * @type { _converse.XMPPStatus } - * @example _converse.api.listen.on('profileModalInitialized', status => { ... }); - */ - - api.trigger('profileModalInitialized', this.model); - }, - - toHTML() { - return templates_profile(Object.assign(this.model.toJSON(), this.model.vcard.toJSON(), this.getAvatarData(), { - 'view': this - })); - }, - - getAvatarData() { - const image_type = this.model.vcard.get('image_type'); - const image_data = this.model.vcard.get('image'); - const image = "data:" + image_type + ";base64," + image_data; - return { - 'height': 128, - 'width': 128, - image - }; - }, - - afterRender() { - this.tabs = profile_sizzle('.nav-item .nav-link', this.el).map(e => new (bootstrap_native_default()).Tab(e)); - }, - - async setVCard(data) { - try { - await api.vcard.set(shared_converse.bare_jid, data); - } catch (err) { - headless_log.fatal(err); - this.alert([__("Sorry, an error happened while trying to save your profile data."), __("You can check your browser's developer console for any error output.")].join(" ")); - return; - } - - this.modal.hide(); - }, - - onFormSubmitted(ev) { - ev.preventDefault(); - const reader = new FileReader(); - const form_data = new FormData(ev.target); - const image_file = form_data.get('image'); - const data = { - 'fn': form_data.get('fn'), - 'nickname': form_data.get('nickname'), - 'role': form_data.get('role'), - 'email': form_data.get('email'), - 'url': form_data.get('url') - }; - - if (!image_file.size) { - Object.assign(data, { - 'image': this.model.vcard.get('image'), - 'image_type': this.model.vcard.get('image_type') - }); - this.setVCard(data); - } else { - reader.onloadend = () => { - Object.assign(data, { - 'image': btoa(reader.result), - 'image_type': image_file.type - }); - this.setVCard(data); - }; - - reader.readAsBinaryString(image_file); - } - } - -}); -shared_converse.ProfileModal = ProfileModal; -/* harmony default export */ const modals_profile = ((/* unused pure expression or super */ null && (ProfileModal))); -;// CONCATENATED MODULE: ./src/plugins/profile/index.js -/** - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - -core_converse.plugins.add('converse-profile', { - dependencies: ["converse-status", "converse-modal", "converse-vcard", "converse-chatboxviews"], - - initialize() { - api.settings.extend({ - 'allow_adhoc_commands': true, - 'show_client_info': true - }); - } - -}); -;// CONCATENATED MODULE: ./src/utils/file.js -const MIMETYPES_MAP = { - 'aac': 'audio/aac', - 'abw': 'application/x-abiword', - 'arc': 'application/x-freearc', - 'avi': 'video/x-msvideo', - 'azw': 'application/vnd.amazon.ebook', - 'bin': 'application/octet-stream', - 'bmp': 'image/bmp', - 'bz': 'application/x-bzip', - 'bz2': 'application/x-bzip2', - 'cda': 'application/x-cdf', - 'csh': 'application/x-csh', - 'css': 'text/css', - 'csv': 'text/csv', - 'doc': 'application/msword', - 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'eot': 'application/vnd.ms-fontobject', - 'epub': 'application/epub+zip', - 'gif': 'image/gif', - 'gz': 'application/gzip', - 'htm': 'text/html', - 'html': 'text/html', - 'ico': 'image/vnd.microsoft.icon', - 'ics': 'text/calendar', - 'jar': 'application/java-archive', - 'jpeg': 'image/jpeg', - 'jpg': 'image/jpeg', - 'js': 'text/javascript', - 'json': 'application/json', - 'jsonld': 'application/ld+json', - 'm4a': 'audio/mp4', - 'mid': 'audio/midi', - 'midi': 'audio/midi', - 'mjs': 'text/javascript', - 'mp3': 'audio/mpeg', - 'mp4': 'video/mp4', - 'mpeg': 'video/mpeg', - 'mpkg': 'application/vnd.apple.installer+xml', - 'odp': 'application/vnd.oasis.opendocument.presentation', - 'ods': 'application/vnd.oasis.opendocument.spreadsheet', - 'odt': 'application/vnd.oasis.opendocument.text', - 'oga': 'audio/ogg', - 'ogv': 'video/ogg', - 'ogx': 'application/ogg', - 'opus': 'audio/opus', - 'otf': 'font/otf', - 'png': 'image/png', - 'pdf': 'application/pdf', - 'php': 'application/x-httpd-php', - 'ppt': 'application/vnd.ms-powerpoint', - 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'rar': 'application/vnd.rar', - 'rtf': 'application/rtf', - 'sh': 'application/x-sh', - 'svg': 'image/svg+xml', - 'swf': 'application/x-shockwave-flash', - 'tar': 'application/x-tar', - 'tif': 'image/tiff', - 'tiff': 'image/tiff', - 'ts': 'video/mp2t', - 'ttf': 'font/ttf', - 'txt': 'text/plain', - 'vsd': 'application/vnd.visio', - 'wav': 'audio/wav', - 'weba': 'audio/webm', - 'webm': 'video/webm', - 'webp': 'image/webp', - 'woff': 'font/woff', - 'woff2': 'font/woff2', - 'xhtml': 'application/xhtml+xml', - 'xls': 'application/vnd.ms-excel', - 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xml': 'text/xml', - 'xul': 'application/vnd.mozilla.xul+xml', - 'zip': 'application/zip', - '3gp': 'video/3gpp', - '3g2': 'video/3gpp2', - '7z': 'application/x-7z-compressed' -}; -;// CONCATENATED MODULE: ./src/plugins/omemo/consts.js -const UNDECIDED = 0; -const TRUSTED = 1; -const UNTRUSTED = -1; -const TAG_LENGTH = 128; -const KEY_ALGO = { - 'name': 'AES-GCM', - 'length': 128 -}; -;// CONCATENATED MODULE: ./node_modules/lodash-es/concat.js - - - - -/** - * Creates a new array concatenating `array` with any additional arrays - * and/or values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to concatenate. - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example - * - * var array = [1]; - * var other = _.concat(array, 2, [3], [[4]]); - * - * console.log(other); - * // => [1, 2, 3, [4]] - * - * console.log(array); - * // => [1] - */ - -function concat() { - var length = arguments.length; - - if (!length) { - return []; - } - - var args = Array(length - 1), - array = arguments[0], - index = length; - - while (index--) { - args[index - 1] = arguments[index]; - } - - return _arrayPush(lodash_es_isArray(array) ? _copyArray(array) : [array], _baseFlatten(args, 1)); -} - -/* harmony default export */ const lodash_es_concat = (concat); -;// CONCATENATED MODULE: ./src/headless/utils/arraybuffer.js - -const { - u: arraybuffer_u -} = core_converse.env; -function appendArrayBuffer(buffer1, buffer2) { - const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); - tmp.set(new Uint8Array(buffer1), 0); - tmp.set(new Uint8Array(buffer2), buffer1.byteLength); - return tmp.buffer; -} -function arrayBufferToHex(ab) { - // https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex#40031979 - return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join(''); -} -function arrayBufferToString(ab) { - return new TextDecoder("utf-8").decode(ab); -} -function stringToArrayBuffer(string) { - const bytes = new TextEncoder("utf-8").encode(string); - return bytes.buffer; -} -function arrayBufferToBase64(ab) { - return btoa(new Uint8Array(ab).reduce((data, byte) => data + String.fromCharCode(byte), '')); -} -function base64ToArrayBuffer(b64) { - const binary_string = window.atob(b64), - len = binary_string.length, - bytes = new Uint8Array(len); - - for (let i = 0; i < len; i++) { - bytes[i] = binary_string.charCodeAt(i); - } - - return bytes.buffer; -} -function hexToArrayBuffer(hex) { - const typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(h => parseInt(h, 16))); - return typedArray.buffer; -} -Object.assign(arraybuffer_u, { - arrayBufferToHex, - arrayBufferToString, - stringToArrayBuffer, - arrayBufferToBase64, - base64ToArrayBuffer -}); -;// CONCATENATED MODULE: ./src/plugins/omemo/utils.js -/* global libsignal */ - - - - - - - - - - - - - - - - -const { - $msg: utils_$msg, - Strophe: omemo_utils_Strophe, - URI: utils_URI, - sizzle: omemo_utils_sizzle, - u: omemo_utils_u -} = core_converse.env; - -async function encryptMessage(plaintext) { - // The client MUST use fresh, randomly generated key/IV pairs - // with AES-128 in Galois/Counter Mode (GCM). - // For GCM a 12 byte IV is strongly suggested as other IV lengths - // will require additional calculations. In principle any IV size - // can be used as long as the IV doesn't ever repeat. NIST however - // suggests that only an IV size of 12 bytes needs to be supported - // by implementations. - // - // https://crypto.stackexchange.com/questions/26783/ciphertext-and-tag-size-and-iv-transmission-with-aes-in-gcm-mode - const iv = crypto.getRandomValues(new window.Uint8Array(12)); - const key = await crypto.subtle.generateKey(KEY_ALGO, true, ['encrypt', 'decrypt']); - const algo = { - 'name': 'AES-GCM', - 'iv': iv, - 'tagLength': TAG_LENGTH - }; - const encrypted = await crypto.subtle.encrypt(algo, key, stringToArrayBuffer(plaintext)); - const length = encrypted.byteLength - (128 + 7 >> 3); - const ciphertext = encrypted.slice(0, length); - const tag = encrypted.slice(length); - const exported_key = await crypto.subtle.exportKey('raw', key); - return { - 'key': exported_key, - 'tag': tag, - 'key_and_tag': appendArrayBuffer(exported_key, tag), - 'payload': arrayBufferToBase64(ciphertext), - 'iv': arrayBufferToBase64(iv) - }; -} - -async function decryptMessage(obj) { - const key_obj = await crypto.subtle.importKey('raw', obj.key, KEY_ALGO, true, ['encrypt', 'decrypt']); - const cipher = appendArrayBuffer(base64ToArrayBuffer(obj.payload), obj.tag); - const algo = { - 'name': 'AES-GCM', - 'iv': base64ToArrayBuffer(obj.iv), - 'tagLength': TAG_LENGTH - }; - return arrayBufferToString(await crypto.subtle.decrypt(algo, key_obj, cipher)); -} - -const omemo = { - decryptMessage, - encryptMessage -}; -async function encryptFile(file) { - const iv = crypto.getRandomValues(new Uint8Array(12)); - const key = await crypto.subtle.generateKey({ - name: 'AES-GCM', - length: 256 - }, true, ['encrypt', 'decrypt']); - const encrypted = await crypto.subtle.encrypt({ - name: 'AES-GCM', - iv - }, key, await file.arrayBuffer()); - const exported_key = await window.crypto.subtle.exportKey('raw', key); - const encrypted_file = new File([encrypted], file.name, { - type: file.type, - lastModified: file.lastModified - }); - encrypted_file.xep454_ivkey = arrayBufferToHex(iv) + arrayBufferToHex(exported_key); - return encrypted_file; -} -function setEncryptedFileURL(message, attrs) { - const url = attrs.oob_url.replace(/^https?:/, 'aesgcm:') + '#' + message.file.xep454_ivkey; - return Object.assign(attrs, { - 'oob_url': null, - // Since only the body gets encrypted, we don't set the oob_url - 'message': url, - 'body': url - }); -} - -async function decryptFile(iv, key, cipher) { - const key_obj = await crypto.subtle.importKey('raw', hexToArrayBuffer(key), 'AES-GCM', false, ['decrypt']); - const algo = { - 'name': 'AES-GCM', - 'iv': hexToArrayBuffer(iv) - }; - return crypto.subtle.decrypt(algo, key_obj, cipher); -} - -async function downloadFile(url) { - let response; - - try { - response = await fetch(url); - } catch (e) { - headless_log.error(`${e.name}: Failed to download encrypted media: ${url}`); - headless_log.error(e); - return null; - } - - if (response.status >= 200 && response.status < 400) { - return response.arrayBuffer(); - } -} - -async function getAndDecryptFile(uri) { - var _uri$filename; - - const hash = uri.hash().slice(1); - const protocol = window.location.hostname === 'localhost' ? 'http' : 'https'; - const http_url = uri.toString().replace(/^aesgcm/, protocol); - const cipher = await downloadFile(http_url); - - if (cipher === null) { - headless_log.error(`Could not decrypt file ${uri.toString()} since it could not be downloaded`); - return null; - } - - const iv = hash.slice(0, 24); - const key = hash.slice(24); - let content; - - try { - content = await decryptFile(iv, key, cipher); - } catch (e) { - headless_log.error(`Could not decrypt file ${uri.toString()}`); - headless_log.error(e); - return null; - } - - const [filename, extension] = (_uri$filename = uri.filename()) === null || _uri$filename === void 0 ? void 0 : _uri$filename.split('.'); - const mimetype = MIMETYPES_MAP[extension]; - - try { - const file = new File([content], filename, { - 'type': mimetype - }); - return URL.createObjectURL(file); - } catch (e) { - headless_log.error(`Could not decrypt file ${uri.toString()}`); - headless_log.error(e); - return null; - } -} - -function getTemplateForObjectURL(uri, obj_url, richtext) { - const file_url = uri.toString(); - - if (obj_url === null) { - return file_url; - } - - if (isImageURL(file_url)) { - return src_templates_image({ - 'url': obj_url, - 'onClick': richtext.onImgClick, - 'onLoad': richtext.onImgLoad - }); - } else if (isAudioURL(file_url)) { - return audio(obj_url); - } else if (isVideoURL(file_url)) { - return video(obj_url); - } else { - return file(obj_url, uri.filename()); - } -} - -function addEncryptedFiles(text, offset, richtext) { - const objs = []; - - try { - const parse_options = { - 'start': /\b(aesgcm:\/\/)/gi - }; - utils_URI.withinString(text, (url, start, end) => { - objs.push({ - url, - start, - end - }); - return url; - }, parse_options); - } catch (error) { - headless_log.debug(error); - return; - } - - objs.forEach(o => { - const uri = getURI(text.slice(o.start, o.end)); - const promise = getAndDecryptFile(uri).then(obj_url => getTemplateForObjectURL(uri, obj_url, richtext)); - const template = T`${until_o(promise, '')}`; - richtext.addTemplateResult(o.start + offset, o.end + offset, template); - }); -} - -function handleEncryptedFiles(richtext) { - if (!shared_converse.config.get('trusted')) { - return; - } - - richtext.addAnnotations((text, offset) => addEncryptedFiles(text, offset, richtext)); -} -function parseEncryptedMessage(stanza, attrs) { - if (attrs.is_encrypted && attrs.encrypted.key) { - // https://xmpp.org/extensions/xep-0384.html#usecases-receiving - if (attrs.encrypted.prekey === true) { - return decryptPrekeyWhisperMessage(attrs); - } else { - return decryptWhisperMessage(attrs); - } - } else { - return attrs; - } -} -function utils_onChatBoxesInitialized() { - shared_converse.chatboxes.on('add', chatbox => { - checkOMEMOSupported(chatbox); - - if (chatbox.get('type') === shared_converse.CHATROOMS_TYPE) { - chatbox.occupants.on('add', o => onOccupantAdded(chatbox, o)); - chatbox.features.on('change', () => checkOMEMOSupported(chatbox)); - } - }); -} -function onChatInitialized(el) { - el.listenTo(el.model.messages, 'add', message => { - if (message.get('is_encrypted') && !message.get('is_error')) { - el.model.save('omemo_supported', true); - } - }); - el.listenTo(el.model, 'change:omemo_supported', () => { - if (!el.model.get('omemo_supported') && el.model.get('omemo_active')) { - el.model.set('omemo_active', false); - } else { - var _el$querySelector; - - // Manually trigger an update, setting omemo_active to - // false above will automatically trigger one. - (_el$querySelector = el.querySelector('converse-chat-toolbar')) === null || _el$querySelector === void 0 ? void 0 : _el$querySelector.requestUpdate(); - } - }); - el.listenTo(el.model, 'change:omemo_active', () => { - el.querySelector('converse-chat-toolbar').requestUpdate(); - }); -} -function getSessionCipher(jid, id) { - const address = new libsignal.SignalProtocolAddress(jid, id); - return new window.libsignal.SessionCipher(shared_converse.omemo_store, address); -} - -async function handleDecryptedWhisperMessage(attrs, key_and_tag) { - const encrypted = attrs.encrypted; - - const devicelist = shared_converse.devicelists.getDeviceList(attrs.from); - - await devicelist._devices_promise; - let device = devicelist.get(encrypted.device_id); - - if (!device) { - device = await devicelist.devices.create({ - 'id': encrypted.device_id, - 'jid': attrs.from - }, { - 'promise': true - }); - } - - if (encrypted.payload) { - const key = key_and_tag.slice(0, 16); - const tag = key_and_tag.slice(16); - const result = await omemo.decryptMessage(Object.assign(encrypted, { - 'key': key, - 'tag': tag - })); - device.save('active', true); - return result; - } -} - -function getDecryptionErrorAttributes(e) { - if (api.settings.get('loglevel') === 'debug') { - return { - 'error_text': __('Sorry, could not decrypt a received OMEMO message due to an error.') + ` ${e.name} ${e.message}`, - 'error_type': 'Decryption', - 'is_ephemeral': true, - 'is_error': true, - 'type': 'error' - }; - } else { - return {}; - } -} - -async function decryptPrekeyWhisperMessage(attrs) { - const session_cipher = getSessionCipher(attrs.from, parseInt(attrs.encrypted.device_id, 10)); - const key = base64ToArrayBuffer(attrs.encrypted.key); - let key_and_tag; - - try { - key_and_tag = await session_cipher.decryptPreKeyWhisperMessage(key, 'binary'); - } catch (e) { - // TODO from the XEP: - // There are various reasons why decryption of an - // OMEMOKeyExchange or an OMEMOAuthenticatedMessage - // could fail. One reason is if the message was - // received twice and already decrypted once, in this - // case the client MUST ignore the decryption failure - // and not show any warnings/errors. In all other cases - // of decryption failure, clients SHOULD respond by - // forcibly doing a new key exchange and sending a new - // OMEMOKeyExchange with a potentially empty SCE - // payload. By building a new session with the original - // sender this way, the invalid session of the original - // sender will get overwritten with this newly created, - // valid session. - headless_log.error(`${e.name} ${e.message}`); - return Object.assign(attrs, getDecryptionErrorAttributes(e)); - } // TODO from the XEP: - // When a client receives the first message for a given - // ratchet key with a counter of 53 or higher, it MUST send - // a heartbeat message. Heartbeat messages are normal OMEMO - // encrypted messages where the SCE payload does not include - // any elements. These heartbeat messages cause the ratchet - // to forward, thus consequent messages will have the - // counter restarted from 0. - - - try { - const plaintext = await handleDecryptedWhisperMessage(attrs, key_and_tag); - await shared_converse.omemo_store.generateMissingPreKeys(); - await shared_converse.omemo_store.publishBundle(); - - if (plaintext) { - return Object.assign(attrs, { - 'plaintext': plaintext - }); - } else { - return Object.assign(attrs, { - 'is_only_key': true - }); - } - } catch (e) { - headless_log.error(`${e.name} ${e.message}`); - return Object.assign(attrs, getDecryptionErrorAttributes(e)); - } -} - -async function decryptWhisperMessage(attrs) { - const from_jid = attrs.from_muc ? attrs.from_real_jid : attrs.from; - - if (!from_jid) { - Object.assign(attrs, { - 'error_text': __("Sorry, could not decrypt a received OMEMO message because we don't have the XMPP address for that user."), - 'error_type': 'Decryption', - 'is_ephemeral': false, - 'is_error': true, - 'type': 'error' - }); - } - - const session_cipher = getSessionCipher(from_jid, parseInt(attrs.encrypted.device_id, 10)); - const key = base64ToArrayBuffer(attrs.encrypted.key); - - try { - const key_and_tag = await session_cipher.decryptWhisperMessage(key, 'binary'); - const plaintext = await handleDecryptedWhisperMessage(attrs, key_and_tag); - return Object.assign(attrs, { - 'plaintext': plaintext - }); - } catch (e) { - headless_log.error(`${e.name} ${e.message}`); - return Object.assign(attrs, getDecryptionErrorAttributes(e)); - } -} - -function addKeysToMessageStanza(stanza, dicts, iv) { - for (const i in dicts) { - if (Object.prototype.hasOwnProperty.call(dicts, i)) { - const payload = dicts[i].payload; - const device = dicts[i].device; - const prekey = 3 == parseInt(payload.type, 10); - stanza.c('key', { - 'rid': device.get('id') - }).t(btoa(payload.body)); - - if (prekey) { - stanza.attrs({ - 'prekey': prekey - }); - } - - stanza.up(); - - if (i == dicts.length - 1) { - stanza.c('iv').t(iv).up().up(); - } - } - } - - return Promise.resolve(stanza); -} -/** - * Given an XML element representing a user's OMEMO bundle, parse it - * and return a map. - */ - -function parseBundle(bundle_el) { - const signed_prekey_public_el = bundle_el.querySelector('signedPreKeyPublic'); - const signed_prekey_signature_el = bundle_el.querySelector('signedPreKeySignature'); - const prekeys = omemo_utils_sizzle(`prekeys > preKeyPublic`, bundle_el).map(el => ({ - 'id': parseInt(el.getAttribute('preKeyId'), 10), - 'key': el.textContent - })); - return { - 'identity_key': bundle_el.querySelector('identityKey').textContent.trim(), - 'signed_prekey': { - 'id': parseInt(signed_prekey_public_el.getAttribute('signedPreKeyId'), 10), - 'public_key': signed_prekey_public_el.textContent, - 'signature': signed_prekey_signature_el.textContent - }, - 'prekeys': prekeys - }; -} -async function generateFingerprint(device) { - var _device$get; - - if ((_device$get = device.get('bundle')) !== null && _device$get !== void 0 && _device$get.fingerprint) { - return; - } - - const bundle = await device.getBundle(); - bundle['fingerprint'] = arrayBufferToHex(base64ToArrayBuffer(bundle['identity_key'])); - device.save('bundle', bundle); - device.trigger('change:bundle'); // Doesn't get triggered automatically due to pass-by-reference -} -async function getDevicesForContact(jid) { - await api.waitUntil('OMEMOInitialized'); - - const devicelist = shared_converse.devicelists.get(jid) || shared_converse.devicelists.create({ - 'jid': jid - }); - - await devicelist.fetchDevices(); - return devicelist.devices; -} -function generateDeviceID() { - /* Generates a device ID, making sure that it's unique */ - const existing_ids = shared_converse.devicelists.get(shared_converse.bare_jid).devices.pluck('id'); - - let device_id = libsignal.KeyHelper.generateRegistrationId(); // Before publishing a freshly generated device id for the first time, - // a device MUST check whether that device id already exists, and if so, generate a new one. - - let i = 0; - - while (existing_ids.includes(device_id)) { - device_id = libsignal.KeyHelper.generateRegistrationId(); - i++; - - if (i === 10) { - throw new Error('Unable to generate a unique device ID'); - } - } - - return device_id.toString(); -} - -async function buildSession(device) { - // TODO: check device-get('jid') versus the 'from' attribute which is used - // to build a session when receiving an encrypted message in a MUC. - // https://github.com/conversejs/converse.js/issues/1481#issuecomment-509183431 - const address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id')); - const sessionBuilder = new libsignal.SessionBuilder(shared_converse.omemo_store, address); - const prekey = device.getRandomPreKey(); - const bundle = await device.getBundle(); - return sessionBuilder.processPreKey({ - 'registrationId': parseInt(device.get('id'), 10), - 'identityKey': base64ToArrayBuffer(bundle.identity_key), - 'signedPreKey': { - 'keyId': bundle.signed_prekey.id, - // - 'publicKey': base64ToArrayBuffer(bundle.signed_prekey.public_key), - 'signature': base64ToArrayBuffer(bundle.signed_prekey.signature) - }, - 'preKey': { - 'keyId': prekey.id, - // - 'publicKey': base64ToArrayBuffer(prekey.key) - } - }); -} - -async function getSession(device) { - if (!device.get('bundle')) { - headless_log.error(`Could not build an OMEMO session for device ${device.get('id')} because we don't have its bundle`); - return null; - } - - const address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id')); - const session = await shared_converse.omemo_store.loadSession(address.toString()); - - if (session) { - return session; - } else { - try { - const session = await buildSession(device); - return session; - } catch (e) { - headless_log.error(`Could not build an OMEMO session for device ${device.get('id')}`); - headless_log.error(e); - return null; - } - } -} - -function updateBundleFromStanza(stanza) { - const items_el = omemo_utils_sizzle(`items`, stanza).pop(); - - if (!items_el || !items_el.getAttribute('node').startsWith(omemo_utils_Strophe.NS.OMEMO_BUNDLES)) { - return; - } - - const device_id = items_el.getAttribute('node').split(':')[1]; - const jid = stanza.getAttribute('from'); - const bundle_el = omemo_utils_sizzle(`item > bundle`, items_el).pop(); - - const devicelist = shared_converse.devicelists.getDeviceList(jid); - - const device = devicelist.devices.get(device_id) || devicelist.devices.create({ - 'id': device_id, - 'jid': jid - }); - device.save({ - 'bundle': parseBundle(bundle_el) - }); -} - -function updateDevicesFromStanza(stanza) { - const items_el = omemo_utils_sizzle(`items[node="${omemo_utils_Strophe.NS.OMEMO_DEVICELIST}"]`, stanza).pop(); - - if (!items_el) { - return; - } - - const device_selector = `item list[xmlns="${omemo_utils_Strophe.NS.OMEMO}"] device`; - const device_ids = omemo_utils_sizzle(device_selector, items_el).map(d => d.getAttribute('id')); - const jid = stanza.getAttribute('from'); - - const devicelist = shared_converse.devicelists.getDeviceList(jid); - - const devices = devicelist.devices; - const removed_ids = lodash_es_difference(devices.pluck('id'), device_ids); - removed_ids.forEach(id => { - if (jid === shared_converse.bare_jid && id === shared_converse.omemo_store.get('device_id')) { - return; // We don't set the current device as inactive - } - - devices.get(id).save('active', false); - }); - device_ids.forEach(device_id => { - const device = devices.get(device_id); - - if (device) { - device.save('active', true); - } else { - devices.create({ - 'id': device_id, - 'jid': jid - }); - } - }); - - if (omemo_utils_u.isSameBareJID(jid, shared_converse.bare_jid)) { - // Make sure our own device is on the list - // (i.e. if it was removed, add it again). - devicelist.publishCurrentDevice(device_ids); - } -} - -function registerPEPPushHandler() { - // Add a handler for devices pushed from other connected clients - shared_converse.connection.addHandler(message => { - try { - if (omemo_utils_sizzle(`event[xmlns="${omemo_utils_Strophe.NS.PUBSUB}#event"]`, message).length) { - updateDevicesFromStanza(message); - updateBundleFromStanza(message); - } - } catch (e) { - headless_log.error(e.message); - } - - return true; - }, null, 'message', 'headline'); -} -function restoreOMEMOSession() { - if (shared_converse.omemo_store === undefined) { - const id = `converse.omemosession-${shared_converse.bare_jid}`; - shared_converse.omemo_store = new shared_converse.OMEMOStore({ - id - }); - initStorage(shared_converse.omemo_store, id); - } - - return shared_converse.omemo_store.fetchSession(); -} - -function fetchDeviceLists() { - return new Promise((success, error) => shared_converse.devicelists.fetch({ - success, - 'error': (m, e) => error(e) - })); -} - -async function fetchOwnDevices() { - await fetchDeviceLists(); - - let own_devicelist = shared_converse.devicelists.get(shared_converse.bare_jid); - - if (own_devicelist) { - own_devicelist.fetchDevices(); - } else { - own_devicelist = await shared_converse.devicelists.create({ - 'jid': shared_converse.bare_jid - }, { - 'promise': true - }); - } - - return own_devicelist._devices_promise; -} - -async function initOMEMO() { - if (!shared_converse.config.get('trusted') || api.settings.get('clear_cache_on_logout')) { - headless_log.warn('Not initializing OMEMO, since this browser is not trusted or clear_cache_on_logout is set to true'); - return; - } - - shared_converse.devicelists = new shared_converse.DeviceLists(); - const id = `converse.devicelists-${shared_converse.bare_jid}`; - initStorage(shared_converse.devicelists, id); - - try { - await fetchOwnDevices(); - await restoreOMEMOSession(); - await shared_converse.omemo_store.publishBundle(); - } catch (e) { - headless_log.error('Could not initialize OMEMO support'); - headless_log.error(e); - return; - } - /** - * Triggered once OMEMO support has been initialized - * @event _converse#OMEMOInitialized - * @example _converse.api.listen.on('OMEMOInitialized', () => { ... }); */ - - - api.trigger('OMEMOInitialized'); -} - -async function onOccupantAdded(chatroom, occupant) { - if (occupant.isSelf() || !chatroom.features.get('nonanonymous') || !chatroom.features.get('membersonly')) { - return; - } - - if (chatroom.get('omemo_active')) { - const supported = await shared_converse.contactHasOMEMOSupport(occupant.get('jid')); - - if (!supported) { - chatroom.createMessage({ - 'message': __("%1$s doesn't appear to have a client that supports OMEMO. " + 'Encrypted chat will no longer be possible in this grouchat.', occupant.get('nick')), - 'type': 'error' - }); - chatroom.save({ - 'omemo_active': false, - 'omemo_supported': false - }); - } - } -} - -async function checkOMEMOSupported(chatbox) { - let supported; - - if (chatbox.get('type') === shared_converse.CHATROOMS_TYPE) { - await api.waitUntil('OMEMOInitialized'); - supported = chatbox.features.get('nonanonymous') && chatbox.features.get('membersonly'); - } else if (chatbox.get('type') === shared_converse.PRIVATE_CHAT_TYPE) { - supported = await shared_converse.contactHasOMEMOSupport(chatbox.get('jid')); - } - - chatbox.set('omemo_supported', supported); - - if (supported && api.settings.get('omemo_default')) { - chatbox.set('omemo_active', true); - } -} - -function toggleOMEMO(ev) { - ev.stopPropagation(); - ev.preventDefault(); - const toolbar_el = omemo_utils_u.ancestor(ev.target, 'converse-chat-toolbar'); - - if (!toolbar_el.model.get('omemo_supported')) { - let messages; - - if (toolbar_el.model.get('type') === shared_converse.CHATROOMS_TYPE) { - messages = [__('Cannot use end-to-end encryption in this groupchat, ' + 'either the groupchat has some anonymity or not all participants support OMEMO.')]; - } else { - messages = [__("Cannot use end-to-end encryption because %1$s uses a client that doesn't support OMEMO.", toolbar_el.model.contact.getDisplayName())]; - } - - return api.alert('error', __('Error'), messages); - } - - toolbar_el.model.save({ - 'omemo_active': !toolbar_el.model.get('omemo_active') - }); -} - -function getOMEMOToolbarButton(toolbar_el, buttons) { - const model = toolbar_el.model; - - const is_muc = model.get('type') === shared_converse.CHATROOMS_TYPE; - - let title; - - if (model.get('omemo_supported')) { - const i18n_plaintext = __('Messages are being sent in plaintext'); - - const i18n_encrypted = __('Messages are sent encrypted'); - - title = model.get('omemo_active') ? i18n_encrypted : i18n_plaintext; - } else if (is_muc) { - title = __('This groupchat needs to be members-only and non-anonymous in ' + 'order to support OMEMO encrypted messages'); - } else { - title = __('OMEMO encryption is not supported'); - } - - let color; - - if (model.get('omemo_supported')) { - color = model.get('omemo_active') ? `var(--info-color)` : `var(--error-color)`; - } else { - color = `var(--muc-toolbar-btn-disabled-color)`; - } - - buttons.push(T` - - `); - return buttons; -} -async function getBundlesAndBuildSessions(chatbox) { - const no_devices_err = __('Sorry, no devices found to which we can send an OMEMO encrypted message.'); - - let devices; - - if (chatbox.get('type') === shared_converse.CHATROOMS_TYPE) { - const collections = await Promise.all(chatbox.occupants.map(o => getDevicesForContact(o.get('jid')))); - devices = collections.reduce((a, b) => lodash_es_concat(a, b.models), []); - } else if (chatbox.get('type') === shared_converse.PRIVATE_CHAT_TYPE) { - const their_devices = await getDevicesForContact(chatbox.get('jid')); - - if (their_devices.length === 0) { - const err = new Error(no_devices_err); - err.user_facing = true; - throw err; - } - - const own_devices = shared_converse.devicelists.get(shared_converse.bare_jid).devices; - - devices = [...own_devices.models, ...their_devices.models]; - } // Filter out our own device - - - const id = shared_converse.omemo_store.get('device_id'); - - devices = devices.filter(d => d.get('id') !== id); // Fetch bundles if necessary - - await Promise.all(devices.map(d => d.getBundle())); - const sessions = devices.filter(d => d).map(d => getSession(d)); - await Promise.all(sessions); - - if (sessions.includes(null)) { - // We couldn't build a session for certain devices. - devices = devices.filter(d => sessions[devices.indexOf(d)]); - - if (devices.length === 0) { - const err = new Error(no_devices_err); - err.user_facing = true; - throw err; - } - } - - return devices; -} -function createOMEMOMessageStanza(chatbox, message, devices) { - const body = __('This is an OMEMO encrypted message which your client doesn’t seem to support. ' + 'Find more information on https://conversations.im/omemo'); - - if (!message.get('message')) { - throw new Error('No message body to encrypt!'); - } - - const stanza = utils_$msg({ - 'from': shared_converse.connection.jid, - 'to': chatbox.get('jid'), - 'type': chatbox.get('message_type'), - 'id': message.get('msgid') - }).c('body').t(body).up(); - - if (message.get('type') === 'chat') { - stanza.c('request', { - 'xmlns': omemo_utils_Strophe.NS.RECEIPTS - }).up(); - } // An encrypted header is added to the message for - // each device that is supposed to receive it. - // These headers simply contain the key that the - // payload message is encrypted with, - // and they are separately encrypted using the - // session corresponding to the counterpart device. - - - stanza.c('encrypted', { - 'xmlns': omemo_utils_Strophe.NS.OMEMO - }).c('header', { - 'sid': shared_converse.omemo_store.get('device_id') - }); - return omemo.encryptMessage(message.get('message')).then(obj => { - // The 16 bytes key and the GCM authentication tag (The tag - // SHOULD have at least 128 bit) are concatenated and for each - // intended recipient device, i.e. both own devices as well as - // devices associated with the contact, the result of this - // concatenation is encrypted using the corresponding - // long-standing SignalProtocol session. - const promises = devices.filter(device => device.get('trusted') != UNTRUSTED && device.get('active')).map(device => chatbox.encryptKey(obj.key_and_tag, device)); - return Promise.all(promises).then(dicts => addKeysToMessageStanza(stanza, dicts, obj.iv)).then(stanza => { - stanza.c('payload').t(obj.payload).up().up(); - stanza.c('store', { - 'xmlns': omemo_utils_Strophe.NS.HINTS - }).up(); - stanza.c('encryption', { - 'xmlns': omemo_utils_Strophe.NS.EME, - namespace: omemo_utils_Strophe.NS.OMEMO - }); - return stanza; - }); - }); -} -;// CONCATENATED MODULE: ./src/plugins/omemo/overrides/chatbox.js - - -const chatbox_ChatBox = { - async sendMessage(attrs) { - var _attrs; - - if (this.get('omemo_active') && (_attrs = attrs) !== null && _attrs !== void 0 && _attrs.body) { - var _attrs2; - - const plaintext = (_attrs2 = attrs) === null || _attrs2 === void 0 ? void 0 : _attrs2.body; - attrs = this.getOutgoingMessageAttributes(attrs); - attrs['is_encrypted'] = true; - attrs['plaintext'] = plaintext; - let message, stanza; - - try { - const devices = await getBundlesAndBuildSessions(this); - message = await this.createMessage(attrs); - stanza = await createOMEMOMessageStanza(this, message, devices); - } catch (e) { - this.handleMessageSendError(e); - return null; - } - - shared_converse.api.send(stanza); - - return message; - } else { - return this.__super__.sendMessage.apply(this, arguments); - } - } - -}; -/* harmony default export */ const chatbox = (chatbox_ChatBox); -;// CONCATENATED MODULE: ./src/plugins/omemo/mixins/converse.js - -const ConverseMixins = { - generateFingerprints: async function (jid) { - const devices = await getDevicesForContact(jid); - return Promise.all(devices.map(d => generateFingerprint(d))); - }, - getDeviceForContact: function (jid, device_id) { - return getDevicesForContact(jid).then(devices => devices.get(device_id)); - }, - contactHasOMEMOSupport: async function (jid) { - /* Checks whether the contact advertises any OMEMO-compatible devices. */ - const devices = await getDevicesForContact(jid); - return devices.length > 0; - } -}; -/* harmony default export */ const mixins_converse = (ConverseMixins); -;// CONCATENATED MODULE: ./src/plugins/omemo/errors.js -class IQError extends Error { - constructor(message, iq) { - super(message, iq); - this.name = 'IQError'; - this.iq = iq; - } - -} -;// CONCATENATED MODULE: ./src/plugins/omemo/device.js - - - - - - -const { - Strophe: device_Strophe, - sizzle: device_sizzle, - u: device_u, - $iq: device_$iq -} = core_converse.env; -/** - * @class - * @namespace _converse.Device - * @memberOf _converse - */ - -const Device = Model.extend({ - defaults: { - 'trusted': UNDECIDED, - 'active': true - }, - - getRandomPreKey() { - // XXX: assumes that the bundle has already been fetched - const bundle = this.get('bundle'); - return bundle.prekeys[device_u.getRandomInt(bundle.prekeys.length)]; - }, - - async fetchBundleFromServer() { - const stanza = device_$iq({ - 'type': 'get', - 'from': shared_converse.bare_jid, - 'to': this.get('jid') - }).c('pubsub', { - 'xmlns': device_Strophe.NS.PUBSUB - }).c('items', { - 'node': `${device_Strophe.NS.OMEMO_BUNDLES}:${this.get('id')}` - }); - let iq; - - try { - iq = await api.sendIQ(stanza); - } catch (iq) { - headless_log.error(`Could not fetch bundle for device ${this.get('id')} from ${this.get('jid')}`); - headless_log.error(iq); - return null; - } - - if (iq.querySelector('error')) { - throw new IQError('Could not fetch bundle', iq); - } - - const publish_el = device_sizzle(`items[node="${device_Strophe.NS.OMEMO_BUNDLES}:${this.get('id')}"]`, iq).pop(); - const bundle_el = device_sizzle(`bundle[xmlns="${device_Strophe.NS.OMEMO}"]`, publish_el).pop(); - const bundle = parseBundle(bundle_el); - this.save('bundle', bundle); - return bundle; - }, - - /** - * Fetch and save the bundle information associated with - * this device, if the information is not cached already. - * @method _converse.Device#getBundle - */ - getBundle() { - if (this.get('bundle')) { - return Promise.resolve(this.get('bundle'), this); - } else { - return this.fetchBundleFromServer(); - } - } - -}); -/* harmony default export */ const device = (Device); -;// CONCATENATED MODULE: ./src/plugins/omemo/devicelist.js - - - - - -const { - Strophe: devicelist_Strophe, - $build: devicelist_$build, - $iq: devicelist_$iq, - sizzle: devicelist_sizzle -} = core_converse.env; -/** - * @class - * @namespace _converse.DeviceList - * @memberOf _converse - */ - -const DeviceList = Model.extend({ - idAttribute: 'jid', - - initialize() { - this.initDevices(); - }, - - initDevices() { - this.devices = new shared_converse.Devices(); - const id = `converse.devicelist-${shared_converse.bare_jid}-${this.get('jid')}`; - initStorage(this.devices, id); - this.fetchDevices(); - }, - - async onDevicesFound(collection) { - if (collection.length === 0) { - let ids; - - try { - ids = await this.fetchDevicesFromServer(); - } catch (e) { - if (e === null) { - headless_log.error(`Timeout error while fetching devices for ${this.get('jid')}`); - } else { - headless_log.error(`Could not fetch devices for ${this.get('jid')}`); - headless_log.error(e); - } - - this.destroy(); - } - - if (this.get('jid') === shared_converse.bare_jid) { - await this.publishCurrentDevice(ids); - } - } - }, - - fetchDevices() { - if (this._devices_promise === undefined) { - this._devices_promise = new Promise(resolve => { - this.devices.fetch({ - 'success': c => resolve(this.onDevicesFound(c)), - 'error': (m, e) => { - headless_log.error(e); - resolve(); - } - }); - }); - } - - return this._devices_promise; - }, - - async getOwnDeviceId() { - let device_id = shared_converse.omemo_store.get('device_id'); - - if (!this.devices.findWhere({ - 'id': device_id - })) { - // Generate a new bundle if we cannot find our device - await shared_converse.omemo_store.generateBundle(); - device_id = shared_converse.omemo_store.get('device_id'); - } - - return device_id; - }, - - async publishCurrentDevice(device_ids) { - if (this.get('jid') !== shared_converse.bare_jid) { - return; // We only publish for ourselves. - } - - await restoreOMEMOSession(); - - if (!shared_converse.omemo_store) { - // Happens during tests. The connection gets torn down - // before publishCurrentDevice has time to finish. - headless_log.warn('publishCurrentDevice: omemo_store is not defined, likely a timing issue'); - return; - } - - if (!device_ids.includes(await this.getOwnDeviceId())) { - return this.publishDevices(); - } - }, - - async fetchDevicesFromServer() { - const stanza = devicelist_$iq({ - 'type': 'get', - 'from': shared_converse.bare_jid, - 'to': this.get('jid') - }).c('pubsub', { - 'xmlns': devicelist_Strophe.NS.PUBSUB - }).c('items', { - 'node': devicelist_Strophe.NS.OMEMO_DEVICELIST - }); - let iq; - - try { - iq = await api.sendIQ(stanza); - } catch (e) { - headless_log.error(e); - return []; - } - - const selector = `list[xmlns="${devicelist_Strophe.NS.OMEMO}"] device`; - const device_ids = devicelist_sizzle(selector, iq).map(d => d.getAttribute('id')); - await Promise.all(device_ids.map(id => this.devices.create({ - id, - 'jid': this.get('jid') - }, { - 'promise': true - }))); - return device_ids; - }, - - /** - * Send an IQ stanza to the current user's "devices" PEP node to - * ensure that all devices are published for potential chat partners to see. - * See: https://xmpp.org/extensions/xep-0384.html#usecases-announcing - */ - publishDevices() { - const item = devicelist_$build('item', { - 'id': 'current' - }).c('list', { - 'xmlns': devicelist_Strophe.NS.OMEMO - }); - this.devices.filter(d => d.get('active')).forEach(d => item.c('device', { - 'id': d.get('id') - }).up()); - const options = { - 'pubsub#access_model': 'open' - }; - return api.pubsub.publish(null, devicelist_Strophe.NS.OMEMO_DEVICELIST, item, options, false); - }, - - removeOwnDevices(device_ids) { - if (this.get('jid') !== shared_converse.bare_jid) { - throw new Error("Cannot remove devices from someone else's device list"); - } - - device_ids.forEach(device_id => this.devices.get(device_id).destroy()); - return this.publishDevices(); - } - -}); -/* harmony default export */ const devicelist = (DeviceList); -;// CONCATENATED MODULE: ./src/plugins/omemo/devicelists.js - - -/** - * @class - * @namespace _converse.DeviceLists - * @memberOf _converse - */ - -const DeviceLists = Collection.extend({ - model: devicelist, - - /** - * Returns the {@link _converse.DeviceList} for a particular JID. - * The device list will be created if it doesn't exist already. - * @private - * @method _converse.DeviceLists#getDeviceList - * @param { String } jid - The Jabber ID for which the device list will be returned. - */ - getDeviceList(jid) { - return this.get(jid) || this.create({ - 'jid': jid - }); - } - -}); -/* harmony default export */ const devicelists = (DeviceLists); -;// CONCATENATED MODULE: ./src/plugins/omemo/devices.js - - -/* harmony default export */ const devices = (Collection.extend({ - model: device -})); -;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeCeil = Math.ceil, - _baseRange_nativeMax = Math.max; -/** - * The base implementation of `_.range` and `_.rangeRight` which doesn't - * coerce arguments. - * - * @private - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @param {number} step The value to increment or decrement by. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the range of numbers. - */ - -function baseRange(start, end, step, fromRight) { - var index = -1, - length = _baseRange_nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); - - while (length--) { - result[fromRight ? length : ++index] = start; - start += step; - } - - return result; -} - -/* harmony default export */ const _baseRange = (baseRange); -;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js - - - -/** - * Creates a `_.range` or `_.rangeRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new range function. - */ - -function createRange(fromRight) { - return function (start, end, step) { - if (step && typeof step != 'number' && _isIterateeCall(start, end, step)) { - end = step = undefined; - } // Ensure the sign of `-0` is preserved. - - - start = lodash_es_toFinite(start); - - if (end === undefined) { - end = start; - start = 0; - } else { - end = lodash_es_toFinite(end); - } - - step = step === undefined ? start < end ? 1 : -1 : lodash_es_toFinite(step); - return _baseRange(start, end, step, fromRight); - }; -} - -/* harmony default export */ const _createRange = (createRange); -;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js - -/** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to, but not including, `end`. A step of `-1` is used if a negative - * `start` is specified without an `end` or `step`. If `end` is not specified, - * it's set to `start` with `start` then set to `0`. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns the range of numbers. - * @see _.inRange, _.rangeRight - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(-4); - * // => [0, -1, -2, -3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - -var range = _createRange(); -/* harmony default export */ const lodash_es_range = (range); -;// CONCATENATED MODULE: ./src/plugins/omemo/store.js -/* global libsignal */ - - - - - - - - -const { - Strophe: store_Strophe, - $build: store_$build, - u: store_u -} = core_converse.env; -const OMEMOStore = Model.extend({ - Direction: { - SENDING: 1, - RECEIVING: 2 - }, - - getIdentityKeyPair() { - const keypair = this.get('identity_keypair'); - return Promise.resolve({ - 'privKey': store_u.base64ToArrayBuffer(keypair.privKey), - 'pubKey': store_u.base64ToArrayBuffer(keypair.pubKey) - }); - }, - - getLocalRegistrationId() { - return Promise.resolve(parseInt(this.get('device_id'), 10)); - }, - - isTrustedIdentity(identifier, identity_key, direction) { - // eslint-disable-line no-unused-vars - if (identifier === null || identifier === undefined) { - throw new Error("Can't check identity key for invalid key"); - } - - if (!(identity_key instanceof ArrayBuffer)) { - throw new Error('Expected identity_key to be an ArrayBuffer'); - } - - const trusted = this.get('identity_key' + identifier); - - if (trusted === undefined) { - return Promise.resolve(true); - } - - return Promise.resolve(store_u.arrayBufferToBase64(identity_key) === trusted); - }, - - loadIdentityKey(identifier) { - if (identifier === null || identifier === undefined) { - throw new Error("Can't load identity_key for invalid identifier"); - } - - return Promise.resolve(store_u.base64ToArrayBuffer(this.get('identity_key' + identifier))); - }, - - saveIdentity(identifier, identity_key) { - if (identifier === null || identifier === undefined) { - throw new Error("Can't save identity_key for invalid identifier"); - } - - const address = new libsignal.SignalProtocolAddress.fromString(identifier); - const existing = this.get('identity_key' + address.getName()); - const b64_idkey = store_u.arrayBufferToBase64(identity_key); - this.save('identity_key' + address.getName(), b64_idkey); - - if (existing && b64_idkey !== existing) { - return Promise.resolve(true); - } else { - return Promise.resolve(false); - } - }, - - getPreKeys() { - return this.get('prekeys') || {}; - }, - - loadPreKey(key_id) { - const res = this.getPreKeys()[key_id]; - - if (res) { - return Promise.resolve({ - 'privKey': store_u.base64ToArrayBuffer(res.privKey), - 'pubKey': store_u.base64ToArrayBuffer(res.pubKey) - }); - } - - return Promise.resolve(); - }, - - storePreKey(key_id, key_pair) { - const prekey = {}; - prekey[key_id] = { - 'pubKey': store_u.arrayBufferToBase64(key_pair.pubKey), - 'privKey': store_u.arrayBufferToBase64(key_pair.privKey) - }; - this.save('prekeys', Object.assign(this.getPreKeys(), prekey)); - return Promise.resolve(); - }, - - removePreKey(key_id) { - this.save('prekeys', lodash_es_omit(this.getPreKeys(), key_id)); - return Promise.resolve(); - }, - - loadSignedPreKey(keyId) { - // eslint-disable-line no-unused-vars - const res = this.get('signed_prekey'); - - if (res) { - return Promise.resolve({ - 'privKey': store_u.base64ToArrayBuffer(res.privKey), - 'pubKey': store_u.base64ToArrayBuffer(res.pubKey) - }); - } - - return Promise.resolve(); - }, - - storeSignedPreKey(spk) { - if (typeof spk !== 'object') { - // XXX: We've changed the signature of this method from the - // example given in InMemorySignalProtocolStore. - // Should be fine because the libsignal code doesn't - // actually call this method. - throw new Error('storeSignedPreKey: expected an object'); - } - - this.save('signed_prekey', { - 'id': spk.keyId, - 'privKey': store_u.arrayBufferToBase64(spk.keyPair.privKey), - 'pubKey': store_u.arrayBufferToBase64(spk.keyPair.pubKey), - // XXX: The InMemorySignalProtocolStore does not pass - // in or store the signature, but we need it when we - // publish out bundle and this method isn't called from - // within libsignal code, so we modify it to also store - // the signature. - 'signature': store_u.arrayBufferToBase64(spk.signature) - }); - return Promise.resolve(); - }, - - removeSignedPreKey(key_id) { - if (this.get('signed_prekey')['id'] === key_id) { - this.unset('signed_prekey'); - this.save(); - } - - return Promise.resolve(); - }, - - loadSession(identifier) { - return Promise.resolve(this.get('session' + identifier)); - }, - - storeSession(identifier, record) { - return Promise.resolve(this.save('session' + identifier, record)); - }, - - removeSession(identifier) { - return Promise.resolve(this.unset('session' + identifier)); - }, - - removeAllSessions(identifier) { - const keys = Object.keys(this.attributes).filter(key => key.startsWith('session' + identifier) ? key : false); - const attrs = {}; - keys.forEach(key => { - attrs[key] = undefined; - }); - this.save(attrs); - return Promise.resolve(); - }, - - publishBundle() { - const signed_prekey = this.get('signed_prekey'); - const node = `${store_Strophe.NS.OMEMO_BUNDLES}:${this.get('device_id')}`; - const item = store_$build('item').c('bundle', { - 'xmlns': store_Strophe.NS.OMEMO - }).c('signedPreKeyPublic', { - 'signedPreKeyId': signed_prekey.id - }).t(signed_prekey.pubKey).up().c('signedPreKeySignature').t(signed_prekey.signature).up().c('identityKey').t(this.get('identity_keypair').pubKey).up().c('prekeys'); - Object.values(this.get('prekeys')).forEach((prekey, id) => item.c('preKeyPublic', { - 'preKeyId': id - }).t(prekey.pubKey).up()); - const options = { - 'pubsub#access_model': 'open' - }; - return api.pubsub.publish(null, node, item, options, false); - }, - - async generateMissingPreKeys() { - const missing_keys = lodash_es_difference(lodash_es_invokeMap(lodash_es_range(0, shared_converse.NUM_PREKEYS), Number.prototype.toString), Object.keys(this.getPreKeys())); - - if (missing_keys.length < 1) { - headless_log.warn('No missing prekeys to generate for our own device'); - return Promise.resolve(); - } - - const keys = await Promise.all(missing_keys.map(id => libsignal.KeyHelper.generatePreKey(parseInt(id, 10)))); - keys.forEach(k => this.storePreKey(k.keyId, k.keyPair)); - const marshalled_keys = Object.keys(this.getPreKeys()).map(k => ({ - 'id': k.keyId, - 'key': store_u.arrayBufferToBase64(k.pubKey) - })); - - const devicelist = shared_converse.devicelists.get(shared_converse.bare_jid); - - const device = devicelist.devices.get(this.get('device_id')); - const bundle = await device.getBundle(); - device.save('bundle', Object.assign(bundle, { - 'prekeys': marshalled_keys - })); - }, - - /** - * Generate a the data used by the X3DH key agreement protocol - * that can be used to build a session with a device. - */ - async generateBundle() { - // The first thing that needs to happen if a client wants to - // start using OMEMO is they need to generate an IdentityKey - // and a Device ID. The IdentityKey is a Curve25519 [6] - // public/private Key pair. The Device ID is a randomly - // generated integer between 1 and 2^31 - 1. - const identity_keypair = await libsignal.KeyHelper.generateIdentityKeyPair(); - const bundle = {}; - const identity_key = store_u.arrayBufferToBase64(identity_keypair.pubKey); - const device_id = generateDeviceID(); - bundle['identity_key'] = identity_key; - bundle['device_id'] = device_id; - this.save({ - 'device_id': device_id, - 'identity_keypair': { - 'privKey': store_u.arrayBufferToBase64(identity_keypair.privKey), - 'pubKey': identity_key - }, - 'identity_key': identity_key - }); - const signed_prekey = await libsignal.KeyHelper.generateSignedPreKey(identity_keypair, 0); - - shared_converse.omemo_store.storeSignedPreKey(signed_prekey); - - bundle['signed_prekey'] = { - 'id': signed_prekey.keyId, - 'public_key': store_u.arrayBufferToBase64(signed_prekey.keyPair.pubKey), - 'signature': store_u.arrayBufferToBase64(signed_prekey.signature) - }; - const keys = await Promise.all(lodash_es_range(0, shared_converse.NUM_PREKEYS).map(id => libsignal.KeyHelper.generatePreKey(id))); - keys.forEach(k => shared_converse.omemo_store.storePreKey(k.keyId, k.keyPair)); - - const devicelist = shared_converse.devicelists.get(shared_converse.bare_jid); - - const device = await devicelist.devices.create({ - 'id': bundle.device_id, - 'jid': shared_converse.bare_jid - }, { - 'promise': true - }); - const marshalled_keys = keys.map(k => ({ - 'id': k.keyId, - 'key': store_u.arrayBufferToBase64(k.keyPair.pubKey) - })); - bundle['prekeys'] = marshalled_keys; - device.save('bundle', bundle); - }, - - fetchSession() { - if (this._setup_promise === undefined) { - this._setup_promise = new Promise((resolve, reject) => { - this.fetch({ - 'success': () => { - if (!shared_converse.omemo_store.get('device_id')) { - this.generateBundle().then(resolve).catch(reject); - } else { - resolve(); - } - }, - 'error': (model, resp) => { - headless_log.warn("Could not fetch OMEMO session from cache, we'll generate a new one."); - headless_log.warn(resp); - this.generateBundle().then(resolve).catch(reject); - } - }); - }); - } - - return this._setup_promise; - } - -}); -/* harmony default export */ const store = (OMEMOStore); -;// CONCATENATED MODULE: ./src/plugins/omemo/overrides/profile-modal.js - - - - -const { - Strophe: profile_modal_Strophe, - sizzle: profile_modal_sizzle, - u: profile_modal_u -} = core_converse.env; -const profile_modal_ProfileModal = { - events: { - 'change input.select-all': 'selectAll', - 'click .generate-bundle': 'generateOMEMODeviceBundle', - 'submit .fingerprint-removal': 'removeSelectedFingerprints' - }, - - initialize() { - this.debouncedRender = lodash_es_debounce(this.render, 50); - this.devicelist = shared_converse.devicelists.get(shared_converse.bare_jid); - this.listenTo(this.devicelist.devices, 'change:bundle', this.debouncedRender); - this.listenTo(this.devicelist.devices, 'reset', this.debouncedRender); - this.listenTo(this.devicelist.devices, 'reset', this.debouncedRender); - this.listenTo(this.devicelist.devices, 'remove', this.debouncedRender); - this.listenTo(this.devicelist.devices, 'add', this.debouncedRender); - return this.__super__.initialize.apply(this, arguments); - }, - - beforeRender() { - var _converse$omemo_store, _this$__super__$befor; - - const device_id = (_converse$omemo_store = shared_converse.omemo_store) === null || _converse$omemo_store === void 0 ? void 0 : _converse$omemo_store.get('device_id'); - - if (device_id) { - this.current_device = this.devicelist.devices.get(device_id); - this.other_devices = this.devicelist.devices.filter(d => d.get('id') !== device_id); - } - - return (_this$__super__$befor = this.__super__.beforeRender) === null || _this$__super__$befor === void 0 ? void 0 : _this$__super__$befor.apply(this, arguments); - }, - - selectAll(ev) { - let sibling = profile_modal_u.ancestor(ev.target, 'li'); - - while (sibling) { - sibling.querySelector('input[type="checkbox"]').checked = ev.target.checked; - sibling = sibling.nextElementSibling; - } - }, - - removeSelectedFingerprints(ev) { - ev.preventDefault(); - ev.stopPropagation(); - ev.target.querySelector('.select-all').checked = false; - const device_ids = profile_modal_sizzle('.fingerprint-removal-item input[type="checkbox"]:checked', ev.target).map(c => c.value); - this.devicelist.removeOwnDevices(device_ids).then(this.modal.hide).catch(err => { - headless_log.error(err); - - shared_converse.api.alert(profile_modal_Strophe.LogLevel.ERROR, __('Error'), [__('Sorry, an error occurred while trying to remove the devices.')]); - }); - }, - - generateOMEMODeviceBundle(ev) { - ev.preventDefault(); - - if (confirm(__('Are you sure you want to generate new OMEMO keys? ' + 'This will remove your old keys and all previously encrypted messages will no longer be decryptable on this device.'))) { - api.omemo.bundle.generate(); - } - } - -}; -/* harmony default export */ const profile_modal = (profile_modal_ProfileModal); -;// CONCATENATED MODULE: ./src/plugins/omemo/overrides/user-details-modal.js - -const user_details_modal_UserDetailsModal = { - events: { - 'click .fingerprint-trust .btn input': 'toggleDeviceTrust' - }, - - initialize() { - const jid = this.model.get('jid'); - this.devicelist = shared_converse.devicelists.getDeviceList(jid); - this.listenTo(this.devicelist.devices, 'change:bundle', this.render); - this.listenTo(this.devicelist.devices, 'change:trusted', this.render); - this.listenTo(this.devicelist.devices, 'remove', this.render); - this.listenTo(this.devicelist.devices, 'add', this.render); - this.listenTo(this.devicelist.devices, 'reset', this.render); - return this.__super__.initialize.apply(this, arguments); - }, - - toggleDeviceTrust(ev) { - const radio = ev.target; - const device = this.devicelist.devices.get(radio.getAttribute('name')); - device.save('trusted', parseInt(radio.value, 10)); - } - -}; -/* harmony default export */ const user_details_modal = (user_details_modal_UserDetailsModal); -;// CONCATENATED MODULE: ./src/plugins/omemo/api.js - - -/* harmony default export */ const omemo_api = ({ - /** - * The "omemo" namespace groups methods relevant to OMEMO - * encryption. - * - * @namespace _converse.api.omemo - * @memberOf _converse.api - */ - 'omemo': { - /** - * The "bundle" namespace groups methods relevant to the user's - * OMEMO bundle. - * - * @namespace _converse.api.omemo.bundle - * @memberOf _converse.api.omemo - */ - 'bundle': { - /** - * Lets you generate a new OMEMO device bundle - * - * @method _converse.api.omemo.bundle.generate - * @returns {promise} Promise which resolves once we have a result from the server. - */ - 'generate': async () => { - // Remove current device - const devicelist = shared_converse.devicelists.get(shared_converse.bare_jid); - - const device_id = shared_converse.omemo_store.get('device_id'); - - if (device_id) { - const device = devicelist.devices.get(device_id); - - shared_converse.omemo_store.unset(device_id); - - if (device) { - await new Promise(done => device.destroy({ - 'success': done, - 'error': done - })); - } - - devicelist.devices.trigger('remove'); - } // Generate new device bundle and publish - // https://xmpp.org/extensions/attic/xep-0384-0.3.0.html#usecases-announcing - - - await shared_converse.omemo_store.generateBundle(); - await devicelist.publishDevices(); - const device = devicelist.devices.get(shared_converse.omemo_store.get('device_id')); - const fp = generateFingerprint(device); - await shared_converse.omemo_store.publishBundle(); - return fp; - } - } - } -}); -;// CONCATENATED MODULE: ./src/plugins/omemo/mixins/chatbox.js - - - - -const { - Strophe: chatbox_Strophe, - sizzle: chatbox_sizzle -} = core_converse.env; -/** - * Mixin object that contains OMEMO-related methods for - * {@link _converse.ChatBox} or {@link _converse.ChatRoom} objects. - * - * @typedef {Object} OMEMOEnabledChatBox - */ - -const OMEMOEnabledChatBox = { - encryptKey(plaintext, device) { - return getSessionCipher(device.get('jid'), device.get('id')).encrypt(plaintext).then(payload => ({ - 'payload': payload, - 'device': device - })); - }, - - handleMessageSendError(e) { - if (e.name === 'IQError') { - this.save('omemo_supported', false); - const err_msgs = []; - - if (chatbox_sizzle(`presence-subscription-required[xmlns="${chatbox_Strophe.NS.PUBSUB_ERROR}"]`, e.iq).length) { - err_msgs.push(__("Sorry, we're unable to send an encrypted message because %1$s " + 'requires you to be subscribed to their presence in order to see their OMEMO information', e.iq.getAttribute('from'))); - } else if (chatbox_sizzle(`remote-server-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]`, e.iq).length) { - err_msgs.push(__("Sorry, we're unable to send an encrypted message because the remote server for %1$s could not be found", e.iq.getAttribute('from'))); - } else { - err_msgs.push(__('Unable to send an encrypted message due to an unexpected error.')); - err_msgs.push(e.iq.outerHTML); - } - - api.alert('error', __('Error'), err_msgs); - headless_log.error(e); - } else if (e.user_facing) { - api.alert('error', __('Error'), [e.message]); - headless_log.error(e); - } else { - throw e; - } - } - -}; -;// CONCATENATED MODULE: ./src/plugins/omemo/index.js -/** - * @module converse-omemo - * @copyright The Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - - - - - - - - - - -const { - Strophe: omemo_Strophe -} = core_converse.env; -core_converse.env.omemo = omemo; -omemo_Strophe.addNamespace('OMEMO_DEVICELIST', omemo_Strophe.NS.OMEMO + '.devicelist'); -omemo_Strophe.addNamespace('OMEMO_VERIFICATION', omemo_Strophe.NS.OMEMO + '.verification'); -omemo_Strophe.addNamespace('OMEMO_WHITELISTED', omemo_Strophe.NS.OMEMO + '.whitelisted'); -omemo_Strophe.addNamespace('OMEMO_BUNDLES', omemo_Strophe.NS.OMEMO + '.bundles'); -core_converse.plugins.add('converse-omemo', { - enabled(_converse) { - return window.libsignal && _converse.config.get('trusted') && !api.settings.get('clear_cache_on_logout') && !_converse.api.settings.get('blacklisted_plugins').includes('converse-omemo'); - }, - - dependencies: ['converse-chatview', 'converse-pubsub', 'converse-profile'], - overrides: { - ProfileModal: profile_modal, - UserDetailsModal: user_details_modal, - ChatBox: chatbox - }, - - initialize() { - api.settings.extend({ - 'omemo_default': false - }); - api.promises.add(['OMEMOInitialized']); - shared_converse.NUM_PREKEYS = 100; // Set here so that tests can override - - Object.assign(shared_converse.ChatBox.prototype, OMEMOEnabledChatBox); - Object.assign(shared_converse, mixins_converse); - Object.assign(shared_converse.api, omemo_api); - shared_converse.OMEMOStore = store; - shared_converse.Device = device; - shared_converse.Devices = devices; - shared_converse.DeviceList = devicelist; - shared_converse.DeviceLists = devicelists; - /******************** Event Handlers ********************/ - - api.waitUntil('chatBoxesInitialized').then(utils_onChatBoxesInitialized); - api.listen.on('afterFileUploaded', (msg, attrs) => msg.file.xep454_ivkey ? setEncryptedFileURL(msg, attrs) : attrs); - api.listen.on('beforeFileUpload', (chat, file) => chat.get('omemo_active') ? encryptFile(file) : file); - api.listen.on('parseMessage', parseEncryptedMessage); - api.listen.on('parseMUCMessage', parseEncryptedMessage); - api.listen.on('chatBoxViewInitialized', onChatInitialized); - api.listen.on('chatRoomViewInitialized', onChatInitialized); - api.listen.on('connected', registerPEPPushHandler); - api.listen.on('getToolbarButtons', getOMEMOToolbarButton); - api.listen.on('statusInitialized', initOMEMO); - api.listen.on('addClientFeatures', () => api.disco.own.features.add(`${omemo_Strophe.NS.OMEMO_DEVICELIST}+notify`)); - api.listen.on('afterMessageBodyTransformed', handleEncryptedFiles); - api.listen.on('userDetailsModalInitialized', contact => { - const jid = contact.get('jid'); - - shared_converse.generateFingerprints(jid).catch(e => headless_log.error(e)); - }); - api.listen.on('profileModalInitialized', () => { - shared_converse.generateFingerprints(shared_converse.bare_jid).catch(e => headless_log.error(e)); - }); - api.listen.on('afterTearDown', () => delete shared_converse.omemo_store); - api.listen.on('clearSession', () => { - if (shared_converse.shouldClearCache() && shared_converse.devicelists) { - shared_converse.devicelists.clearStore(); - - delete shared_converse.devicelists; - } - }); - } - -}); -;// CONCATENATED MODULE: ./src/plugins/push/utils.js - - -const { - Strophe: push_utils_Strophe, - $iq: push_utils_$iq -} = core_converse.env; - -async function disablePushAppServer(domain, push_app_server) { - if (!push_app_server.jid) { - return; - } - - if (!(await api.disco.supports(push_utils_Strophe.NS.PUSH, domain || shared_converse.bare_jid))) { - headless_log.warn(`Not disabling push app server "${push_app_server.jid}", no disco support from your server.`); - return; - } - - const stanza = push_utils_$iq({ - 'type': 'set' - }); - - if (domain !== shared_converse.bare_jid) { - stanza.attrs({ - 'to': domain - }); - } - - stanza.c('disable', { - 'xmlns': push_utils_Strophe.NS.PUSH, - 'jid': push_app_server.jid - }); - - if (push_app_server.node) { - stanza.attrs({ - 'node': push_app_server.node - }); - } - - api.sendIQ(stanza).catch(e => { - headless_log.error(`Could not disable push app server for ${push_app_server.jid}`); - headless_log.error(e); - }); -} - -async function enablePushAppServer(domain, push_app_server) { - if (!push_app_server.jid || !push_app_server.node) { - return; - } - - const identity = await api.disco.getIdentity('pubsub', 'push', push_app_server.jid); - - if (!identity) { - return headless_log.warn(`Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.`); - } - - const result = await Promise.all([api.disco.supports(push_utils_Strophe.NS.PUSH, push_app_server.jid), api.disco.supports(push_utils_Strophe.NS.PUSH, domain)]); - - if (!result[0] && !result[1]) { - headless_log.warn(`Not enabling push app server "${push_app_server.jid}", no disco support from your server.`); - return; - } - - const stanza = push_utils_$iq({ - 'type': 'set' - }); - - if (domain !== shared_converse.bare_jid) { - stanza.attrs({ - 'to': domain - }); - } - - stanza.c('enable', { - 'xmlns': push_utils_Strophe.NS.PUSH, - 'jid': push_app_server.jid, - 'node': push_app_server.node - }); - - if (push_app_server.secret) { - stanza.c('x', { - 'xmlns': push_utils_Strophe.NS.XFORM, - 'type': 'submit' - }).c('field', { - 'var': 'FORM_TYPE' - }).c('value').t(`${push_utils_Strophe.NS.PUBSUB}#publish-options`).up().up().c('field', { - 'var': 'secret' - }).c('value').t(push_app_server.secret); - } - - return api.sendIQ(stanza); -} - -async function enablePush(domain) { - domain = domain || shared_converse.bare_jid; - const push_enabled = shared_converse.session.get('push_enabled') || []; - - if (push_enabled.includes(domain)) { - return; - } - - const enabled_services = api.settings.get('push_app_servers').filter(s => !s.disable); - const disabled_services = api.settings.get('push_app_servers').filter(s => s.disable); - const enabled = enabled_services.map(s => enablePushAppServer(domain, s)); - const disabled = disabled_services.map(s => disablePushAppServer(domain, s)); - - try { - await Promise.all(enabled.concat(disabled)); - } catch (e) { - headless_log.error('Could not enable or disable push App Server'); - if (e) headless_log.error(e); - } finally { - push_enabled.push(domain); - } - - shared_converse.session.save('push_enabled', push_enabled); -} -function onChatBoxAdded(model) { - if (model.get('type') == shared_converse.CHATROOMS_TYPE) { - enablePush(push_utils_Strophe.getDomainFromJid(model.get('jid'))); - } -} -;// CONCATENATED MODULE: ./src/plugins/push/index.js -/** - * @description - * Converse.js plugin which add support for registering - * an "App Server" as defined in XEP-0357 - * @copyright 2021, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - -const { - Strophe: push_Strophe -} = core_converse.env; -push_Strophe.addNamespace('PUSH', 'urn:xmpp:push:0'); -core_converse.plugins.add('converse-push', { - initialize() { - /* The initialize function gets called as soon as the plugin is - * loaded by converse.js's plugin machinery. - */ - api.settings.extend({ - 'push_app_servers': [], - 'enable_muc_push': false - }); - api.listen.on('statusInitialized', () => enablePush()); - - if (api.settings.get('enable_muc_push')) { - api.listen.on('chatBoxesInitialized', () => shared_converse.chatboxes.on('add', onChatBoxAdded)); - } - } - -}); -;// CONCATENATED MODULE: ./src/plugins/register/templates/registration_form.js - - - -/* harmony default export */ const registration_form = (o => { - const i18n_choose_provider = __('Choose a different provider'); - - const i18n_has_account = __('Already have a chat account?'); - - const i18n_legend = __('Account Registration:'); - - const i18n_login = __('Log in here'); - - const i18n_register = __('Register'); - - const registration_domain = api.settings.get('registration_domain'); - return T` -
    - ${i18n_legend} ${o.domain} -

    ${o.title}

    -

    ${o.instructions}

    - - ${o.form_fields} - -
    - ${o.fields ? T` - - ` : ''} - ${registration_domain ? '' : T` - - `} -
    -

    ${i18n_has_account}

    -

    -
    -
    -
    - `; -}); -;// CONCATENATED MODULE: ./src/plugins/register/templates/register_panel.js - - - - - - -const tpl_form_request = () => { - const default_domain = api.settings.get('registration_domain'); - - const i18n_fetch_form = __("Hold tight, we're fetching the registration form…"); - - const i18n_cancel = __('Cancel'); - - return T` -
    - ${spinner({ - 'classes': 'hor_centered' - })} -

    ${i18n_fetch_form}

    - ${default_domain ? '' : T` - - `} -
    - `; -}; - -const tpl_domain_input = () => { - const domain_placeholder = api.settings.get('domain_placeholder'); - - const i18n_providers = __('Tip: A list of public XMPP providers is available'); - - const i18n_providers_link = __('here'); - - const href_providers = api.settings.get('providers_link'); - return T` - -

    - ${i18n_providers} - ${i18n_providers_link}. -

    - `; -}; - -const tpl_fetch_form_buttons = () => { - const i18n_register = __('Fetch registration form'); - - const i18n_existing_account = __('Already have a chat account?'); - - const i18n_login = __('Log in here'); - - return T` -
    - -
    -
    -

    ${i18n_existing_account}

    -

    -
    - `; -}; - -const tpl_choose_provider = () => { - const default_domain = api.settings.get('registration_domain'); - - const i18n_create_account = __('Create your account'); - - const i18n_choose_provider = __('Please enter the XMPP provider to register with:'); - - return T` -
    - ${i18n_create_account} -
    - - - ${default_domain ? default_domain : tpl_domain_input()} -
    - ${default_domain ? '' : tpl_fetch_form_buttons()} -
    - `; -}; - -const CHOOSE_PROVIDER = 0; -const FETCHING_FORM = 1; -const REGISTRATION_FORM = 2; -/* harmony default export */ const register_panel = (o => { - return T` - - ${o.model.get('registration_status') === CHOOSE_PROVIDER ? tpl_choose_provider() : ''} - ${o.model.get('registration_status') === FETCHING_FORM ? tpl_form_request(o) : ''} - ${o.model.get('registration_status') === REGISTRATION_FORM ? registration_form(o) : ''} - `; -}); -;// CONCATENATED MODULE: ./src/plugins/register/panel.js -function register_panel_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - - - - - - - - - - - - - // Strophe methods for building stanzas - -const { - Strophe: panel_Strophe, - sizzle: panel_sizzle, - $iq: panel_$iq -} = core_converse.env; -const panel_u = core_converse.env.utils; -const panel_CHOOSE_PROVIDER = 0; -const panel_FETCHING_FORM = 1; -const panel_REGISTRATION_FORM = 2; -/** - * @class - * @namespace _converse.RegisterPanel - * @memberOf _converse - */ - -class RegisterPanel extends ElementView { - constructor(...args) { - super(...args); - - register_panel_defineProperty(this, "id", "converse-register-panel"); - - register_panel_defineProperty(this, "className", 'controlbox-pane fade-in'); - - register_panel_defineProperty(this, "events", { - 'submit form#converse-register': 'onFormSubmission', - 'click .button-cancel': 'renderProviderChoiceForm' - }); - } - - initialize() { - this.reset(); - - const controlbox = shared_converse.chatboxes.get('controlbox'); - - this.model = controlbox; - this.listenTo(shared_converse, 'connectionInitialized', this.registerHooks); - this.listenTo(this.model, 'change:registration_status', this.render); - const domain = api.settings.get('registration_domain'); - - if (domain) { - this.fetchRegistrationForm(domain); - } else { - this.model.set('registration_status', panel_CHOOSE_PROVIDER); - } - } - - render() { - V(register_panel({ - 'domain': this.domain, - 'fields': this.fields, - 'form_fields': this.form_fields, - 'instructions': this.instructions, - 'model': this.model, - 'title': this.title - }), this); - } - /** - * Hook into Strophe's _connect_cb, so that we can send an IQ - * requesting the registration fields. - */ - - - registerHooks() { - const conn = shared_converse.connection; - - const connect_cb = conn._connect_cb.bind(conn); - - conn._connect_cb = (req, callback, raw) => { - if (!this._registering) { - connect_cb(req, callback, raw); - } else { - if (this.getRegistrationFields(req, callback)) { - this._registering = false; - } - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.render(); - } - /** - * Send an IQ stanza to the XMPP server asking for the registration fields. - * @private - * @method _converse.RegisterPanel#getRegistrationFields - * @param { Strophe.Request } req - The current request - * @param { Function } callback - The callback function - */ - - - getRegistrationFields(req, _callback) { - const conn = shared_converse.connection; - conn.connected = true; - - const body = conn._proto._reqToData(req); - - if (!body) { - return; - } - - if (conn._proto._connect_cb(body) === panel_Strophe.Status.CONNFAIL) { - this.showValidationError(__("Sorry, we're unable to connect to your chosen provider.")); - return false; - } - - const register = body.getElementsByTagName("register"); - const mechanisms = body.getElementsByTagName("mechanism"); - - if (register.length === 0 && mechanisms.length === 0) { - conn._proto._no_auth_received(_callback); - - return false; - } - - if (register.length === 0) { - conn._changeConnectStatus(panel_Strophe.Status.REGIFAIL); - - this.showValidationError(__("Sorry, the given provider does not support in " + "band account registration. Please try with a " + "different provider.")); - return true; - } // Send an IQ stanza to get all required data fields - - - conn._addSysHandler(this.onRegistrationFields.bind(this), null, "iq", null, null); - - const stanza = panel_$iq({ - type: "get" - }).c("query", { - xmlns: panel_Strophe.NS.REGISTER - }).tree(); - stanza.setAttribute("id", conn.getUniqueId("sendIQ")); - conn.send(stanza); - conn.connected = false; - return true; - } - /** - * Handler for {@link _converse.RegisterPanel#getRegistrationFields} - * @private - * @method _converse.RegisterPanel#onRegistrationFields - * @param { XMLElement } stanza - The query stanza. - */ - - - onRegistrationFields(stanza) { - if (stanza.getAttribute("type") === "error") { - shared_converse.connection._changeConnectStatus(panel_Strophe.Status.REGIFAIL, __('Something went wrong while establishing a connection with "%1$s". ' + 'Are you sure it exists?', this.domain)); - - return false; - } - - if (stanza.getElementsByTagName("query").length !== 1) { - shared_converse.connection._changeConnectStatus(panel_Strophe.Status.REGIFAIL, "unknown"); - - return false; - } - - this.setFields(stanza); - - if (this.model.get('registration_status') === panel_FETCHING_FORM) { - this.renderRegistrationForm(stanza); - } - - return false; - } - - reset(settings) { - const defaults = { - fields: {}, - urls: [], - title: "", - instructions: "", - registered: false, - _registering: false, - domain: null, - form_type: null - }; - Object.assign(this, defaults); - - if (settings) { - Object.assign(this, lodash_es_pick(settings, Object.keys(defaults))); - } - } - /** - * Event handler when the #converse-register form is submitted. - * Depending on the available input fields, we delegate to other methods. - * @private - * @param { Event } ev - */ - - - onFormSubmission(ev) { - if (ev && ev.preventDefault) { - ev.preventDefault(); - } - - if (ev.target.querySelector('input[name=domain]') === null) { - this.submitRegistrationForm(ev.target); - } else { - this.onProviderChosen(ev.target); - } - } - /** - * Callback method that gets called when the user has chosen an XMPP provider - * @private - * @method _converse.RegisterPanel#onProviderChosen - * @param { HTMLElement } form - The form that was submitted - */ - - - onProviderChosen(form) { - const domain_input = form.querySelector('input[name=domain]'), - domain = domain_input === null || domain_input === void 0 ? void 0 : domain_input.value; - - if (!domain) { - // TODO: add validation message - domain_input.classList.add('error'); - return; - } - - form.querySelector('input[type=submit]').classList.add('hidden'); - this.fetchRegistrationForm(domain.trim()); - } - /** - * Fetch a registration form from the requested domain - * @private - * @method _converse.RegisterPanel#fetchRegistrationForm - * @param { String } domain_name - XMPP server domain - */ - - - async fetchRegistrationForm(domain_name) { - var _converse$connection; - - this.model.set('registration_status', panel_FETCHING_FORM); - this.reset({ - 'domain': panel_Strophe.getDomainFromJid(domain_name), - '_registering': true - }); - await shared_converse.initConnection(this.domain); // When testing, the test tears down before the async function - // above finishes. So we use optional chaining here - - (_converse$connection = shared_converse.connection) === null || _converse$connection === void 0 ? void 0 : _converse$connection.connect(this.domain, "", status => this.onConnectStatusChanged(status)); - return false; - } - - giveFeedback(message, klass) { - let feedback = this.querySelector('.reg-feedback'); - - if (feedback !== null) { - feedback.parentNode.removeChild(feedback); - } - - const form = this.querySelector('form'); - form.insertAdjacentHTML('afterbegin', ''); - feedback = form.querySelector('.reg-feedback'); - feedback.textContent = message; - - if (klass) { - feedback.classList.add(klass); - } - } - - showSpinner() { - const form = this.querySelector('form'); - V(spinner(), form); - return this; - } - /** - * Callback function called by Strophe whenever the connection status changes. - * Passed to Strophe specifically during a registration attempt. - * @private - * @method _converse.RegisterPanel#onConnectStatusChanged - * @param { integer } status_code - The Strophe.Status status code - */ - - - onConnectStatusChanged(status_code) { - headless_log.debug('converse-register: onConnectStatusChanged'); - - if ([panel_Strophe.Status.DISCONNECTED, panel_Strophe.Status.CONNFAIL, panel_Strophe.Status.REGIFAIL, panel_Strophe.Status.NOTACCEPTABLE, panel_Strophe.Status.CONFLICT].includes(status_code)) { - headless_log.error(`Problem during registration: Strophe.Status is ${shared_converse.CONNECTION_STATUS[status_code]}`); - this.abortRegistration(); - } else if (status_code === panel_Strophe.Status.REGISTERED) { - headless_log.debug("Registered successfully."); - - shared_converse.connection.reset(); - - this.showSpinner(); - - if (["converse/login", "converse/register"].includes(shared_converse.router.history.getFragment())) { - shared_converse.router.navigate('', { - 'replace': true - }); - } - - if (this.fields.password && this.fields.username) { - // automatically log the user in - shared_converse.connection.connect(this.fields.username.toLowerCase() + '@' + this.domain.toLowerCase(), this.fields.password, shared_converse.onConnectStatusChanged); - - this.giveFeedback(__('Now logging you in'), 'info'); - } else { - shared_converse.giveFeedback(__('Registered successfully')); - } - - this.reset(); - } - } - - getLegacyFormFields() { - const input_fields = Object.keys(this.fields).map(key => { - if (key === "username") { - return form_username({ - 'domain': ` @${this.domain}`, - 'name': key, - 'type': "text", - 'label': key, - 'value': '', - 'required': true - }); - } else { - return form_input({ - 'label': key, - 'name': key, - 'placeholder': key, - 'required': true, - 'type': key === 'password' || key === 'email' ? key : "text", - 'value': '' - }); - } - }); - const urls = this.urls.map(u => form_url({ - 'label': '', - 'value': u - })); - return [...input_fields, ...urls]; - } - - getFormFields(stanza) { - if (this.form_type === 'xform') { - return Array.from(stanza.querySelectorAll('field')).map(field => utils_form.xForm2TemplateResult(field, stanza, { - 'domain': this.domain - })); - } else { - return this.getLegacyFormFields(); - } - } - /** - * Renders the registration form based on the XForm fields - * received from the XMPP server. - * @private - * @method _converse.RegisterPanel#renderRegistrationForm - * @param { XMLElement } stanza - The IQ stanza received from the XMPP server. - */ - - - renderRegistrationForm(stanza) { - this.form_fields = this.getFormFields(stanza); - this.model.set('registration_status', panel_REGISTRATION_FORM); - } - - showValidationError(message) { - const form = this.querySelector('form'); - let flash = form.querySelector('.form-errors'); - - if (flash === null) { - flash = ''; - const instructions = form.querySelector('p.instructions'); - - if (instructions === null) { - form.insertAdjacentHTML('afterbegin', flash); - } else { - instructions.insertAdjacentHTML('afterend', flash); - } - - flash = form.querySelector('.form-errors'); - } else { - flash.innerHTML = ''; - } - - flash.insertAdjacentHTML('beforeend', '

    ' + message + '

    '); - flash.classList.remove('hidden'); - } - /** - * Report back to the user any error messages received from the - * XMPP server after attempted registration. - * @private - * @method _converse.RegisterPanel#reportErrors - * @param { XMLElement } stanza - The IQ stanza received from the XMPP server - */ - - - reportErrors(stanza) { - const errors = stanza.querySelectorAll('error'); - errors.forEach(e => this.showValidationError(e.textContent)); - - if (!errors.length) { - const message = __('The provider rejected your registration attempt. ' + 'Please check the values you entered for correctness.'); - - this.showValidationError(message); - } - } - - renderProviderChoiceForm(ev) { - if (ev && ev.preventDefault) { - ev.preventDefault(); - } - - shared_converse.connection._proto._abortAllRequests(); - - shared_converse.connection.reset(); - - this.render(); - } - - abortRegistration() { - shared_converse.connection._proto._abortAllRequests(); - - shared_converse.connection.reset(); - - if ([panel_FETCHING_FORM, panel_REGISTRATION_FORM].includes(this.model.get('registration_status'))) { - if (api.settings.get('registration_domain')) { - this.fetchRegistrationForm(api.settings.get('registration_domain')); - } - } else { - this.render(); - } - } - /** - * Handler, when the user submits the registration form. - * Provides form error feedback or starts the registration process. - * @private - * @method _converse.RegisterPanel#submitRegistrationForm - * @param { HTMLElement } form - The HTML form that was submitted - */ - - - submitRegistrationForm(form) { - const has_empty_inputs = Array.from(this.querySelectorAll('input.required')).reduce((result, input) => { - if (input.value === '') { - input.classList.add('error'); - return result + 1; - } - - return result; - }, 0); - - if (has_empty_inputs) { - return; - } - - const inputs = panel_sizzle(':input:not([type=button]):not([type=submit])', form); - const iq = panel_$iq({ - 'type': 'set', - 'id': panel_u.getUniqueId() - }).c("query", { - xmlns: panel_Strophe.NS.REGISTER - }); - - if (this.form_type === 'xform') { - iq.c("x", { - xmlns: panel_Strophe.NS.XFORM, - type: 'submit' - }); - const xml_nodes = inputs.map(i => utils_form.webForm2xForm(i)).filter(n => n); - xml_nodes.forEach(n => iq.cnode(n).up()); - } else { - inputs.forEach(input => iq.c(input.getAttribute('name'), {}, input.value)); - } - - shared_converse.connection._addSysHandler(this._onRegisterIQ.bind(this), null, "iq", null, null); - - shared_converse.connection.send(iq); - - this.setFields(iq.tree()); - } - /* Stores the values that will be sent to the XMPP server during attempted registration. - * @private - * @method _converse.RegisterPanel#setFields - * @param { XMLElement } stanza - the IQ stanza that will be sent to the XMPP server. - */ - - - setFields(stanza) { - const query = stanza.querySelector('query'); - const xform = panel_sizzle(`x[xmlns="${panel_Strophe.NS.XFORM}"]`, query); - - if (xform.length > 0) { - this._setFieldsFromXForm(xform.pop()); - } else { - this._setFieldsFromLegacy(query); - } - } - - _setFieldsFromLegacy(query) { - [].forEach.call(query.children, field => { - if (field.tagName.toLowerCase() === 'instructions') { - this.instructions = panel_Strophe.getText(field); - return; - } else if (field.tagName.toLowerCase() === 'x') { - if (field.getAttribute('xmlns') === 'jabber:x:oob') { - this.urls.concat(panel_sizzle('url', field).map(u => u.textContent)); - } - - return; - } - - this.fields[field.tagName.toLowerCase()] = panel_Strophe.getText(field); - }); - this.form_type = 'legacy'; - } - - _setFieldsFromXForm(xform) { - var _xform$querySelector, _xform$querySelector2; - - this.title = (_xform$querySelector = xform.querySelector('title')) === null || _xform$querySelector === void 0 ? void 0 : _xform$querySelector.textContent; - this.instructions = (_xform$querySelector2 = xform.querySelector('instructions')) === null || _xform$querySelector2 === void 0 ? void 0 : _xform$querySelector2.textContent; - xform.querySelectorAll('field').forEach(field => { - const _var = field.getAttribute('var'); - - if (_var) { - var _field$querySelector; - - this.fields[_var.toLowerCase()] = ((_field$querySelector = field.querySelector('value')) === null || _field$querySelector === void 0 ? void 0 : _field$querySelector.textContent) ?? ''; - } else { - // TODO: other option seems to be type="fixed" - headless_log.warn("Found field we couldn't parse"); - } - }); - this.form_type = 'xform'; - } - /** - * Callback method that gets called when a return IQ stanza - * is received from the XMPP server, after attempting to - * register a new user. - * @private - * @method _converse.RegisterPanel#reportErrors - * @param { XMLElement } stanza - The IQ stanza. - */ - - - _onRegisterIQ(stanza) { - if (stanza.getAttribute("type") === "error") { - headless_log.error("Registration failed."); - this.reportErrors(stanza); - let error = stanza.getElementsByTagName("error"); - - if (error.length !== 1) { - shared_converse.connection._changeConnectStatus(panel_Strophe.Status.REGIFAIL, "unknown"); - - return false; - } - - error = error[0].firstElementChild.tagName.toLowerCase(); - - if (error === 'conflict') { - shared_converse.connection._changeConnectStatus(panel_Strophe.Status.CONFLICT, error); - } else if (error === 'not-acceptable') { - shared_converse.connection._changeConnectStatus(panel_Strophe.Status.NOTACCEPTABLE, error); - } else { - shared_converse.connection._changeConnectStatus(panel_Strophe.Status.REGIFAIL, error); - } - } else { - shared_converse.connection._changeConnectStatus(panel_Strophe.Status.REGISTERED, null); - } - - return false; - } - -} - -api.elements.define('converse-register-panel', RegisterPanel); -;// CONCATENATED MODULE: ./src/plugins/register/index.js -/** - * @module converse-register - * @description - * This is a Converse.js plugin which add support for in-band registration - * as specified in XEP-0077. - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - // Strophe methods for building stanzas - -const { - Strophe: register_Strophe -} = core_converse.env; // Add Strophe Namespaces - -register_Strophe.addNamespace('REGISTER', 'jabber:iq:register'); // Add Strophe Statuses - -const register_i = Object.keys(register_Strophe.Status).reduce((max, k) => Math.max(max, register_Strophe.Status[k]), 0); -register_Strophe.Status.REGIFAIL = register_i + 1; -register_Strophe.Status.REGISTERED = register_i + 2; -register_Strophe.Status.CONFLICT = register_i + 3; -register_Strophe.Status.NOTACCEPTABLE = register_i + 5; -core_converse.plugins.add('converse-register', { - dependencies: ['converse-controlbox'], - - enabled() { - return true; - }, - - initialize() { - shared_converse.CONNECTION_STATUS[register_Strophe.Status.REGIFAIL] = 'REGIFAIL'; - shared_converse.CONNECTION_STATUS[register_Strophe.Status.REGISTERED] = 'REGISTERED'; - shared_converse.CONNECTION_STATUS[register_Strophe.Status.CONFLICT] = 'CONFLICT'; - shared_converse.CONNECTION_STATUS[register_Strophe.Status.NOTACCEPTABLE] = 'NOTACCEPTABLE'; - api.settings.extend({ - 'allow_registration': true, - 'domain_placeholder': __(' e.g. conversejs.org'), - // Placeholder text shown in the domain input on the registration form - 'providers_link': 'https://compliance.conversations.im/', - // Link to XMPP providers shown on registration page - 'registration_domain': '' - }); - - async function setActiveForm(value) { - await api.waitUntil('controlBoxInitialized'); - - const controlbox = shared_converse.chatboxes.get('controlbox'); - - controlbox.set({ - 'active-form': value - }); - } - - shared_converse.router.route('converse/login', () => setActiveForm('login')); - - shared_converse.router.route('converse/register', () => setActiveForm('register')); - - api.listen.on('controlBoxInitialized', view => { - view.model.on('change:active-form', view.showLoginOrRegisterForm, view); - }); - } - -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/add-muc.js - - - - - - -const nickname_input = o => { - const i18n_nickname = __('Nickname'); - - const i18n_required_field = __('This field is required'); - - return T` -
    - - -
    - `; -}; - -/* harmony default export */ const add_muc = (o => { - const i18n_join = __('Join'); - - const i18n_enter = __('Enter a new Groupchat'); - - return T` - - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/modals/add-muc.js - - - - -const add_muc_u = core_converse.env.utils; -const { - Strophe: add_muc_Strophe -} = core_converse.env; -/* harmony default export */ const modals_add_muc = (base.extend({ - persistent: true, - id: 'add-chatroom-modal', - events: { - 'submit form.add-chatroom': 'openChatRoom', - 'keyup .roomjid-input': 'checkRoomidPolicy', - 'change .roomjid-input': 'checkRoomidPolicy' - }, - - initialize() { - base.prototype.initialize.apply(this, arguments); - this.listenTo(this.model, 'change:muc_domain', this.render); - this.muc_roomid_policy_error_msg = null; - }, - - toHTML() { - let placeholder = ''; - - if (!api.settings.get('locked_muc_domain')) { - const muc_domain = this.model.get('muc_domain') || api.settings.get('muc_domain'); - placeholder = muc_domain ? `name@${muc_domain}` : __('name@conference.example.org'); - } - - return add_muc(Object.assign(this.model.toJSON(), { - '_converse': shared_converse, - 'label_room_address': api.settings.get('muc_domain') ? __('Groupchat name') : __('Groupchat address'), - 'chatroom_placeholder': placeholder, - 'muc_roomid_policy_error_msg': this.muc_roomid_policy_error_msg, - 'muc_roomid_policy_hint': api.settings.get('muc_roomid_policy_hint') - })); - }, - - afterRender() { - this.el.addEventListener('shown.bs.modal', () => { - this.el.querySelector('input[name="chatroom"]').focus(); - }, false); - }, - - parseRoomDataFromEvent(form) { - const data = new FormData(form); - const jid = data.get('chatroom'); - let nick; - - if (api.settings.get('locked_muc_nickname')) { - nick = shared_converse.getDefaultMUCNickname(); - - if (!nick) { - throw new Error("Using locked_muc_nickname but no nickname found!"); - } - } else { - nick = data.get('nickname').trim(); - } - - return { - 'jid': jid, - 'nick': nick - }; - }, - - openChatRoom(ev) { - ev.preventDefault(); - const data = this.parseRoomDataFromEvent(ev.target); - - if (data.nick === "") { - // Make sure defaults apply if no nick is provided. - data.nick = undefined; - } - - let jid; - - if (api.settings.get('locked_muc_domain') || api.settings.get('muc_domain') && !add_muc_u.isValidJID(data.jid)) { - jid = `${add_muc_Strophe.escapeNode(data.jid)}@${api.settings.get('muc_domain')}`; - } else { - jid = data.jid; - this.model.setDomain(jid); - } - - api.rooms.open(jid, Object.assign(data, { - jid - }), true); - this.modal.hide(); - ev.target.reset(); - }, - - checkRoomidPolicy() { - if (api.settings.get('muc_roomid_policy') && api.settings.get('muc_domain')) { - let jid = this.el.querySelector('.roomjid-input').value; - - if (core_converse.locked_muc_domain || !add_muc_u.isValidJID(jid)) { - jid = `${add_muc_Strophe.escapeNode(jid)}@${api.settings.get('muc_domain')}`; - } - - const roomid = add_muc_Strophe.getNodeFromJid(jid); - const roomdomain = add_muc_Strophe.getDomainFromJid(jid); - - if (api.settings.get('muc_domain') !== roomdomain || api.settings.get('muc_roomid_policy').test(roomid)) { - this.muc_roomid_policy_error_msg = null; - } else { - this.muc_roomid_policy_error_msg = __('Groupchat id is invalid.'); - } - - this.render(); - } - } - -})); -;// CONCATENATED MODULE: ./node_modules/lodash-es/head.js -/** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias first - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.head([1, 2, 3]); - * // => 1 - * - * _.head([]); - * // => undefined - */ -function head(array) { - return array && array.length ? array[0] : undefined; -} - -/* harmony default export */ const lodash_es_head = (head); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-list.js - - - - - - -const muc_list_form = o => { - const i18n_query = __('Show groupchats'); - - const i18n_server_address = __('Server address'); - - return T` -
    -
    - - -
    - -
    - `; -}; - -const tpl_item = (o, item) => { - const i18n_info_title = __('Show more information on this groupchat'); - - const i18n_open_title = __('Click to open this groupchat'); - - return T` -
  • - -
  • - `; -}; - -/* harmony default export */ const muc_list = (o => { - const i18n_list_chatrooms = __('Query for Groupchats'); - - return T` - - `; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/templates/muc-description.js - - -/* harmony default export */ const muc_description = (o => { - const i18n_desc = __('Description:'); - - const i18n_jid = __('Groupchat XMPP Address:'); - - const i18n_occ = __('Participants:'); - - const i18n_features = __('Features:'); - - const i18n_requires_auth = __('Requires authentication'); - - const i18n_hidden = __('Hidden'); - - const i18n_requires_invite = __('Requires an invitation'); - - const i18n_moderated = __('Moderated'); - - const i18n_non_anon = __('Non-anonymous'); - - const i18n_open_room = __('Open'); - - const i18n_permanent_room = __('Permanent'); - - const i18n_public = __('Public'); - - const i18n_semi_anon = __('Semi-anonymous'); - - const i18n_temp_room = __('Temporary'); - - const i18n_unmoderated = __('Unmoderated'); - - return T` -
    -

    ${i18n_jid} ${o.jid}

    -

    ${i18n_desc} ${o.desc}

    -

    ${i18n_occ} ${o.occ}

    -

    ${i18n_features} -

      - ${o.passwordprotected ? T`
    • ${i18n_requires_auth}
    • ` : ''} - ${o.hidden ? T`
    • ${i18n_hidden}
    • ` : ''} - ${o.membersonly ? T`
    • ${i18n_requires_invite}
    • ` : ''} - ${o.moderated ? T`
    • ${i18n_moderated}
    • ` : ''} - ${o.nonanonymous ? T`
    • ${i18n_non_anon}
    • ` : ''} - ${o.open ? T`
    • ${i18n_open_room}
    • ` : ''} - ${o.persistent ? T`
    • ${i18n_permanent_room}
    • ` : ''} - ${o.publicroom ? T`
    • ${i18n_public}
    • ` : ''} - ${o.semianonymous ? T`
    • ${i18n_semi_anon}
    • ` : ''} - ${o.temporary ? T`
    • ${i18n_temp_room}
    • ` : ''} - ${o.unmoderated ? T`
    • ${i18n_unmoderated}
    • ` : ''} -
    -

    -
    -`; -}); -;// CONCATENATED MODULE: ./src/plugins/muc-views/modals/muc-list.js - - - - - - - - - -const { - Strophe: muc_list_Strophe, - $iq: muc_list_$iq, - sizzle: muc_list_sizzle -} = core_converse.env; -const muc_list_u = core_converse.env.utils; -/* Insert groupchat info (based on returned #disco IQ stanza) - * @function insertRoomInfo - * @param { HTMLElement } el - The HTML DOM element that contains the info. - * @param { XMLElement } stanza - The IQ stanza containing the groupchat info. - */ - -function insertRoomInfo(el, stanza) { - var _head, _head2; - - // All MUC features found here: https://xmpp.org/registrar/disco-features.html - el.querySelector('span.spinner').remove(); - el.querySelector('a.room-info').classList.add('selected'); - el.insertAdjacentHTML('beforeEnd', muc_list_u.getElementFromTemplateResult(muc_description({ - 'jid': stanza.getAttribute('from'), - 'desc': (_head = lodash_es_head(muc_list_sizzle('field[var="muc#roominfo_description"] value', stanza))) === null || _head === void 0 ? void 0 : _head.textContent, - 'occ': (_head2 = lodash_es_head(muc_list_sizzle('field[var="muc#roominfo_occupants"] value', stanza))) === null || _head2 === void 0 ? void 0 : _head2.textContent, - 'hidden': muc_list_sizzle('feature[var="muc_hidden"]', stanza).length, - 'membersonly': muc_list_sizzle('feature[var="muc_membersonly"]', stanza).length, - 'moderated': muc_list_sizzle('feature[var="muc_moderated"]', stanza).length, - 'nonanonymous': muc_list_sizzle('feature[var="muc_nonanonymous"]', stanza).length, - 'open': muc_list_sizzle('feature[var="muc_open"]', stanza).length, - 'passwordprotected': muc_list_sizzle('feature[var="muc_passwordprotected"]', stanza).length, - 'persistent': muc_list_sizzle('feature[var="muc_persistent"]', stanza).length, - 'publicroom': muc_list_sizzle('feature[var="muc_publicroom"]', stanza).length, - 'semianonymous': muc_list_sizzle('feature[var="muc_semianonymous"]', stanza).length, - 'temporary': muc_list_sizzle('feature[var="muc_temporary"]', stanza).length, - 'unmoderated': muc_list_sizzle('feature[var="muc_unmoderated"]', stanza).length - }))); -} -/** - * Show/hide extra information about a groupchat in a listing. - * @function toggleRoomInfo - * @param { Event } - */ - - -function toggleRoomInfo(ev) { - const parent_el = muc_list_u.ancestor(ev.target, '.room-item'); - const div_el = parent_el.querySelector('div.room-info'); - - if (div_el) { - muc_list_u.slideIn(div_el).then(muc_list_u.removeElement); - parent_el.querySelector('a.room-info').classList.remove('selected'); - } else { - parent_el.insertAdjacentElement('beforeend', muc_list_u.getElementFromTemplateResult(spinner())); - api.disco.info(ev.target.getAttribute('data-room-jid'), null).then(stanza => insertRoomInfo(parent_el, stanza)).catch(e => headless_log.error(e)); - } -} - -/* harmony default export */ const modals_muc_list = (base.extend({ - id: "muc-list-modal", - persistent: true, - - initialize() { - this.items = []; - this.loading_items = false; - base.prototype.initialize.apply(this, arguments); - - if (api.settings.get('muc_domain') && !this.model.get('muc_domain')) { - this.model.save('muc_domain', api.settings.get('muc_domain')); - } - - this.listenTo(this.model, 'change:muc_domain', this.onDomainChange); - this.el.addEventListener('shown.bs.modal', () => api.settings.get('locked_muc_domain') ? this.updateRoomsList() : this.el.querySelector('input[name="server"]').focus()); - }, - - toHTML() { - const muc_domain = this.model.get('muc_domain') || api.settings.get('muc_domain'); - return muc_list(Object.assign(this.model.toJSON(), { - 'show_form': !api.settings.get('locked_muc_domain'), - 'server_placeholder': muc_domain ? muc_domain : __('conference.example.org'), - 'items': this.items, - 'loading_items': this.loading_items, - 'openRoom': ev => this.openRoom(ev), - 'setDomainFromEvent': ev => this.setDomainFromEvent(ev), - 'submitForm': ev => this.showRooms(ev), - 'toggleRoomInfo': ev => this.toggleRoomInfo(ev) - })); - }, - - openRoom(ev) { - ev.preventDefault(); - const jid = ev.target.getAttribute('data-room-jid'); - const name = ev.target.getAttribute('data-room-name'); - this.modal.hide(); - api.rooms.open(jid, { - 'name': name - }, true); - }, - - toggleRoomInfo(ev) { - ev.preventDefault(); - toggleRoomInfo(ev); - }, - - onDomainChange() { - api.settings.get('auto_list_rooms') && this.updateRoomsList(); - }, - - /** - * Handle the IQ stanza returned from the server, containing - * all its public groupchats. - * @private - * @method _converse.ChatRoomView#onRoomsFound - * @param { HTMLElement } iq - */ - onRoomsFound(iq) { - this.loading_items = false; - const rooms = iq ? muc_list_sizzle('query item', iq) : []; - - if (rooms.length) { - this.model.set({ - 'feedback_text': __('Groupchats found') - }, { - 'silent': true - }); - this.items = rooms.map(getAttributes); - } else { - this.items = []; - this.model.set({ - 'feedback_text': __('No groupchats found') - }, { - 'silent': true - }); - } - - this.render(); - return true; - }, - - /** - * Send an IQ stanza to the server asking for all groupchats - * @private - * @method _converse.ChatRoomView#updateRoomsList - */ - updateRoomsList() { - const iq = muc_list_$iq({ - 'to': this.model.get('muc_domain'), - 'from': shared_converse.connection.jid, - 'type': "get" - }).c("query", { - xmlns: muc_list_Strophe.NS.DISCO_ITEMS - }); - api.sendIQ(iq).then(iq => this.onRoomsFound(iq)).catch(() => this.onRoomsFound()); - }, - - showRooms(ev) { - ev.preventDefault(); - this.loading_items = true; - this.render(); - const data = new FormData(ev.target); - this.model.setDomain(data.get('server')); - this.updateRoomsList(); - }, - - setDomainFromEvent(ev) { - this.model.setDomain(ev.target.value); - }, - - setNick(ev) { - this.model.save({ - nick: ev.target.value - }); - } - -})); -;// CONCATENATED MODULE: ./src/plugins/roomslist/templates/roomslist.js - - - - - - -const bookmark = o => { - const i18n_add_bookmark = __('Bookmark this groupchat'); - - const i18n_remove_bookmark = __('Unbookmark this groupchat'); - - if (o.bookmarked) { - return T` - `; - } else { - return T` - `; - } -}; - -const unread_indicator = o => T`${o.room.get('num_unread')}`; - -const activity_indicator = () => T``; - -const room_item = o => { - const i18n_leave_room = __('Leave this groupchat'); - - const has_unread_msgs = o.room.get('num_unread_general') || o.room.get('has_activity'); - return T` -
    - - ${o.room.get('num_unread') ? unread_indicator(o) : o.room.get('has_activity') ? activity_indicator(o) : ''} - - ${o.room.getDisplayName()} - - ${o.allow_bookmarks ? bookmark(o) : ''} - - - - -
    `; -}; - -/* harmony default export */ const roomslist = (o => { - const i18n_desc_rooms = __('Click to toggle the list of open groupchats'); - - const i18n_heading_chatrooms = __('Groupchats'); - - const i18n_title_list_rooms = __('Query for groupchats'); - - const i18n_title_new_room = __('Add a new groupchat'); - - return T` - - -
    - - ${__('Open Groupchats')} -
    - ${o.rooms.map(room => room_item(Object.assign({ - room - }, o)))} -
    -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/roomslist/model.js - - -const { - Strophe: roomslist_model_Strophe -} = core_converse.env; -const RoomsListModel = Model.extend({ - defaults: function () { - return { - 'muc_domain': api.settings.get('muc_domain'), - 'nick': shared_converse.getDefaultMUCNickname(), - 'toggle-state': shared_converse.OPENED - }; - }, - - setDomain(jid) { - if (!api.settings.get('locked_muc_domain')) { - this.save('muc_domain', roomslist_model_Strophe.getDomainFromJid(jid)); - } - } - -}); -/* harmony default export */ const roomslist_model = (RoomsListModel); -;// CONCATENATED MODULE: ./src/plugins/roomslist/view.js - - - - - - - - -const { - Strophe: view_Strophe, - u: view_u -} = core_converse.env; -class RoomsList extends ElementView { - initialize() { - const id = `converse.roomspanel${shared_converse.bare_jid}`; - this.model = new roomslist_model({ - id - }); - initStorage(this.model, id); - this.model.fetch(); - this.listenTo(shared_converse.chatboxes, 'add', this.renderIfChatRoom); - this.listenTo(shared_converse.chatboxes, 'remove', this.renderIfChatRoom); - this.listenTo(shared_converse.chatboxes, 'destroy', this.renderIfChatRoom); - this.listenTo(shared_converse.chatboxes, 'change', this.renderIfRelevantChange); - this.render(); - } - - renderIfChatRoom(model) { - view_u.isChatRoom(model) && this.render(); - } - - renderIfRelevantChange(model) { - const attrs = ['bookmarked', 'hidden', 'name', 'num_unread', 'num_unread_general', 'has_activity']; - const changed = model.changed || {}; - - if (view_u.isChatRoom(model) && Object.keys(changed).filter(m => attrs.includes(m)).length) { - this.render(); - } - } - - render() { - V(roomslist({ - 'addBookmark': ev => this.addBookmark(ev), - 'allow_bookmarks': shared_converse.allow_bookmarks && shared_converse.bookmarks, - 'closeRoom': ev => this.closeRoom(ev), - 'collapsed': this.model.get('toggle-state') !== shared_converse.OPENED, - 'currently_open': room => shared_converse.isUniView() && !room.get('hidden'), - 'model': this.model, - 'openRoom': ev => this.openRoom(ev), - 'removeBookmark': ev => this.removeBookmark(ev), - 'rooms': shared_converse.chatboxes.filter(m => m.get('type') === shared_converse.CHATROOMS_TYPE), - 'showRoomDetailsModal': ev => this.showRoomDetailsModal(ev), - 'toggleRoomsList': ev => this.toggleRoomsList(ev), - 'toggle_state': this.model.get('toggle-state') - }), this); - } - - showRoomDetailsModal(ev) { - // eslint-disable-line class-methods-use-this - const jid = ev.target.getAttribute('data-room-jid'); - - const room = shared_converse.chatboxes.get(jid); - - ev.preventDefault(); - api.modal.show(modals_muc_details, { - 'model': room - }, ev); - } - - async openRoom(ev) { - // eslint-disable-line class-methods-use-this - ev.preventDefault(); - const name = ev.target.textContent; - const jid = ev.target.getAttribute('data-room-jid'); - const data = { - 'name': name || view_Strophe.unescapeNode(view_Strophe.getNodeFromJid(jid)) || jid - }; - await api.rooms.open(jid, data, true); - } - - async closeRoom(ev) { - // eslint-disable-line class-methods-use-this - ev.preventDefault(); - const name = ev.target.getAttribute('data-room-name'); - - if (confirm(__("Are you sure you want to leave the groupchat %1$s?", name))) { - const jid = ev.target.getAttribute('data-room-jid'); - const room = await api.rooms.get(jid); - room.close(); - } - } - - removeBookmark(ev) { - // eslint-disable-line class-methods-use-this - shared_converse.removeBookmarkViaEvent(ev); - } - - addBookmark(ev) { - // eslint-disable-line class-methods-use-this - shared_converse.addBookmarkViaEvent(ev); - } - - toggleRoomsList(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - const icon_el = ev.target.matches('.fa') ? ev.target : ev.target.querySelector('.fa'); - - if (icon_el.classList.contains("fa-caret-down")) { - view_u.slideIn(this.querySelector('.open-rooms-list')).then(() => { - this.model.save({ - 'toggle-state': shared_converse.CLOSED - }); - icon_el.classList.remove("fa-caret-down"); - icon_el.classList.add("fa-caret-right"); - }); - } else { - view_u.slideOut(this.querySelector('.open-rooms-list')).then(() => { - this.model.save({ - 'toggle-state': shared_converse.OPENED - }); - icon_el.classList.remove("fa-caret-right"); - icon_el.classList.add("fa-caret-down"); - }); - } - } - -} -api.elements.define('converse-rooms-list', RoomsList); -;// CONCATENATED MODULE: ./src/plugins/roomslist/index.js -/** - * @description - * Converse.js plugin which shows a list of currently open - * rooms in the "Rooms Panel" of the ControlBox. - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - -core_converse.plugins.add('converse-roomslist', { - dependencies: ["converse-singleton", "converse-controlbox", "converse-muc", "converse-bookmarks"], - - initialize() { - // Event handlers - api.listen.on('connected', async () => { - if (shared_converse.allow_bookmarks) { - await api.waitUntil('bookmarksInitialized'); - } else { - await Promise.all([api.waitUntil('chatBoxesFetched')]); - } - }); - } - -}); -;// CONCATENATED MODULE: ./src/shared/templates/icons.js - -/* harmony default export */ const icons = (() => T` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`); -;// CONCATENATED MODULE: ./src/shared/components/font-awesome.js - - -class FontAwesome extends CustomElement { - render() { - // eslint-disable-line class-methods-use-this - return icons(); - } - -} -window.customElements.define('converse-fontawesome', FontAwesome); -;// CONCATENATED MODULE: ./src/plugins/rootview/templates/root.js - - - -/* harmony default export */ const templates_root = (() => { - let extra_classes = api.settings.get('singleton') ? 'converse-singleton' : ''; - extra_classes += `converse-${api.settings.get('view_mode')}`; - return T` - -
    - - `; -}); -;// CONCATENATED MODULE: ./src/plugins/rootview/root.js - - - -/** - * `converse-root` is an optional custom element which can be used to - * declaratively insert the Converse UI into the DOM. - * - * It can be inserted into the DOM before or after Converse has loaded or been - * initialized. - */ - -class ConverseRoot extends CustomElement { - render() { - // eslint-disable-line class-methods-use-this - return templates_root(); - } - - connectedCallback() { - super.connectedCallback(); - this.classList.add('conversejs'); - this.classList.add(`converse-${api.settings.get('view_mode')}`); - this.classList.add(`theme-${api.settings.get('theme')}`); - this.setAttribute('id', 'conversejs'); - } - -} - -customElements.define('converse-root', ConverseRoot); -;// CONCATENATED MODULE: ./src/plugins/rootview/utils.js - -function ensureElement() { - if (!api.settings.get('auto_insert')) { - return; - } - - const root = api.settings.get('root'); - - if (!root.querySelector('converse-root#conversejs')) { - const el = document.createElement('converse-root'); - const body = root.querySelector('body'); - - if (body) { - body.appendChild(el); - } else { - root.appendChild(el); // Perhaps inside a web component? - } - } -} -;// CONCATENATED MODULE: ./src/plugins/rootview/index.js - - - -core_converse.plugins.add('converse-rootview', { - initialize() { - api.settings.extend({ - 'auto_insert': true - }); - api.listen.on('chatBoxesInitialized', ensureElement); - } - -}); -;// CONCATENATED MODULE: ./src/modals/templates/add-contact.js - - - -/* harmony default export */ const add_contact = (o => { - const i18n_contact_placeholder = __('name@example.org'); - - const i18n_add = __('Add'); - - const i18n_error_message = __('Please enter a valid XMPP address'); - - const i18n_new_contact = __('Add a Contact'); - - const i18n_xmpp_address = __('XMPP Address'); - - const i18n_nickname = __('Nickname'); - - return T` - - `; -}); -;// CONCATENATED MODULE: ./src/modals/add-contact.js - - - - - - - -const { - Strophe: add_contact_Strophe -} = core_converse.env; -const add_contact_u = core_converse.env.utils; -const AddContactModal = base.extend({ - id: "add-contact-modal", - events: { - 'submit form': 'addContactFromForm' - }, - - initialize() { - base.prototype.initialize.apply(this, arguments); - this.listenTo(this.model, 'change', this.render); - }, - - toHTML() { - const label_nickname = api.settings.get('xhr_user_search_url') ? __('Contact name') : __('Optional nickname'); - return add_contact(Object.assign(this.model.toJSON(), { - _converse: shared_converse, - label_nickname - })); - }, - - afterRender() { - if (typeof api.settings.get('xhr_user_search_url') === 'string') { - this.initXHRAutoComplete(); - } else { - this.initJIDAutoComplete(); - } - - const jid_input = this.el.querySelector('input[name="jid"]'); - this.el.addEventListener('shown.bs.modal', () => jid_input.focus(), false); - }, - - initJIDAutoComplete() { - if (!api.settings.get('autocomplete_add_contact')) { - return; - } - - const el = this.el.querySelector('.suggestion-box__jid').parentElement; - this.jid_auto_complete = new shared_converse.AutoComplete(el, { - 'data': (text, input) => `${input.slice(0, input.indexOf("@"))}@${text}`, - 'filter': shared_converse.FILTER_STARTSWITH, - 'list': [...new Set(shared_converse.roster.map(item => add_contact_Strophe.getDomainFromJid(item.get('jid'))))] - }); - }, - - initXHRAutoComplete() { - if (!api.settings.get('autocomplete_add_contact')) { - return this.initXHRFetch(); - } - - const el = this.el.querySelector('.suggestion-box__name').parentElement; - this.name_auto_complete = new shared_converse.AutoComplete(el, { - 'auto_evaluate': false, - 'filter': shared_converse.FILTER_STARTSWITH, - 'list': [] - }); - const xhr = new window.XMLHttpRequest(); // `open` must be called after `onload` for mock/testing purposes. - - xhr.onload = () => { - if (xhr.responseText) { - const r = xhr.responseText; - this.name_auto_complete.list = JSON.parse(r).map(i => ({ - 'label': i.fullname || i.jid, - 'value': i.jid - })); - this.name_auto_complete.auto_completing = true; - this.name_auto_complete.evaluate(); - } - }; - - const input_el = this.el.querySelector('input[name="name"]'); - input_el.addEventListener('input', lodash_es_debounce(() => { - xhr.open("GET", `${api.settings.get('xhr_user_search_url')}q=${encodeURIComponent(input_el.value)}`, true); - xhr.send(); - }, 300)); - this.name_auto_complete.on('suggestion-box-selectcomplete', ev => { - this.el.querySelector('input[name="name"]').value = ev.text.label; - this.el.querySelector('input[name="jid"]').value = ev.text.value; - }); - }, - - initXHRFetch() { - this.xhr = new window.XMLHttpRequest(); - - this.xhr.onload = () => { - if (this.xhr.responseText) { - const r = this.xhr.responseText; - const list = JSON.parse(r).map(i => ({ - 'label': i.fullname || i.jid, - 'value': i.jid - })); - - if (list.length !== 1) { - const el = this.el.querySelector('.invalid-feedback'); - el.textContent = __('Sorry, could not find a contact with that name'); - add_contact_u.addClass('d-block', el); - return; - } - - const jid = list[0].value; - - if (this.validateSubmission(jid)) { - const form = this.el.querySelector('form'); - const name = list[0].label; - this.afterSubmission(form, jid, name); - } - } - }; - }, - - validateSubmission(jid) { - const el = this.el.querySelector('.invalid-feedback'); - - if (!jid || lodash_es_compact(jid.split('@')).length < 2) { - add_contact_u.addClass('is-invalid', this.el.querySelector('input[name="jid"]')); - add_contact_u.addClass('d-block', el); - return false; - } else if (shared_converse.roster.get(add_contact_Strophe.getBareJidFromJid(jid))) { - el.textContent = __('This contact has already been added'); - add_contact_u.addClass('d-block', el); - return false; - } - - add_contact_u.removeClass('d-block', el); - return true; - }, - - afterSubmission(form, jid, name) { - shared_converse.roster.addAndSubscribe(jid, name); - - this.model.clear(); - this.modal.hide(); - }, - - addContactFromForm(ev) { - ev.preventDefault(); - const data = new FormData(ev.target), - jid = (data.get('jid') || '').trim(); - - if (!jid && typeof api.settings.get('xhr_user_search_url') === 'string') { - const input_el = this.el.querySelector('input[name="name"]'); - this.xhr.open("GET", `${api.settings.get('xhr_user_search_url')}q=${encodeURIComponent(input_el.value)}`, true); - this.xhr.send(); - return; - } - - if (this.validateSubmission(jid)) { - this.afterSubmission(ev.target, jid, data.get('name')); - } - } - -}); -shared_converse.AddContactModal = AddContactModal; -/* harmony default export */ const modals_add_contact = ((/* unused pure expression or super */ null && (AddContactModal))); -;// CONCATENATED MODULE: ./src/plugins/rosterview/utils.js - -function highlightRosterItem(chatbox) { - var _converse$roster, _converse$roster$find; - - (_converse$roster = shared_converse.roster) === null || _converse$roster === void 0 ? void 0 : (_converse$roster$find = _converse$roster.findWhere({ - 'jid': chatbox.get('jid') - })) === null || _converse$roster$find === void 0 ? void 0 : _converse$roster$find.trigger('highlight'); -} -function toggleGroup(ev, name) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - - const collapsed = shared_converse.roster.state.get('collapsed_groups'); - - if (collapsed.includes(name)) { - shared_converse.roster.state.save('collapsed_groups', collapsed.filter(n => n !== name)); - } else { - shared_converse.roster.state.save('collapsed_groups', [...collapsed, name]); - } -} -function isContactFiltered(contact, groupname) { - const filter = shared_converse.roster_filter; - const type = filter.get('filter_type'); - const q = type === 'state' ? filter.get('chat_state').toLowerCase() : filter.get('filter_text').toLowerCase(); - if (!q) return false; - - if (type === 'state') { - const sticky_groups = [shared_converse.HEADER_REQUESTING_CONTACTS, shared_converse.HEADER_UNREAD]; - - if (sticky_groups.includes(groupname)) { - // When filtering by chat state, we still want to - // show sticky groups, even though they don't - // match the state in question. - return false; - } else if (q === 'unread_messages') { - return contact.get('num_unread') === 0; - } else if (q === 'online') { - return ["offline", "unavailable"].includes(contact.presence.get('show')); - } else { - return !contact.presence.get('show').includes(q); - } - } else if (type === 'contacts') { - return !contact.getFilterCriteria().includes(q); - } -} -function shouldShowContact(contact, groupname) { - const chat_status = contact.presence.get('show'); - - if (api.settings.get('hide_offline_users') && chat_status === 'offline') { - // If pending or requesting, show - if (contact.get('ask') === 'subscribe' || contact.get('subscription') === 'from' || contact.get('requesting') === true) { - return !isContactFiltered(contact, groupname); - } - - return false; - } - - return !isContactFiltered(contact, groupname); -} -function shouldShowGroup(group) { - const filter = shared_converse.roster_filter; - const type = filter.get('filter_type'); - - if (type === 'groups') { - var _filter$get; - - const q = (_filter$get = filter.get('filter_text')) === null || _filter$get === void 0 ? void 0 : _filter$get.toLowerCase(); - - if (!q) { - return true; - } - - if (!group.toLowerCase().includes(q)) { - return false; - } - } - - return true; -} -;// CONCATENATED MODULE: ./src/plugins/rosterview/templates/group.js - - - - - -const { - u: group_u -} = core_converse.env; - -function renderContact(contact) { - const jid = contact.get('jid'); - const extra_classes = []; - - if (shared_converse.isUniView()) { - const chatbox = shared_converse.chatboxes.get(jid); - - if (chatbox && !chatbox.get('hidden')) { - extra_classes.push('open'); - } - } - - const ask = contact.get('ask'); - const requesting = contact.get('requesting'); - const subscription = contact.get('subscription'); - - if (ask === 'subscribe' || subscription === 'from') { - /* ask === 'subscribe' - * Means we have asked to subscribe to them. - * - * subscription === 'from' - * They are subscribed to us, but not vice versa. - * We assume that there is a pending subscription - * from us to them (otherwise we're in a state not - * supported by converse.js). - * - * So in both cases the user is a "pending" contact. - */ - extra_classes.push('pending-xmpp-contact'); - } else if (requesting === true) { - extra_classes.push('requesting-xmpp-contact'); - } else if (subscription === 'both' || subscription === 'to' || group_u.isSameBareJID(jid, shared_converse.connection.jid)) { - extra_classes.push('current-xmpp-contact'); - extra_classes.push(subscription); - extra_classes.push(contact.presence.get('show')); - } - - return T` -
  • - -
  • `; -} - -/* harmony default export */ const group = (o => { - const i18n_title = __('Click to hide these contacts'); - - const collapsed = shared_converse.roster.state.get('collapsed_groups'); - - return T` -
    - toggleGroup(ev, o.name)}> - ${o.name} - -
      - ${o.contacts.map(renderContact)} -
    -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/rosterview/templates/roster.js - - - - - - - - -function populateContactsMap(contacts_map, contact) { - if (contact.get('ask') === 'subscribe') { - const name = shared_converse.HEADER_PENDING_CONTACTS; - contacts_map[name] ? contacts_map[name].push(contact) : contacts_map[name] = [contact]; - } else if (contact.get('requesting')) { - const name = shared_converse.HEADER_REQUESTING_CONTACTS; - contacts_map[name] ? contacts_map[name].push(contact) : contacts_map[name] = [contact]; - } else { - let contact_groups; - - if (api.settings.get('roster_groups')) { - contact_groups = contact.get('groups'); - contact_groups = contact_groups.length === 0 ? [shared_converse.HEADER_UNGROUPED] : contact_groups; - } else { - contact_groups = [shared_converse.HEADER_CURRENT_CONTACTS]; - } - - for (const name of contact_groups) { - contacts_map[name] ? contacts_map[name].push(contact) : contacts_map[name] = [contact]; - } - } - - if (contact.get('num_unread')) { - const name = shared_converse.HEADER_UNREAD; - contacts_map[name] ? contacts_map[name].push(contact) : contacts_map[name] = [contact]; - } - - return contacts_map; -} - -/* harmony default export */ const roster = (el => { - const i18n_heading_contacts = __('Contacts'); - - const i18n_title_add_contact = __('Add a contact'); - - const i18n_title_sync_contacts = __('Re-sync your contacts'); - - const roster = shared_converse.roster || []; - const contacts_map = roster.reduce((acc, contact) => populateContactsMap(acc, contact), {}); - const groupnames = Object.keys(contacts_map).filter(shouldShowGroup); - groupnames.sort(groupsComparator); - return T` - - -
    - ${repeat_c(groupnames, n => n, name => { - const contacts = contacts_map[name].filter(c => shouldShowContact(c, name)); - contacts.sort(contactsComparator); - - if (contacts.length) { - return group({ - 'contacts': contacts, - 'name': name - }); - } else { - return ''; - } - })} -
    - `; -}); -;// CONCATENATED MODULE: ./src/plugins/rosterview/rosterview.js - - - - -/** - * @class - * @namespace _converse.RosterView - * @memberOf _converse - */ - -class RosterView extends CustomElement { - constructor() { - super(); - this.initialize(); - } - - async initialize() { - await api.waitUntil('rosterInitialized'); - this.listenTo(shared_converse, 'rosterContactsFetched', this.requestUpdate); - this.listenTo(shared_converse.presences, 'change:show', this.requestUpdate); - this.listenTo(shared_converse.roster, 'add', this.requestUpdate); - this.listenTo(shared_converse.roster, 'destroy', this.requestUpdate); - this.listenTo(shared_converse.roster, 'remove', this.requestUpdate); - this.listenTo(shared_converse.roster, 'change', this.requestUpdate); - this.listenTo(shared_converse.roster.state, 'change', this.requestUpdate); - /** - * Triggered once the _converse.RosterView instance has been created and initialized. - * @event _converse#rosterViewInitialized - * @example _converse.api.listen.on('rosterViewInitialized', () => { ... }); - */ - - api.trigger('rosterViewInitialized'); - } - - firstUpdated() { - this.listenToRosterFilter(); - } - - render() { - return roster(this); - } - - listenToRosterFilter() { - this.filter_view = this.querySelector('converse-roster-filter'); - this.filter_view.addEventListener('update', () => this.requestUpdate()); - } - - showAddContactModal(ev) { - // eslint-disable-line class-methods-use-this - api.modal.show(shared_converse.AddContactModal, { - 'model': new Model() - }, ev); - } - - async syncContacts(ev) { - // eslint-disable-line class-methods-use-this - ev.preventDefault(); - this.syncing_contacts = true; - this.requestUpdate(); - - shared_converse.roster.data.save('version', null); - - await shared_converse.roster.fetchFromServer(); - api.user.presence.send(); - this.syncing_contacts = false; - this.requestUpdate(); - } - -} -api.elements.define('converse-roster', RosterView); -;// CONCATENATED MODULE: ./src/plugins/rosterview/templates/pending_contact.js - - - - -const tpl_pending_contact = o => T`${o.display_name}`; - -/* harmony default export */ const pending_contact = (o => { - const i18n_remove = __('Click to remove %1$s as a contact', o.display_name); - - return T` - ${api.settings.get('allow_chat_pending_contacts') ? T`${tpl_pending_contact(o)}` : tpl_pending_contact(o)} - `; -}); -;// CONCATENATED MODULE: ./src/plugins/rosterview/templates/requesting_contact.js - - - -const tpl_requesting_contact = o => T`${o.display_name}`; - -/* harmony default export */ const requesting_contact = (o => T` - ${api.settings.get('allow_chat_pending_contacts') ? T`${tpl_requesting_contact(o)}` : tpl_requesting_contact(o)} - - `); -;// CONCATENATED MODULE: ./src/plugins/rosterview/templates/roster_item.js - - - - -/* harmony default export */ const roster_item = (o => { - const i18n_chat = __('Click to chat with %1$s (XMPP address: %2$s)', o.display_name, o.jid); - - const i18n_remove = __('Click to remove %1$s as a contact', o.display_name); - - return T` - - ${renderAvatar(o.getAvatarData())} - - ${o.num_unread ? T`${o.num_unread}` : ''} - ${o.display_name} - - ${api.settings.get('allow_contact_removal') ? T`` : ''}`; -}); -;// CONCATENATED MODULE: ./src/plugins/rosterview/contactview.js - - - - - - - -const contactview_u = core_converse.env.utils; -class contactview_RosterContact extends CustomElement { - static get properties() { - return { - model: { - type: Object - } - }; - } - - connectedCallback() { - super.connectedCallback(); - this.listenTo(this.model, "change", this.requestUpdate); - this.listenTo(this.model, "highlight", this.requestUpdate); - this.listenTo(this.model, 'vcard:change', this.requestUpdate); - } - - render() { - const ask = this.model.get('ask'); - const requesting = this.model.get('requesting'); - const subscription = this.model.get('subscription'); - const jid = this.model.get('jid'); - - if (ask === 'subscribe' || subscription === 'from') { - /* ask === 'subscribe' - * Means we have asked to subscribe to them. - * - * subscription === 'from' - * They are subscribed to use, but not vice versa. - * We assume that there is a pending subscription - * from us to them (otherwise we're in a state not - * supported by converse.js). - * - * So in both cases the user is a "pending" contact. - */ - const display_name = this.model.getDisplayName(); - return pending_contact(Object.assign(this.model.toJSON(), { - display_name, - 'openChat': ev => this.openChat(ev), - 'removeContact': ev => this.removeContact(ev) - })); - } else if (requesting === true) { - const display_name = this.model.getDisplayName(); - return requesting_contact(Object.assign(this.model.toJSON(), { - display_name, - 'openChat': ev => this.openChat(ev), - 'acceptRequest': ev => this.acceptRequest(ev), - 'declineRequest': ev => this.declineRequest(ev), - 'desc_accept': __("Click to accept the contact request from %1$s", display_name), - 'desc_decline': __("Click to decline the contact request from %1$s", display_name), - 'allow_chat_pending_contacts': api.settings.get('allow_chat_pending_contacts') - })); - } else if (subscription === 'both' || subscription === 'to' || contactview_u.isSameBareJID(jid, shared_converse.connection.jid)) { - return this.renderRosterItem(this.model); - } - } - - renderRosterItem(item) { - const STATUSES = { - 'dnd': __('This contact is busy'), - 'online': __('This contact is online'), - 'offline': __('This contact is offline'), - 'unavailable': __('This contact is unavailable'), - 'xa': __('This contact is away for an extended period'), - 'away': __('This contact is away') - }; - const show = item.presence.get('show') || 'offline'; - let status_icon; - - if (show === 'online') { - status_icon = 'fa fa-circle chat-status chat-status--online'; - } else if (show === 'away') { - status_icon = 'fa fa-circle chat-status chat-status--away'; - } else if (show === 'xa') { - status_icon = 'far fa-circle chat-status chat-status-xa'; - } else if (show === 'dnd') { - status_icon = 'fa fa-minus-circle chat-status chat-status--busy'; - } else { - status_icon = 'fa fa-times-circle chat-status chat-status--offline'; - } - - const display_name = item.getDisplayName(); - return roster_item(Object.assign(item.toJSON(), { - show, - display_name, - status_icon, - 'openChat': ev => this.openChat(ev), - 'removeContact': ev => this.removeContact(ev), - 'getAvatarData': () => this.getAvatarData(), - 'desc_status': STATUSES[show], - 'num_unread': item.get('num_unread') || 0 - })); - } - - getAvatarData() { - var _this$model$vcard, _this$model$vcard2; - - const image_type = ((_this$model$vcard = this.model.vcard) === null || _this$model$vcard === void 0 ? void 0 : _this$model$vcard.get('image_type')) || shared_converse.DEFAULT_IMAGE_TYPE; - const image_data = ((_this$model$vcard2 = this.model.vcard) === null || _this$model$vcard2 === void 0 ? void 0 : _this$model$vcard2.get('image')) || shared_converse.DEFAULT_IMAGE; - const image = "data:" + image_type + ";base64," + image_data; - return { - 'classes': 'avatar', - 'height': 30, - 'width': 30, - image - }; - } - - openChat(ev) { - var _ev$preventDefault; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault = ev.preventDefault) === null || _ev$preventDefault === void 0 ? void 0 : _ev$preventDefault.call(ev); - this.model.openChat(); - } - - removeContact(ev) { - var _ev$preventDefault2; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault2 = ev.preventDefault) === null || _ev$preventDefault2 === void 0 ? void 0 : _ev$preventDefault2.call(ev); - - if (!api.settings.get('allow_contact_removal')) { - return; - } - - if (!confirm(__("Are you sure you want to remove this contact?"))) { - return; - } - - try { - this.model.removeFromRoster(); - - if (this.model.collection) { - // The model might have already been removed as - // result of a roster push. - this.model.destroy(); - } - } catch (e) { - headless_log.error(e); - api.alert('error', __('Error'), [__('Sorry, there was an error while trying to remove %1$s as a contact.', this.model.getDisplayName())]); - } - } - - async acceptRequest(ev) { - var _ev$preventDefault3; - - ev === null || ev === void 0 ? void 0 : (_ev$preventDefault3 = ev.preventDefault) === null || _ev$preventDefault3 === void 0 ? void 0 : _ev$preventDefault3.call(ev); - await shared_converse.roster.sendContactAddIQ(this.model.get('jid'), this.model.getFullname(), []); - this.model.authorize().subscribe(); - } - - declineRequest(ev) { - if (ev && ev.preventDefault) { - ev.preventDefault(); - } - - const result = confirm(__("Are you sure you want to decline this contact request?")); - - if (result === true) { - this.model.unauthorize().destroy(); - } - - return this; - } - -} -api.elements.define('converse-roster-contact', contactview_RosterContact); -;// CONCATENATED MODULE: ./src/plugins/rosterview/templates/roster_filter.js - - -/* harmony default export */ const roster_filter = (o => { - const i18n_placeholder = __('Filter'); - - const title_contact_filter = __('Filter by contact name'); - - const title_group_filter = __('Filter by group name'); - - const title_status_filter = __('Filter by status'); - - const label_any = __('Any'); - - const label_unread_messages = __('Unread'); - - const label_online = __('Online'); - - const label_chatty = __('Chatty'); - - const label_busy = __('Busy'); - - const label_away = __('Away'); - - const label_xa = __('Extended Away'); - - const label_offline = __('Offline'); - - return T` -
    -
    -
    - - - -
    -
    - - - -
    - -
    -
    `; -}); -;// CONCATENATED MODULE: ./src/plugins/rosterview/filterview.js - - - - - - -const RosterFilter = Model.extend({ - initialize() { - this.set({ - 'filter_text': '', - 'filter_type': 'contacts', - 'chat_state': 'online' - }); - } - -}); -class RosterFilterView extends CustomElement { - constructor() { - super(); - this.initialize(); - } - - initialize() { - const model = new shared_converse.RosterFilter(); - model.id = `_converse.rosterfilter-${shared_converse.bare_jid}`; - initStorage(model, model.id); - this.model = model; - shared_converse.roster_filter = model; - this.liveFilter = lodash_es_debounce(() => { - this.model.save({ - 'filter_text': this.querySelector('.roster-filter').value - }); - }, 250); - this.listenTo(shared_converse, 'rosterContactsFetched', this.requestUpdate); - this.listenTo(shared_converse.presences, 'change:show', this.requestUpdate); - this.listenTo(shared_converse.roster, "add", this.requestUpdate); - this.listenTo(shared_converse.roster, "destroy", this.requestUpdate); - this.listenTo(shared_converse.roster, "remove", this.requestUpdate); - this.listenTo(this.model, 'change', this.dispatchUpdateEvent); - this.listenTo(this.model, 'change', this.requestUpdate); - this.model.fetch(); - } - - render() { - return roster_filter(Object.assign(this.model.toJSON(), { - visible: this.shouldBeVisible(), - changeChatStateFilter: ev => this.changeChatStateFilter(ev), - changeTypeFilter: ev => this.changeTypeFilter(ev), - clearFilter: ev => this.clearFilter(ev), - liveFilter: ev => this.liveFilter(ev), - submitFilter: ev => this.submitFilter(ev) - })); - } - - dispatchUpdateEvent() { - this.dispatchEvent(new CustomEvent('update', { - 'detail': this.model.changed - })); - } - - changeChatStateFilter(ev) { - ev && ev.preventDefault(); - this.model.save({ - 'chat_state': this.querySelector('.state-type').value - }); - } - - changeTypeFilter(ev) { - ev && ev.preventDefault(); - const type = ev.target.dataset.type; - - if (type === 'state') { - this.model.save({ - 'filter_type': type, - 'chat_state': this.querySelector('.state-type').value - }); - } else { - this.model.save({ - 'filter_type': type, - 'filter_text': this.querySelector('.roster-filter').value - }); - } - } - - submitFilter(ev) { - ev && ev.preventDefault(); - this.liveFilter(); - } - /** - * Returns true if the filter is enabled (i.e. if the user - * has added values to the filter). - * @private - * @method _converse.RosterFilterView#isActive - */ - - - isActive() { - return this.model.get('filter_type') === 'state' || this.model.get('filter_text'); - } - - shouldBeVisible() { - var _converse$roster; - - return ((_converse$roster = shared_converse.roster) === null || _converse$roster === void 0 ? void 0 : _converse$roster.length) >= 5 || this.isActive(); - } - - clearFilter(ev) { - ev && ev.preventDefault(); - this.model.save({ - 'filter_text': '' - }); - } - -} -api.elements.define('converse-roster-filter', RosterFilterView); -// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[3].use[3]!./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].use[1]!./node_modules/postcss-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].use[3]!./src/plugins/rosterview/styles/roster.scss -var styles_roster = __webpack_require__(74); -;// CONCATENATED MODULE: ./src/plugins/rosterview/styles/roster.scss - - - - - - - - - - - -var roster_options = {}; - -roster_options.styleTagTransform = (styleTagTransform_default()); -roster_options.setAttributes = (setAttributesWithoutAttributes_default()); - - roster_options.insert = insertBySelector_default().bind(null, "head"); - -roster_options.domAPI = (styleDomAPI_default()); -roster_options.insertStyleElement = (insertStyleElement_default()); - -var roster_update = injectStylesIntoStyleTag_default()(styles_roster/* default */.Z, roster_options); - - - - - /* harmony default export */ const rosterview_styles_roster = (styles_roster/* default */.Z && styles_roster/* default.locals */.Z.locals ? styles_roster/* default.locals */.Z.locals : undefined); - -;// CONCATENATED MODULE: ./src/plugins/rosterview/index.js -/** - * @copyright 2020, the Converse.js contributors - * @license Mozilla Public License (MPLv2) - */ - - - - - - - - - - -core_converse.plugins.add('converse-rosterview', { - dependencies: ["converse-roster", "converse-modal", "converse-chatboxviews"], - - initialize() { - api.settings.extend({ - 'autocomplete_add_contact': true, - 'allow_chat_pending_contacts': true, - 'allow_contact_removal': true, - 'hide_offline_users': false, - 'roster_groups': true, - 'xhr_user_search_url': null - }); - api.promises.add('rosterViewInitialized'); - shared_converse.RosterFilter = RosterFilter; - shared_converse.RosterFilterView = RosterFilterView; - shared_converse.RosterContactView = contactview_RosterContact; - /* -------- Event Handlers ----------- */ - - api.listen.on('chatBoxesInitialized', () => { - shared_converse.chatboxes.on('destroy', chatbox => highlightRosterItem(chatbox)); - - shared_converse.chatboxes.on('change:hidden', chatbox => highlightRosterItem(chatbox)); - }); - api.listen.on('afterTearDown', () => { - var _converse$rotergroups; - - return (_converse$rotergroups = shared_converse.rotergroups) === null || _converse$rotergroups === void 0 ? void 0 : _converse$rotergroups.off().reset(); - }); - } - -}); -;// CONCATENATED MODULE: ./src/converse.js -/** - * @description Converse.js (A browser based XMPP chat client) - * @copyright 2021, The Converse developers - * @license Mozilla Public License (MPLv2) - */ - - - - - - - -/* START: Removable plugins - * ------------------------ - * Any of the following plugin imports may be removed if the plugin is not needed - */ - - // Views for XEP-0048 Bookmarks - - // Renders standalone chat boxes for single user chat - - // The control box - - // Allows chat boxes to be resized by dragging them - - - - - // Allows chat boxes to be minimized - - // Views related to MUC - - - - - // XEP-0357 Push Notifications - - // XEP-0077 In-band registration - - // Show currently open chat rooms - - - - -/* END: Removable components */ - -shared_converse.CustomElement = CustomElement; -const initialize = core_converse.initialize; - -core_converse.initialize = function (settings, callback) { - if (Array.isArray(settings.whitelisted_plugins)) { - settings.whitelisted_plugins = settings.whitelisted_plugins.concat(VIEW_PLUGINS); - } else { - settings.whitelisted_plugins = VIEW_PLUGINS; - } - - return initialize(settings, callback); -}; - -/* harmony default export */ const src_converse = (core_converse); - -/***/ }), - -/***/ 6300: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 3742: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 7904: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 4639: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 6220: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 9107: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 7581: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 6752: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 115: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 8859: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 7926: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 1557: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 2490: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 679: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 1107: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 74: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 8481: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 8269: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 9796: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 5223: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 7991: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 7415: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 1065: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 3735: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 3543: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 4452: -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7620); -/* harmony import */ var _node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1246); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_cssWithMappingToString_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, "", "",{"version":3,"sources":[],"names":[],"mappings":"","sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ 9434: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var map = { - "./af.js": [ - 7905, - 9210 - ], - "./am.js": [ - 2067, - 5073 - ], - "./ar-dz.js": [ - 7171, - 9406 - ], - "./ar-kw.js": [ - 6712, - 9897 - ], - "./ar-ly.js": [ - 4198, - 3521 - ], - "./ar-ma.js": [ - 5390, - 5313 - ], - "./ar-sa.js": [ - 8916, - 485 - ], - "./ar-tn.js": [ - 5507, - 8040 - ], - "./ar.js": [ - 8817, - 6755 - ], - "./az.js": [ - 978, - 4963 - ], - "./be.js": [ - 8413, - 9478 - ], - "./bg.js": [ - 7575, - 578 - ], - "./bi.js": [ - 7186, - 2984 - ], - "./bm.js": [ - 7646, - 2263 - ], - "./bn.js": [ - 2760, - 280 - ], - "./bo.js": [ - 10, - 9950 - ], - "./br.js": [ - 5476, - 760 - ], - "./bs.js": [ - 8581, - 9833 - ], - "./ca.js": [ - 545, - 102 - ], - "./cs.js": [ - 7831, - 7400 - ], - "./cv.js": [ - 4598, - 4481 - ], - "./cy.js": [ - 5401, - 6740 - ], - "./da.js": [ - 3499, - 2548 - ], - "./de-at.js": [ - 4026, - 7175 - ], - "./de-ch.js": [ - 7423, - 1679 - ], - "./de.js": [ - 1857, - 52 - ], - "./dv.js": [ - 8027, - 5569 - ], - "./el.js": [ - 4542, - 1606 - ], - "./en-au.js": [ - 8781, - 5485 - ], - "./en-ca.js": [ - 7867, - 4035 - ], - "./en-gb.js": [ - 4147, - 6031 - ], - "./en-ie.js": [ - 5454, - 8129 - ], - "./en-il.js": [ - 7199, - 3463 - ], - "./en-in.js": [ - 8109, - 6898 - ], - "./en-nz.js": [ - 9102, - 8547 - ], - "./en-sg.js": [ - 8113, - 1735 - ], - "./en-tt.js": [ - 5859, - 6105 - ], - "./en.js": [ - 1606, - 535 - ], - "./eo.js": [ - 5545, - 5121 - ], - "./es-do.js": [ - 5839, - 8758 - ], - "./es-pr.js": [ - 3979, - 911 - ], - "./es-us.js": [ - 8624, - 3208 - ], - "./es.js": [ - 4153, - 3411 - ], - "./et.js": [ - 7754, - 4153 - ], - "./eu.js": [ - 2697, - 1396 - ], - "./fa.js": [ - 9068, - 5544 - ], - "./fi.js": [ - 6587, - 2130 - ], - "./fo.js": [ - 26, - 8745 - ], - "./fr-ca.js": [ - 3026, - 7363 - ], - "./fr-ch.js": [ - 2246, - 7952 - ], - "./fr.js": [ - 8278, - 1910 - ], - "./fy.js": [ - 4172, - 6376 - ], - "./ga.js": [ - 9691, - 688 - ], - "./gd.js": [ - 2713, - 5050 - ], - "./gl.js": [ - 6212, - 5818 - ], - "./gom-latn.js": [ - 5516, - 825 - ], - "./gu.js": [ - 945, - 3623 - ], - "./he.js": [ - 7346, - 9372 - ], - "./hi.js": [ - 802, - 8010 - ], - "./hr.js": [ - 1804, - 7419 - ], - "./ht.js": [ - 8259, - 5822 - ], - "./hu.js": [ - 3650, - 8214 - ], - "./hy-am.js": [ - 4800, - 5407 - ], - "./id.js": [ - 5275, - 9513 - ], - "./is.js": [ - 4039, - 1194 - ], - "./it-ch.js": [ - 8846, - 6010 - ], - "./it.js": [ - 6792, - 1880 - ], - "./ja.js": [ - 4679, - 1107 - ], - "./jv.js": [ - 4770, - 4305 - ], - "./ka.js": [ - 7564, - 5186 - ], - "./kk.js": [ - 7316, - 5206 - ], - "./km.js": [ - 1209, - 2475 - ], - "./kn.js": [ - 6713, - 7523 - ], - "./ko.js": [ - 9735, - 3446 - ], - "./ku.js": [ - 5121, - 7024 - ], - "./ky.js": [ - 5901, - 5055 - ], - "./lb.js": [ - 4565, - 5215 - ], - "./lo.js": [ - 8525, - 1204 - ], - "./lt.js": [ - 1305, - 7899 - ], - "./lv.js": [ - 9629, - 631 - ], - "./me.js": [ - 913, - 145 - ], - "./mi.js": [ - 3389, - 7454 - ], - "./mk.js": [ - 5524, - 4951 - ], - "./ml.js": [ - 5321, - 7679 - ], - "./mn.js": [ - 8082, - 8618 - ], - "./mr.js": [ - 3838, - 5600 - ], - "./ms-my.js": [ - 5435, - 882 - ], - "./ms.js": [ - 1525, - 9095 - ], - "./mt.js": [ - 2680, - 9665 - ], - "./my.js": [ - 1390, - 5166 - ], - "./nb.js": [ - 192, - 646 - ], - "./ne.js": [ - 9534, - 9030 - ], - "./nl-be.js": [ - 307, - 3155 - ], - "./nl.js": [ - 808, - 1520 - ], - "./nn.js": [ - 4644, - 7050 - ], - "./oc-lnc.js": [ - 9099, - 7203 - ], - "./pa-in.js": [ - 7117, - 5850 - ], - "./pl.js": [ - 5406, - 1211 - ], - "./pt-br.js": [ - 1291, - 5274 - ], - "./pt.js": [ - 402, - 265 - ], - "./ro.js": [ - 4491, - 8022 - ], - "./ru.js": [ - 1187, - 559 - ], - "./rw.js": [ - 8978, - 3221 - ], - "./sd.js": [ - 454, - 1298 - ], - "./se.js": [ - 1708, - 1942 - ], - "./si.js": [ - 5334, - 9333 - ], - "./sk.js": [ - 7506, - 6783 - ], - "./sl.js": [ - 7608, - 9625 - ], - "./sq.js": [ - 2402, - 8603 - ], - "./sr-cyrl.js": [ - 7786, - 3435 - ], - "./sr.js": [ - 8407, - 7390 - ], - "./ss.js": [ - 2068, - 9238 - ], - "./sv-fi.js": [ - 1057, - 9997 - ], - "./sv.js": [ - 4316, - 9652 - ], - "./sw.js": [ - 9716, - 9733 - ], - "./ta.js": [ - 1541, - 7645 - ], - "./te.js": [ - 5649, - 7714 - ], - "./tet.js": [ - 6539, - 555 - ], - "./tg.js": [ - 222, - 2446 - ], - "./th.js": [ - 4805, - 1729 - ], - "./tk.js": [ - 2679, - 5256 - ], - "./tl-ph.js": [ - 821, - 9443 - ], - "./tlh.js": [ - 9201, - 2814 - ], - "./tr.js": [ - 8273, - 8665 - ], - "./tzl.js": [ - 4837, - 2843 - ], - "./tzm-latn.js": [ - 7003, - 3933 - ], - "./tzm.js": [ - 2165, - 4342 - ], - "./ug-cn.js": [ - 810, - 6890 - ], - "./uk.js": [ - 6638, - 1619 - ], - "./ur.js": [ - 9542, - 9568 - ], - "./uz-latn.js": [ - 3089, - 1110 - ], - "./uz.js": [ - 3380, - 3153 - ], - "./vi.js": [ - 2718, - 8073 - ], - "./x-pseudo.js": [ - 6316, - 4423 - ], - "./yo.js": [ - 2863, - 8692 - ], - "./zh-cn.js": [ - 4385, - 9630 - ], - "./zh-hk.js": [ - 4338, - 3755 - ], - "./zh-tw.js": [ - 1208, - 6776 - ], - "./zh.js": [ - 8383, - 8458 - ] -}; -function webpackAsyncContext(req) { - if(!__webpack_require__.o(map, req)) { - return Promise.resolve().then(() => { - var e = new Error("Cannot find module '" + req + "'"); - e.code = 'MODULE_NOT_FOUND'; - throw e; - }); - } - - var ids = map[req], id = ids[0]; - return __webpack_require__.e(ids[1]).then(() => { - return __webpack_require__.t(id, 7); - }); -} -webpackAsyncContext.keys = () => (Object.keys(map)); -webpackAsyncContext.id = 9434; -module.exports = webpackAsyncContext; - -/***/ }), - -/***/ 3379: -/***/ ((module) => { - -"use strict"; - - -var stylesInDom = []; - -function getIndexByIdentifier(identifier) { - var result = -1; - - for (var i = 0; i < stylesInDom.length; i++) { - if (stylesInDom[i].identifier === identifier) { - result = i; - break; - } - } - - return result; -} - -function modulesToDom(list, options) { - var idCountMap = {}; - var identifiers = []; - - for (var i = 0; i < list.length; i++) { - var item = list[i]; - var id = options.base ? item[0] + options.base : item[0]; - var count = idCountMap[id] || 0; - var identifier = "".concat(id, " ").concat(count); - idCountMap[id] = count + 1; - var index = getIndexByIdentifier(identifier); - var obj = { - css: item[1], - media: item[2], - sourceMap: item[3] - }; - - if (index !== -1) { - stylesInDom[index].references++; - stylesInDom[index].updater(obj); - } else { - stylesInDom.push({ - identifier: identifier, - updater: addStyle(obj, options), - references: 1 - }); - } - - identifiers.push(identifier); - } - - return identifiers; -} - -function addStyle(obj, options) { - var api = options.domAPI(options); - api.update(obj); - return function updateStyle(newObj) { - if (newObj) { - if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) { - return; - } - - api.update(obj = newObj); - } else { - api.remove(); - } - }; -} - -module.exports = function (list, options) { - options = options || {}; - list = list || []; - var lastIdentifiers = modulesToDom(list, options); - return function update(newList) { - newList = newList || []; - - for (var i = 0; i < lastIdentifiers.length; i++) { - var identifier = lastIdentifiers[i]; - var index = getIndexByIdentifier(identifier); - stylesInDom[index].references--; - } - - var newLastIdentifiers = modulesToDom(newList, options); - - for (var _i = 0; _i < lastIdentifiers.length; _i++) { - var _identifier = lastIdentifiers[_i]; - - var _index = getIndexByIdentifier(_identifier); - - if (stylesInDom[_index].references === 0) { - stylesInDom[_index].updater(); - - stylesInDom.splice(_index, 1); - } - } - - lastIdentifiers = newLastIdentifiers; - }; -}; - -/***/ }), - -/***/ 569: -/***/ ((module) => { - -"use strict"; - - -var memo = {}; -/* istanbul ignore next */ - -function getTarget(target) { - if (typeof memo[target] === "undefined") { - var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself - - if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { - try { - // This will throw an exception if access to iframe is blocked - // due to cross-origin restrictions - styleTarget = styleTarget.contentDocument.head; - } catch (e) { - // istanbul ignore next - styleTarget = null; - } - } - - memo[target] = styleTarget; - } - - return memo[target]; -} -/* istanbul ignore next */ - - -function insertBySelector(insert, style) { - var target = getTarget(insert); - - if (!target) { - throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); - } - - target.appendChild(style); -} - -module.exports = insertBySelector; - -/***/ }), - -/***/ 9216: -/***/ ((module) => { - -"use strict"; - - -/* istanbul ignore next */ -function insertStyleElement(options) { - var style = document.createElement("style"); - options.setAttributes(style, options.attributes); - options.insert(style); - return style; -} - -module.exports = insertStyleElement; - -/***/ }), - -/***/ 3565: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -"use strict"; - - -/* istanbul ignore next */ -function setAttributesWithoutAttributes(style) { - var nonce = true ? __webpack_require__.nc : 0; - - if (nonce) { - style.setAttribute("nonce", nonce); - } -} - -module.exports = setAttributesWithoutAttributes; - -/***/ }), - -/***/ 7795: -/***/ ((module) => { - -"use strict"; - - -/* istanbul ignore next */ -function apply(style, options, obj) { - var css = obj.css; - var media = obj.media; - var sourceMap = obj.sourceMap; - - if (media) { - style.setAttribute("media", media); - } else { - style.removeAttribute("media"); - } - - if (sourceMap && typeof btoa !== "undefined") { - css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */"); - } // For old IE - - /* istanbul ignore if */ - - - options.styleTagTransform(css, style); -} - -function removeStyleElement(style) { - // istanbul ignore if - if (style.parentNode === null) { - return false; - } - - style.parentNode.removeChild(style); -} -/* istanbul ignore next */ - - -function domAPI(options) { - var style = options.insertStyleElement(options); - return { - update: function update(obj) { - apply(style, options, obj); - }, - remove: function remove() { - removeStyleElement(style); - } - }; -} - -module.exports = domAPI; - -/***/ }), - -/***/ 4589: -/***/ ((module) => { - -"use strict"; - - -/* istanbul ignore next */ -function styleTagTransform(css, style) { - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - while (style.firstChild) { - style.removeChild(style.firstChild); - } - - style.appendChild(document.createTextNode(css)); - } -} - -module.exports = styleTagTransform; - -/***/ }), - -/***/ 7521: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var map = { - "./af/LC_MESSAGES/converse.po": [ - 2866, - 5830 - ], - "./ar/LC_MESSAGES/converse.po": [ - 7693, - 4469 - ], - "./bg/LC_MESSAGES/converse.po": [ - 5638, - 2551 - ], - "./ca/LC_MESSAGES/converse.po": [ - 6124, - 1553 - ], - "./cs/LC_MESSAGES/converse.po": [ - 4283, - 5301 - ], - "./da/LC_MESSAGES/converse.po": [ - 8135, - 1163 - ], - "./de/LC_MESSAGES/converse.po": [ - 254, - 2895 - ], - "./el/LC_MESSAGES/converse.po": [ - 8778, - 5524 - ], - "./eo/LC_MESSAGES/converse.po": [ - 4111, - 2433 - ], - "./es/LC_MESSAGES/converse.po": [ - 3516, - 8269 - ], - "./eu/LC_MESSAGES/converse.po": [ - 6160, - 3103 - ], - "./fa/LC_MESSAGES/converse.po": [ - 7167, - 321 - ], - "./fi/LC_MESSAGES/converse.po": [ - 5819, - 7618 - ], - "./fr/LC_MESSAGES/converse.po": [ - 7500, - 5129 - ], - "./gl/LC_MESSAGES/converse.po": [ - 8429, - 777 - ], - "./he/LC_MESSAGES/converse.po": [ - 2233, - 4363 - ], - "./hi/LC_MESSAGES/converse.po": [ - 7785, - 4468 - ], - "./hu/LC_MESSAGES/converse.po": [ - 2325, - 6239 - ], - "./id/LC_MESSAGES/converse.po": [ - 4938, - 6678 - ], - "./it/LC_MESSAGES/converse.po": [ - 2755, - 3719 - ], - "./ja/LC_MESSAGES/converse.po": [ - 2693, - 6249 - ], - "./lt/LC_MESSAGES/converse.po": [ - 3547, - 513 - ], - "./mr/LC_MESSAGES/converse.po": [ - 2260, - 1784 - ], - "./nb/LC_MESSAGES/converse.po": [ - 9701, - 473 - ], - "./nl/LC_MESSAGES/converse.po": [ - 3175, - 2473 - ], - "./nl_BE/LC_MESSAGES/converse.po": [ - 658, - 8131 - ], - "./oc/LC_MESSAGES/converse.po": [ - 506, - 5500 - ], - "./pl/LC_MESSAGES/converse.po": [ - 275, - 3606 - ], - "./pt/LC_MESSAGES/converse.po": [ - 8300, - 6227 - ], - "./pt_BR/LC_MESSAGES/converse.po": [ - 7606, - 1455 - ], - "./ro/LC_MESSAGES/converse.po": [ - 6899, - 3539 - ], - "./ru/LC_MESSAGES/converse.po": [ - 499, - 7917 - ], - "./sv/LC_MESSAGES/converse.po": [ - 164, - 8859 - ], - "./th/LC_MESSAGES/converse.po": [ - 4307, - 457 - ], - "./tr/LC_MESSAGES/converse.po": [ - 5882, - 4195 - ], - "./uk/LC_MESSAGES/converse.po": [ - 6264, - 7979 - ], - "./vi/LC_MESSAGES/converse.po": [ - 1937, - 2110 - ], - "./zh_CN/LC_MESSAGES/converse.po": [ - 6592, - 3325 - ], - "./zh_TW/LC_MESSAGES/converse.po": [ - 1288, - 1458 - ] -}; -function webpackAsyncContext(req) { - if(!__webpack_require__.o(map, req)) { - return Promise.resolve().then(() => { - var e = new Error("Cannot find module '" + req + "'"); - e.code = 'MODULE_NOT_FOUND'; - throw e; - }); - } - - var ids = map[req], id = ids[0]; - return __webpack_require__.e(ids[1]).then(() => { - return __webpack_require__.t(id, 3); - }); -} -webpackAsyncContext.keys = () => (Object.keys(map)); -webpackAsyncContext.id = 7521; -module.exports = webpackAsyncContext; - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ id: moduleId, -/******/ loaded: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.loaded = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = __webpack_modules__; -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/compat get default export */ -/******/ (() => { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = (module) => { -/******/ var getter = module && module.__esModule ? -/******/ () => (module['default']) : -/******/ () => (module); -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/create fake namespace object */ -/******/ (() => { -/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); -/******/ var leafPrototypes; -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 16: return value when it's Promise-like -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = this(value); -/******/ if(mode & 8) return value; -/******/ if(typeof value === 'object' && value) { -/******/ if((mode & 4) && value.__esModule) return value; -/******/ if((mode & 16) && typeof value.then === 'function') return value; -/******/ } -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ var def = {}; -/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; -/******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { -/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); -/******/ } -/******/ def['default'] = () => (value); -/******/ __webpack_require__.d(ns, def); -/******/ return ns; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/ensure chunk */ -/******/ (() => { -/******/ __webpack_require__.f = {}; -/******/ // This file contains only the entry chunk. -/******/ // The chunk loading function for additional chunks -/******/ __webpack_require__.e = (chunkId) => { -/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { -/******/ __webpack_require__.f[key](chunkId, promises); -/******/ return promises; -/******/ }, [])); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/get javascript chunk filename */ -/******/ (() => { -/******/ // This function allow to reference async chunks -/******/ __webpack_require__.u = (chunkId) => { -/******/ // return url for filenames based on template -/******/ return "" + {"52":"locales/dayjs/de-js","102":"locales/dayjs/ca-js","145":"locales/dayjs/me-js","265":"locales/dayjs/pt-js","280":"locales/dayjs/bn-js","321":"locales/fa-LC_MESSAGES-converse-po","457":"locales/th-LC_MESSAGES-converse-po","473":"locales/nb-LC_MESSAGES-converse-po","485":"locales/dayjs/ar-sa-js","513":"locales/lt-LC_MESSAGES-converse-po","535":"locales/dayjs/en-js","555":"locales/dayjs/tet-js","559":"locales/dayjs/ru-js","578":"locales/dayjs/bg-js","631":"locales/dayjs/lv-js","646":"locales/dayjs/nb-js","688":"locales/dayjs/ga-js","760":"locales/dayjs/br-js","777":"locales/gl-LC_MESSAGES-converse-po","825":"locales/dayjs/gom-latn-js","882":"locales/dayjs/ms-my-js","911":"locales/dayjs/es-pr-js","1107":"locales/dayjs/ja-js","1110":"locales/dayjs/uz-latn-js","1163":"locales/da-LC_MESSAGES-converse-po","1194":"locales/dayjs/is-js","1204":"locales/dayjs/lo-js","1211":"locales/dayjs/pl-js","1298":"locales/dayjs/sd-js","1396":"locales/dayjs/eu-js","1455":"locales/pt_BR-LC_MESSAGES-converse-po","1458":"locales/zh_TW-LC_MESSAGES-converse-po","1520":"locales/dayjs/nl-js","1553":"locales/ca-LC_MESSAGES-converse-po","1606":"locales/dayjs/el-js","1619":"locales/dayjs/uk-js","1679":"locales/dayjs/de-ch-js","1729":"locales/dayjs/th-js","1735":"locales/dayjs/en-sg-js","1784":"locales/mr-LC_MESSAGES-converse-po","1880":"locales/dayjs/it-js","1910":"locales/dayjs/fr-js","1942":"locales/dayjs/se-js","2110":"locales/vi-LC_MESSAGES-converse-po","2130":"locales/dayjs/fi-js","2263":"locales/dayjs/bm-js","2433":"locales/eo-LC_MESSAGES-converse-po","2446":"locales/dayjs/tg-js","2473":"locales/nl-LC_MESSAGES-converse-po","2475":"locales/dayjs/km-js","2548":"locales/dayjs/da-js","2551":"locales/bg-LC_MESSAGES-converse-po","2814":"locales/dayjs/tlh-js","2843":"locales/dayjs/tzl-js","2895":"locales/de-LC_MESSAGES-converse-po","2984":"locales/dayjs/bi-js","3103":"locales/eu-LC_MESSAGES-converse-po","3153":"locales/dayjs/uz-js","3155":"locales/dayjs/nl-be-js","3208":"locales/dayjs/es-us-js","3221":"locales/dayjs/rw-js","3325":"locales/zh_CN-LC_MESSAGES-converse-po","3411":"locales/dayjs/es-js","3435":"locales/dayjs/sr-cyrl-js","3446":"locales/dayjs/ko-js","3463":"locales/dayjs/en-il-js","3521":"locales/dayjs/ar-ly-js","3539":"locales/ro-LC_MESSAGES-converse-po","3606":"locales/pl-LC_MESSAGES-converse-po","3623":"locales/dayjs/gu-js","3719":"locales/it-LC_MESSAGES-converse-po","3755":"locales/dayjs/zh-hk-js","3933":"locales/dayjs/tzm-latn-js","4035":"locales/dayjs/en-ca-js","4153":"locales/dayjs/et-js","4195":"locales/tr-LC_MESSAGES-converse-po","4305":"locales/dayjs/jv-js","4342":"locales/dayjs/tzm-js","4363":"locales/he-LC_MESSAGES-converse-po","4423":"locales/dayjs/x-pseudo-js","4468":"locales/hi-LC_MESSAGES-converse-po","4469":"locales/ar-LC_MESSAGES-converse-po","4481":"locales/dayjs/cv-js","4610":"emojis","4951":"locales/dayjs/mk-js","4963":"locales/dayjs/az-js","5050":"locales/dayjs/gd-js","5055":"locales/dayjs/ky-js","5073":"locales/dayjs/am-js","5121":"locales/dayjs/eo-js","5129":"locales/fr-LC_MESSAGES-converse-po","5166":"locales/dayjs/my-js","5186":"locales/dayjs/ka-js","5206":"locales/dayjs/kk-js","5215":"locales/dayjs/lb-js","5256":"locales/dayjs/tk-js","5274":"locales/dayjs/pt-br-js","5301":"locales/cs-LC_MESSAGES-converse-po","5313":"locales/dayjs/ar-ma-js","5407":"locales/dayjs/hy-am-js","5485":"locales/dayjs/en-au-js","5500":"locales/oc-LC_MESSAGES-converse-po","5524":"locales/el-LC_MESSAGES-converse-po","5544":"locales/dayjs/fa-js","5569":"locales/dayjs/dv-js","5600":"locales/dayjs/mr-js","5818":"locales/dayjs/gl-js","5822":"locales/dayjs/ht-js","5830":"locales/af-LC_MESSAGES-converse-po","5850":"locales/dayjs/pa-in-js","6010":"locales/dayjs/it-ch-js","6031":"locales/dayjs/en-gb-js","6105":"locales/dayjs/en-tt-js","6227":"locales/pt-LC_MESSAGES-converse-po","6239":"locales/hu-LC_MESSAGES-converse-po","6249":"locales/ja-LC_MESSAGES-converse-po","6376":"locales/dayjs/fy-js","6678":"locales/id-LC_MESSAGES-converse-po","6740":"locales/dayjs/cy-js","6755":"locales/dayjs/ar-js","6776":"locales/dayjs/zh-tw-js","6783":"locales/dayjs/sk-js","6890":"locales/dayjs/ug-cn-js","6898":"locales/dayjs/en-in-js","7024":"locales/dayjs/ku-js","7050":"locales/dayjs/nn-js","7175":"locales/dayjs/de-at-js","7203":"locales/dayjs/oc-lnc-js","7363":"locales/dayjs/fr-ca-js","7390":"locales/dayjs/sr-js","7400":"locales/dayjs/cs-js","7419":"locales/dayjs/hr-js","7454":"locales/dayjs/mi-js","7523":"locales/dayjs/kn-js","7618":"locales/fi-LC_MESSAGES-converse-po","7645":"locales/dayjs/ta-js","7679":"locales/dayjs/ml-js","7714":"locales/dayjs/te-js","7899":"locales/dayjs/lt-js","7917":"locales/ru-LC_MESSAGES-converse-po","7952":"locales/dayjs/fr-ch-js","7979":"locales/uk-LC_MESSAGES-converse-po","8010":"locales/dayjs/hi-js","8022":"locales/dayjs/ro-js","8040":"locales/dayjs/ar-tn-js","8073":"locales/dayjs/vi-js","8129":"locales/dayjs/en-ie-js","8131":"locales/nl_BE-LC_MESSAGES-converse-po","8214":"locales/dayjs/hu-js","8269":"locales/es-LC_MESSAGES-converse-po","8458":"locales/dayjs/zh-js","8547":"locales/dayjs/en-nz-js","8603":"locales/dayjs/sq-js","8618":"locales/dayjs/mn-js","8665":"locales/dayjs/tr-js","8692":"locales/dayjs/yo-js","8745":"locales/dayjs/fo-js","8758":"locales/dayjs/es-do-js","8859":"locales/sv-LC_MESSAGES-converse-po","9030":"locales/dayjs/ne-js","9095":"locales/dayjs/ms-js","9210":"locales/dayjs/af-js","9238":"locales/dayjs/ss-js","9333":"locales/dayjs/si-js","9372":"locales/dayjs/he-js","9406":"locales/dayjs/ar-dz-js","9443":"locales/dayjs/tl-ph-js","9478":"locales/dayjs/be-js","9513":"locales/dayjs/id-js","9568":"locales/dayjs/ur-js","9625":"locales/dayjs/sl-js","9630":"locales/dayjs/zh-cn-js","9652":"locales/dayjs/sv-js","9665":"locales/dayjs/mt-js","9733":"locales/dayjs/sw-js","9833":"locales/dayjs/bs-js","9897":"locales/dayjs/ar-kw-js","9950":"locales/dayjs/bo-js","9997":"locales/dayjs/sv-fi-js"}[chunkId] + ".js"; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/get mini-css chunk filename */ -/******/ (() => { -/******/ // This function allow to reference all chunks -/******/ __webpack_require__.miniCssF = (chunkId) => { -/******/ // return url for filenames based on template -/******/ return undefined; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/get mini-css chunk filename */ -/******/ (() => { -/******/ // This function allow to reference all chunks -/******/ __webpack_require__.miniCssF = (chunkId) => { -/******/ // return url for filenames based on template -/******/ return undefined; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/global */ -/******/ (() => { -/******/ __webpack_require__.g = (function() { -/******/ if (typeof globalThis === 'object') return globalThis; -/******/ try { -/******/ return this || new Function('return this')(); -/******/ } catch (e) { -/******/ if (typeof window === 'object') return window; -/******/ } -/******/ })(); -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/load script */ -/******/ (() => { -/******/ var inProgress = {}; -/******/ var dataWebpackPrefix = "converse.js:"; -/******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key, chunkId) => { -/******/ if(inProgress[url]) { inProgress[url].push(done); return; } -/******/ var script, needAttach; -/******/ if(key !== undefined) { -/******/ var scripts = document.getElementsByTagName("script"); -/******/ for(var i = 0; i < scripts.length; i++) { -/******/ var s = scripts[i]; -/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; } -/******/ } -/******/ } -/******/ if(!script) { -/******/ needAttach = true; -/******/ script = document.createElement('script'); -/******/ -/******/ script.charset = 'utf-8'; -/******/ script.timeout = 120; -/******/ if (__webpack_require__.nc) { -/******/ script.setAttribute("nonce", __webpack_require__.nc); -/******/ } -/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key); -/******/ script.src = url; -/******/ } -/******/ inProgress[url] = [done]; -/******/ var onScriptComplete = (prev, event) => { -/******/ // avoid mem leaks in IE. -/******/ script.onerror = script.onload = null; -/******/ clearTimeout(timeout); -/******/ var doneFns = inProgress[url]; -/******/ delete inProgress[url]; -/******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => (fn(event))); -/******/ if(prev) return prev(event); -/******/ } -/******/ ; -/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); -/******/ script.onerror = onScriptComplete.bind(null, script.onerror); -/******/ script.onload = onScriptComplete.bind(null, script.onload); -/******/ needAttach && document.head.appendChild(script); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/node module decorator */ -/******/ (() => { -/******/ __webpack_require__.nmd = (module) => { -/******/ module.paths = []; -/******/ if (!module.children) module.children = []; -/******/ return module; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/publicPath */ -/******/ (() => { -/******/ __webpack_require__.p = "/dist/"; -/******/ })(); -/******/ -/******/ /* webpack/runtime/jsonp chunk loading */ -/******/ (() => { -/******/ // no baseURI -/******/ -/******/ // object to store loaded and loading chunks -/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded -/******/ var installedChunks = { -/******/ 179: 0 -/******/ }; -/******/ -/******/ __webpack_require__.f.j = (chunkId, promises) => { -/******/ // JSONP chunk loading for javascript -/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; -/******/ if(installedChunkData !== 0) { // 0 means "already installed". -/******/ -/******/ // a Promise means "currently loading". -/******/ if(installedChunkData) { -/******/ promises.push(installedChunkData[2]); -/******/ } else { -/******/ if(true) { // all chunks have JS -/******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); -/******/ promises.push(installedChunkData[2] = promise); -/******/ -/******/ // start chunk loading -/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId); -/******/ // create error before stack unwound to get useful stacktrace later -/******/ var error = new Error(); -/******/ var loadingEnded = (event) => { -/******/ if(__webpack_require__.o(installedChunks, chunkId)) { -/******/ installedChunkData = installedChunks[chunkId]; -/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined; -/******/ if(installedChunkData) { -/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); -/******/ var realSrc = event && event.target && event.target.src; -/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; -/******/ error.name = 'ChunkLoadError'; -/******/ error.type = errorType; -/******/ error.request = realSrc; -/******/ installedChunkData[1](error); -/******/ } -/******/ } -/******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); -/******/ } else installedChunks[chunkId] = 0; -/******/ } -/******/ } -/******/ }; -/******/ -/******/ // no prefetching -/******/ -/******/ // no preloaded -/******/ -/******/ // no HMR -/******/ -/******/ // no HMR manifest -/******/ -/******/ // no on chunks loaded -/******/ -/******/ // install a JSONP callback for chunk loading -/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime] = data; -/******/ // add "moreModules" to the modules object, -/******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0; -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) var result = runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ for(;i < chunkIds.length; i++) { -/******/ chunkId = chunkIds[i]; -/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ installedChunks[chunkId][0](); -/******/ } -/******/ installedChunks[chunkIds[i]] = 0; -/******/ } -/******/ -/******/ } -/******/ -/******/ var chunkLoadingGlobal = self["webpackChunkconverse_js"] = self["webpackChunkconverse_js"] || []; -/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); -/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ })(); -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be in strict mode. -(() => { -"use strict"; -// Converse.js -// https://conversejs.org -// -// Copyright (c) 2020, the Converse.js contributors -// Licensed under the Mozilla Public License (MPLv2) -// -// Webpack entry file -// -// The purpose of this file is to provide an initial temporary public API -// (window.converse) for **before** the rest of converse.js is loaded so -// that we can set the __webpack_public_path__ global variable. -// -// Once the rest converse.js has been loaded, window.converse will be replaced -// with the full-fledged public API. -const plugins = {}; -const converse = { - plugins: { - add(name, plugin) { - if (plugins[name] !== undefined) { - throw new TypeError(`Error: plugin with name "${name}" has already been ` + 'registered!'); - } - - plugins[name] = plugin; - } - - }, - - initialize(settings = {}) { - converse.load(settings).initialize(settings); - }, - - /** - * Public API method which explicitly loads Converse and allows you the - * possibility to pass in configuration settings which need to be defined - * before loading. Currently this is only the [assets_path](https://conversejs.org/docs/html/configuration.html#assets_path) - * setting. - * - * If not called explicitly, this method will be called implicitly once - * {@link converse.initialize} is called. - * - * In most cases, you probably don't need to explicitly call this method, - * however, until converse.js has been loaded you won't have access to the - * utility methods and globals exposed via {@link converse.env}. So if you - * need to access `converse.env` outside of any plugins and before - * `converse.initialize` has been called, then you need to call - * `converse.load` first. - * - * @memberOf converse - * @method load - * @param {object} settings A map of configuration-settings that are needed at load time. - * @example - * converse.load({assets_path: '/path/to/assets/'}); - */ - load(settings = {}) { - if (settings.assets_path) { - __webpack_require__.p = settings.assets_path; // eslint-disable-line no-undef - } - - __webpack_require__(6387); - - Object.keys(plugins).forEach(name => converse.plugins.add(name, plugins[name])); - return converse; - } - -}; -window.converse = converse; -/** - * Once Converse.js has loaded, it'll dispatch a custom event with the name `converse-loaded`. - * You can listen for this event in order to be informed as soon as converse.js has been - * loaded and parsed, which would mean it's safe to call `converse.initialize`. - * @event converse-loaded - * @example window.addEventListener('converse-loaded', () => converse.initialize()); - */ - -const ev = new CustomEvent('converse-loaded', { - 'detail': { - converse - } -}); -window.dispatchEvent(ev); -/* unused harmony default export */ var __WEBPACK_DEFAULT_EXPORT__ = ((/* unused pure expression or super */ null && (converse))); -})(); - -/******/ })() -; -//# sourceMappingURL=converse.js.map \ No newline at end of file diff --git a/sources/dist/converse.min.css b/sources/dist/converse.min.css index 518c730..923f53e 100644 --- a/sources/dist/converse.min.css +++ b/sources/dist/converse.min.css @@ -4,32 +4,40 @@ * * Copyright (c) 2013-2021, JC Brand * Licensed under the Mozilla Public License - */@font-face{font-family:Baumans;font-style:normal;font-weight:400;src:local("Baumans Regular"),local("Baumans-Regular"),url(webfonts/baumans.ttf) format("truetype")}@font-face{font-family:Muli;font-style:normal;font-weight:400;src:local("Muli Regular"),local("Muli-Regular"),url(webfonts/muli.ttf) format("truetype")}@font-face{font-family:ConverseFontAwesomeBrands;font-style:normal;font-weight:400;src:url(webfonts/fa-brands-400.eot);src:url(webfonts/fa-brands-400-.eot#iefix) format("embedded-opentype"),url(webfonts/fa-brands-400.woff2) format("woff2"),url(webfonts/fa-brands-400.woff) format("woff"),url(webfonts/fa-brands-400.ttf) format("truetype"),url(webfonts/fa-brands-400.svg#fontawesome) format("svg")}@font-face{font-family:ConverseFontAwesomeRegular;font-style:normal;font-weight:400;src:url(webfonts/fa-regular-400.eot);src:url(webfonts/fa-regular-400-.eot#iefix) format("embedded-opentype"),url(webfonts/fa-regular-400.woff2) format("woff2"),url(webfonts/fa-regular-400.woff) format("woff"),url(webfonts/fa-regular-400.ttf) format("truetype"),url(webfonts/fa-regular-400.svg#fontawesome) format("svg");font-weight:400;font-style:normal}@font-face{font-family:ConverseFontAwesomeSolid;font-style:normal;font-weight:900;src:url(webfonts/fa-solid-900.eot);src:url(webfonts/fa-solid-900-.eot#iefix) format("embedded-opentype"),url(webfonts/fa-solid-900.svg#fontawesome) format("svg"),url(webfonts/fa-solid-900.woff2) format("woff2"),url(webfonts/fa-solid-900.woff) format("woff"),url(webfonts/fa-solid-900.ttf) format("truetype")}.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scale(-1,1)}.fa-flip-vertical{transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:""}.fa-accessible-icon:before{content:""}.fa-accusoft:before{content:""}.fa-acquisitions-incorporated:before{content:""}.fa-ad:before{content:""}.fa-address-book:before{content:""}.fa-address-card:before{content:""}.fa-adjust:before{content:""}.fa-adn:before{content:""}.fa-adobe:before{content:""}.fa-adversal:before{content:""}.fa-affiliatetheme:before{content:""}.fa-air-freshener:before{content:""}.fa-airbnb:before{content:""}.fa-algolia:before{content:""}.fa-align-center:before{content:""}.fa-align-justify:before{content:""}.fa-align-left:before{content:""}.fa-align-right:before{content:""}.fa-alipay:before{content:""}.fa-allergies:before{content:""}.fa-amazon:before{content:""}.fa-amazon-pay:before{content:""}.fa-ambulance:before{content:""}.fa-american-sign-language-interpreting:before{content:""}.fa-amilia:before{content:""}.fa-anchor:before{content:""}.fa-android:before{content:""}.fa-angellist:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angry:before{content:""}.fa-angrycreative:before{content:""}.fa-angular:before{content:""}.fa-ankh:before{content:""}.fa-app-store:before{content:""}.fa-app-store-ios:before{content:""}.fa-apper:before{content:""}.fa-apple:before{content:""}.fa-apple-alt:before{content:""}.fa-apple-pay:before{content:""}.fa-archive:before{content:""}.fa-archway:before{content:""}.fa-arrow-alt-circle-down:before{content:""}.fa-arrow-alt-circle-left:before{content:""}.fa-arrow-alt-circle-right:before{content:""}.fa-arrow-alt-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-down:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrows-alt:before{content:""}.fa-arrows-alt-h:before{content:""}.fa-arrows-alt-v:before{content:""}.fa-artstation:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asterisk:before{content:""}.fa-asymmetrik:before{content:""}.fa-at:before{content:""}.fa-atlas:before{content:""}.fa-atlassian:before{content:""}.fa-atom:before{content:""}.fa-audible:before{content:""}.fa-audio-description:before{content:""}.fa-autoprefixer:before{content:""}.fa-avianex:before{content:""}.fa-aviato:before{content:""}.fa-award:before{content:""}.fa-aws:before{content:""}.fa-baby:before{content:""}.fa-baby-carriage:before{content:""}.fa-backspace:before{content:""}.fa-backward:before{content:""}.fa-bacon:before{content:""}.fa-bacteria:before{content:""}.fa-bacterium:before{content:""}.fa-bahai:before{content:""}.fa-balance-scale:before{content:""}.fa-balance-scale-left:before{content:""}.fa-balance-scale-right:before{content:""}.fa-ban:before{content:""}.fa-band-aid:before{content:""}.fa-bandcamp:before{content:""}.fa-barcode:before{content:""}.fa-bars:before{content:""}.fa-baseball-ball:before{content:""}.fa-basketball-ball:before{content:""}.fa-bath:before{content:""}.fa-battery-empty:before{content:""}.fa-battery-full:before{content:""}.fa-battery-half:before{content:""}.fa-battery-quarter:before{content:""}.fa-battery-three-quarters:before{content:""}.fa-battle-net:before{content:""}.fa-bed:before{content:""}.fa-beer:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-bell:before{content:""}.fa-bell-slash:before{content:""}.fa-bezier-curve:before{content:""}.fa-bible:before{content:""}.fa-bicycle:before{content:""}.fa-biking:before{content:""}.fa-bimobject:before{content:""}.fa-binoculars:before{content:""}.fa-biohazard:before{content:""}.fa-birthday-cake:before{content:""}.fa-bitbucket:before{content:""}.fa-bitcoin:before{content:""}.fa-bity:before{content:""}.fa-black-tie:before{content:""}.fa-blackberry:before{content:""}.fa-blender:before{content:""}.fa-blender-phone:before{content:""}.fa-blind:before{content:""}.fa-blog:before{content:""}.fa-blogger:before{content:""}.fa-blogger-b:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-bold:before{content:""}.fa-bolt:before{content:""}.fa-bomb:before{content:""}.fa-bone:before{content:""}.fa-bong:before{content:""}.fa-book:before{content:""}.fa-book-dead:before{content:""}.fa-book-medical:before{content:""}.fa-book-open:before{content:""}.fa-book-reader:before{content:""}.fa-bookmark:before{content:""}.fa-bootstrap:before{content:""}.fa-border-all:before{content:""}.fa-border-none:before{content:""}.fa-border-style:before{content:""}.fa-bowling-ball:before{content:""}.fa-box:before{content:""}.fa-box-open:before{content:""}.fa-box-tissue:before{content:""}.fa-boxes:before{content:""}.fa-braille:before{content:""}.fa-brain:before{content:""}.fa-bread-slice:before{content:""}.fa-briefcase:before{content:""}.fa-briefcase-medical:before{content:""}.fa-broadcast-tower:before{content:""}.fa-broom:before{content:""}.fa-brush:before{content:""}.fa-btc:before{content:""}.fa-buffer:before{content:""}.fa-bug:before{content:""}.fa-building:before{content:""}.fa-bullhorn:before{content:""}.fa-bullseye:before{content:""}.fa-burn:before{content:""}.fa-buromobelexperte:before{content:""}.fa-bus:before{content:""}.fa-bus-alt:before{content:""}.fa-business-time:before{content:""}.fa-buy-n-large:before{content:""}.fa-buysellads:before{content:""}.fa-calculator:before{content:""}.fa-calendar:before{content:""}.fa-calendar-alt:before{content:""}.fa-calendar-check:before{content:""}.fa-calendar-day:before{content:""}.fa-calendar-minus:before{content:""}.fa-calendar-plus:before{content:""}.fa-calendar-times:before{content:""}.fa-calendar-week:before{content:""}.fa-camera:before{content:""}.fa-camera-retro:before{content:""}.fa-campground:before{content:""}.fa-canadian-maple-leaf:before{content:""}.fa-candy-cane:before{content:""}.fa-cannabis:before{content:""}.fa-capsules:before{content:""}.fa-car:before{content:""}.fa-car-alt:before{content:""}.fa-car-battery:before{content:""}.fa-car-crash:before{content:""}.fa-car-side:before{content:""}.fa-caravan:before{content:""}.fa-caret-down:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-caret-square-down:before{content:""}.fa-caret-square-left:before{content:""}.fa-caret-square-right:before{content:""}.fa-caret-square-up:before{content:""}.fa-caret-up:before{content:""}.fa-carrot:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-cart-plus:before{content:""}.fa-cash-register:before{content:""}.fa-cat:before{content:""}.fa-cc-amazon-pay:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-apple-pay:before{content:""}.fa-cc-diners-club:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-cc-visa:before{content:""}.fa-centercode:before{content:""}.fa-centos:before{content:""}.fa-certificate:before{content:""}.fa-chair:before{content:""}.fa-chalkboard:before{content:""}.fa-chalkboard-teacher:before{content:""}.fa-charging-station:before{content:""}.fa-chart-area:before{content:""}.fa-chart-bar:before{content:""}.fa-chart-line:before{content:""}.fa-chart-pie:before{content:""}.fa-check:before{content:""}.fa-check-circle:before{content:""}.fa-check-double:before{content:""}.fa-check-square:before{content:""}.fa-cheese:before{content:""}.fa-chess:before{content:""}.fa-chess-bishop:before{content:""}.fa-chess-board:before{content:""}.fa-chess-king:before{content:""}.fa-chess-knight:before{content:""}.fa-chess-pawn:before{content:""}.fa-chess-queen:before{content:""}.fa-chess-rook:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-down:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-chevron-up:before{content:""}.fa-child:before{content:""}.fa-chrome:before{content:""}.fa-chromecast:before{content:""}.fa-church:before{content:""}.fa-circle:before{content:""}.fa-circle-notch:before{content:""}.fa-city:before{content:""}.fa-clinic-medical:before{content:""}.fa-clipboard:before{content:""}.fa-clipboard-check:before{content:""}.fa-clipboard-list:before{content:""}.fa-clock:before{content:""}.fa-clone:before{content:""}.fa-closed-captioning:before{content:""}.fa-cloud:before{content:""}.fa-cloud-download-alt:before{content:""}.fa-cloud-meatball:before{content:""}.fa-cloud-moon:before{content:""}.fa-cloud-moon-rain:before{content:""}.fa-cloud-rain:before{content:""}.fa-cloud-showers-heavy:before{content:""}.fa-cloud-sun:before{content:""}.fa-cloud-sun-rain:before{content:""}.fa-cloud-upload-alt:before{content:""}.fa-cloudscale:before{content:""}.fa-cloudsmith:before{content:""}.fa-cloudversify:before{content:""}.fa-cocktail:before{content:""}.fa-code:before{content:""}.fa-code-branch:before{content:""}.fa-codepen:before{content:""}.fa-codiepie:before{content:""}.fa-coffee:before{content:""}.fa-cog:before{content:""}.fa-cogs:before{content:""}.fa-coins:before{content:""}.fa-columns:before{content:""}.fa-comment:before{content:""}.fa-comment-alt:before{content:""}.fa-comment-dollar:before{content:""}.fa-comment-dots:before{content:""}.fa-comment-medical:before{content:""}.fa-comment-slash:before{content:""}.fa-comments:before{content:""}.fa-comments-dollar:before{content:""}.fa-compact-disc:before{content:""}.fa-compass:before{content:""}.fa-compress:before{content:""}.fa-compress-alt:before{content:""}.fa-compress-arrows-alt:before{content:""}.fa-concierge-bell:before{content:""}.fa-confluence:before{content:""}.fa-connectdevelop:before{content:""}.fa-contao:before{content:""}.fa-cookie:before{content:""}.fa-cookie-bite:before{content:""}.fa-copy:before{content:""}.fa-copyright:before{content:""}.fa-cotton-bureau:before{content:""}.fa-couch:before{content:""}.fa-cpanel:before{content:""}.fa-creative-commons:before{content:""}.fa-creative-commons-by:before{content:""}.fa-creative-commons-nc:before{content:""}.fa-creative-commons-nc-eu:before{content:""}.fa-creative-commons-nc-jp:before{content:""}.fa-creative-commons-nd:before{content:""}.fa-creative-commons-pd:before{content:""}.fa-creative-commons-pd-alt:before{content:""}.fa-creative-commons-remix:before{content:""}.fa-creative-commons-sa:before{content:""}.fa-creative-commons-sampling:before{content:""}.fa-creative-commons-sampling-plus:before{content:""}.fa-creative-commons-share:before{content:""}.fa-creative-commons-zero:before{content:""}.fa-credit-card:before{content:""}.fa-critical-role:before{content:""}.fa-crop:before{content:""}.fa-crop-alt:before{content:""}.fa-cross:before{content:""}.fa-crosshairs:before{content:""}.fa-crow:before{content:""}.fa-crown:before{content:""}.fa-crutch:before{content:""}.fa-css3:before{content:""}.fa-css3-alt:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-cut:before{content:""}.fa-cuttlefish:before{content:""}.fa-d-and-d:before{content:""}.fa-d-and-d-beyond:before{content:""}.fa-dailymotion:before{content:""}.fa-dashcube:before{content:""}.fa-database:before{content:""}.fa-deaf:before{content:""}.fa-deezer:before{content:""}.fa-delicious:before{content:""}.fa-democrat:before{content:""}.fa-deploydog:before{content:""}.fa-deskpro:before{content:""}.fa-desktop:before{content:""}.fa-dev:before{content:""}.fa-deviantart:before{content:""}.fa-dharmachakra:before{content:""}.fa-dhl:before{content:""}.fa-diagnoses:before{content:""}.fa-diaspora:before{content:""}.fa-dice:before{content:""}.fa-dice-d20:before{content:""}.fa-dice-d6:before{content:""}.fa-dice-five:before{content:""}.fa-dice-four:before{content:""}.fa-dice-one:before{content:""}.fa-dice-six:before{content:""}.fa-dice-three:before{content:""}.fa-dice-two:before{content:""}.fa-digg:before{content:""}.fa-digital-ocean:before{content:""}.fa-digital-tachograph:before{content:""}.fa-directions:before{content:""}.fa-discord:before{content:""}.fa-discourse:before{content:""}.fa-disease:before{content:""}.fa-divide:before{content:""}.fa-dizzy:before{content:""}.fa-dna:before{content:""}.fa-dochub:before{content:""}.fa-docker:before{content:""}.fa-dog:before{content:""}.fa-dollar-sign:before{content:""}.fa-dolly:before{content:""}.fa-dolly-flatbed:before{content:""}.fa-donate:before{content:""}.fa-door-closed:before{content:""}.fa-door-open:before{content:""}.fa-dot-circle:before{content:""}.fa-dove:before{content:""}.fa-download:before{content:""}.fa-draft2digital:before{content:""}.fa-drafting-compass:before{content:""}.fa-dragon:before{content:""}.fa-draw-polygon:before{content:""}.fa-dribbble:before{content:""}.fa-dribbble-square:before{content:""}.fa-dropbox:before{content:""}.fa-drum:before{content:""}.fa-drum-steelpan:before{content:""}.fa-drumstick-bite:before{content:""}.fa-drupal:before{content:""}.fa-dumbbell:before{content:""}.fa-dumpster:before{content:""}.fa-dumpster-fire:before{content:""}.fa-dungeon:before{content:""}.fa-dyalog:before{content:""}.fa-earlybirds:before{content:""}.fa-ebay:before{content:""}.fa-edge:before{content:""}.fa-edge-legacy:before{content:""}.fa-edit:before{content:""}.fa-egg:before{content:""}.fa-eject:before{content:""}.fa-elementor:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-ello:before{content:""}.fa-ember:before{content:""}.fa-empire:before{content:""}.fa-envelope:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-text:before{content:""}.fa-envelope-square:before{content:""}.fa-envira:before{content:""}.fa-equals:before{content:""}.fa-eraser:before{content:""}.fa-erlang:before{content:""}.fa-ethereum:before{content:""}.fa-ethernet:before{content:""}.fa-etsy:before{content:""}.fa-euro-sign:before{content:""}.fa-evernote:before{content:""}.fa-exchange-alt:before{content:""}.fa-exclamation:before{content:""}.fa-exclamation-circle:before{content:""}.fa-exclamation-triangle:before{content:""}.fa-expand:before{content:""}.fa-expand-alt:before{content:""}.fa-expand-arrows-alt:before{content:""}.fa-expeditedssl:before{content:""}.fa-external-link-alt:before{content:""}.fa-external-link-square-alt:before{content:""}.fa-eye:before{content:""}.fa-eye-dropper:before{content:""}.fa-eye-slash:before{content:""}.fa-facebook:before{content:""}.fa-facebook-f:before{content:""}.fa-facebook-messenger:before{content:""}.fa-facebook-square:before{content:""}.fa-fan:before{content:""}.fa-fantasy-flight-games:before{content:""}.fa-fast-backward:before{content:""}.fa-fast-forward:before{content:""}.fa-faucet:before{content:""}.fa-fax:before{content:""}.fa-feather:before{content:""}.fa-feather-alt:before{content:""}.fa-fedex:before{content:""}.fa-fedora:before{content:""}.fa-female:before{content:""}.fa-fighter-jet:before{content:""}.fa-figma:before{content:""}.fa-file:before{content:""}.fa-file-alt:before{content:""}.fa-file-archive:before{content:""}.fa-file-audio:before{content:""}.fa-file-code:before{content:""}.fa-file-contract:before{content:""}.fa-file-csv:before{content:""}.fa-file-download:before{content:""}.fa-file-excel:before{content:""}.fa-file-export:before{content:""}.fa-file-image:before{content:""}.fa-file-import:before{content:""}.fa-file-invoice:before{content:""}.fa-file-invoice-dollar:before{content:""}.fa-file-medical:before{content:""}.fa-file-medical-alt:before{content:""}.fa-file-pdf:before{content:""}.fa-file-powerpoint:before{content:""}.fa-file-prescription:before{content:""}.fa-file-signature:before{content:""}.fa-file-upload:before{content:""}.fa-file-video:before{content:""}.fa-file-word:before{content:""}.fa-fill:before{content:""}.fa-fill-drip:before{content:""}.fa-film:before{content:""}.fa-filter:before{content:""}.fa-fingerprint:before{content:""}.fa-fire:before{content:""}.fa-fire-alt:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-firefox:before{content:""}.fa-firefox-browser:before{content:""}.fa-first-aid:before{content:""}.fa-first-order:before{content:""}.fa-first-order-alt:before{content:""}.fa-firstdraft:before{content:""}.fa-fish:before{content:""}.fa-fist-raised:before{content:""}.fa-flag:before{content:""}.fa-flag-checkered:before{content:""}.fa-flag-usa:before{content:""}.fa-flask:before{content:""}.fa-flickr:before{content:""}.fa-flipboard:before{content:""}.fa-flushed:before{content:""}.fa-fly:before{content:""}.fa-folder:before{content:""}.fa-folder-minus:before{content:""}.fa-folder-open:before{content:""}.fa-folder-plus:before{content:""}.fa-font:before{content:""}.fa-font-awesome:before{content:""}.fa-font-awesome-alt:before{content:""}.fa-font-awesome-flag:before{content:""}.fa-font-awesome-logo-full:before{content:""}.fa-fonticons:before{content:""}.fa-fonticons-fi:before{content:""}.fa-football-ball:before{content:""}.fa-fort-awesome:before{content:""}.fa-fort-awesome-alt:before{content:""}.fa-forumbee:before{content:""}.fa-forward:before{content:""}.fa-foursquare:before{content:""}.fa-free-code-camp:before{content:""}.fa-freebsd:before{content:""}.fa-frog:before{content:""}.fa-frown:before{content:""}.fa-frown-open:before{content:""}.fa-fulcrum:before{content:""}.fa-funnel-dollar:before{content:""}.fa-futbol:before{content:""}.fa-galactic-republic:before{content:""}.fa-galactic-senate:before{content:""}.fa-gamepad:before{content:""}.fa-gas-pump:before{content:""}.fa-gavel:before{content:""}.fa-gem:before{content:""}.fa-genderless:before{content:""}.fa-get-pocket:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-ghost:before{content:""}.fa-gift:before{content:""}.fa-gifts:before{content:""}.fa-git:before{content:""}.fa-git-alt:before{content:""}.fa-git-square:before{content:""}.fa-github:before{content:""}.fa-github-alt:before{content:""}.fa-github-square:before{content:""}.fa-gitkraken:before{content:""}.fa-gitlab:before{content:""}.fa-gitter:before{content:""}.fa-glass-cheers:before{content:""}.fa-glass-martini:before{content:""}.fa-glass-martini-alt:before{content:""}.fa-glass-whiskey:before{content:""}.fa-glasses:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-globe:before{content:""}.fa-globe-africa:before{content:""}.fa-globe-americas:before{content:""}.fa-globe-asia:before{content:""}.fa-globe-europe:before{content:""}.fa-gofore:before{content:""}.fa-golf-ball:before{content:""}.fa-goodreads:before{content:""}.fa-goodreads-g:before{content:""}.fa-google:before{content:""}.fa-google-drive:before{content:""}.fa-google-pay:before{content:""}.fa-google-play:before{content:""}.fa-google-plus:before{content:""}.fa-google-plus-g:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-wallet:before{content:""}.fa-gopuram:before{content:""}.fa-graduation-cap:before{content:""}.fa-gratipay:before{content:""}.fa-grav:before{content:""}.fa-greater-than:before{content:""}.fa-greater-than-equal:before{content:""}.fa-grimace:before{content:""}.fa-grin:before{content:""}.fa-grin-alt:before{content:""}.fa-grin-beam:before{content:""}.fa-grin-beam-sweat:before{content:""}.fa-grin-hearts:before{content:""}.fa-grin-squint:before{content:""}.fa-grin-squint-tears:before{content:""}.fa-grin-stars:before{content:""}.fa-grin-tears:before{content:""}.fa-grin-tongue:before{content:""}.fa-grin-tongue-squint:before{content:""}.fa-grin-tongue-wink:before{content:""}.fa-grin-wink:before{content:""}.fa-grip-horizontal:before{content:""}.fa-grip-lines:before{content:""}.fa-grip-lines-vertical:before{content:""}.fa-grip-vertical:before{content:""}.fa-gripfire:before{content:""}.fa-grunt:before{content:""}.fa-guitar:before{content:""}.fa-gulp:before{content:""}.fa-h-square:before{content:""}.fa-hacker-news:before{content:""}.fa-hacker-news-square:before{content:""}.fa-hackerrank:before{content:""}.fa-hamburger:before{content:""}.fa-hammer:before{content:""}.fa-hamsa:before{content:""}.fa-hand-holding:before{content:""}.fa-hand-holding-heart:before{content:""}.fa-hand-holding-medical:before{content:""}.fa-hand-holding-usd:before{content:""}.fa-hand-holding-water:before{content:""}.fa-hand-lizard:before{content:""}.fa-hand-middle-finger:before{content:""}.fa-hand-paper:before{content:""}.fa-hand-peace:before{content:""}.fa-hand-point-down:before{content:""}.fa-hand-point-left:before{content:""}.fa-hand-point-right:before{content:""}.fa-hand-point-up:before{content:""}.fa-hand-pointer:before{content:""}.fa-hand-rock:before{content:""}.fa-hand-scissors:before{content:""}.fa-hand-sparkles:before{content:""}.fa-hand-spock:before{content:""}.fa-hands:before{content:""}.fa-hands-helping:before{content:""}.fa-hands-wash:before{content:""}.fa-handshake:before{content:""}.fa-handshake-alt-slash:before{content:""}.fa-handshake-slash:before{content:""}.fa-hanukiah:before{content:""}.fa-hard-hat:before{content:""}.fa-hashtag:before{content:""}.fa-hat-cowboy:before{content:""}.fa-hat-cowboy-side:before{content:""}.fa-hat-wizard:before{content:""}.fa-hdd:before{content:""}.fa-head-side-cough:before{content:""}.fa-head-side-cough-slash:before{content:""}.fa-head-side-mask:before{content:""}.fa-head-side-virus:before{content:""}.fa-heading:before{content:""}.fa-headphones:before{content:""}.fa-headphones-alt:before{content:""}.fa-headset:before{content:""}.fa-heart:before{content:""}.fa-heart-broken:before{content:""}.fa-heartbeat:before{content:""}.fa-helicopter:before{content:""}.fa-highlighter:before{content:""}.fa-hiking:before{content:""}.fa-hippo:before{content:""}.fa-hips:before{content:""}.fa-hire-a-helper:before{content:""}.fa-history:before{content:""}.fa-hockey-puck:before{content:""}.fa-holly-berry:before{content:""}.fa-home:before{content:""}.fa-hooli:before{content:""}.fa-hornbill:before{content:""}.fa-horse:before{content:""}.fa-horse-head:before{content:""}.fa-hospital:before{content:""}.fa-hospital-alt:before{content:""}.fa-hospital-symbol:before{content:""}.fa-hospital-user:before{content:""}.fa-hot-tub:before{content:""}.fa-hotdog:before{content:""}.fa-hotel:before{content:""}.fa-hotjar:before{content:""}.fa-hourglass:before{content:""}.fa-hourglass-end:before{content:""}.fa-hourglass-half:before{content:""}.fa-hourglass-start:before{content:""}.fa-house-damage:before{content:""}.fa-house-user:before{content:""}.fa-houzz:before{content:""}.fa-hryvnia:before{content:""}.fa-html5:before{content:""}.fa-hubspot:before{content:""}.fa-i-cursor:before{content:""}.fa-ice-cream:before{content:""}.fa-icicles:before{content:""}.fa-icons:before{content:""}.fa-id-badge:before{content:""}.fa-id-card:before{content:""}.fa-id-card-alt:before{content:""}.fa-ideal:before{content:""}.fa-igloo:before{content:""}.fa-image:before{content:""}.fa-images:before{content:""}.fa-imdb:before{content:""}.fa-inbox:before{content:""}.fa-indent:before{content:""}.fa-industry:before{content:""}.fa-infinity:before{content:""}.fa-info:before{content:""}.fa-info-circle:before{content:""}.fa-instagram:before{content:""}.fa-instagram-square:before{content:""}.fa-intercom:before{content:""}.fa-internet-explorer:before{content:""}.fa-invision:before{content:""}.fa-ioxhost:before{content:""}.fa-italic:before{content:""}.fa-itch-io:before{content:""}.fa-itunes:before{content:""}.fa-itunes-note:before{content:""}.fa-java:before{content:""}.fa-jedi:before{content:""}.fa-jedi-order:before{content:""}.fa-jenkins:before{content:""}.fa-jira:before{content:""}.fa-joget:before{content:""}.fa-joint:before{content:""}.fa-joomla:before{content:""}.fa-journal-whills:before{content:""}.fa-js:before{content:""}.fa-js-square:before{content:""}.fa-jsfiddle:before{content:""}.fa-kaaba:before{content:""}.fa-kaggle:before{content:""}.fa-key:before{content:""}.fa-keybase:before{content:""}.fa-keyboard:before{content:""}.fa-keycdn:before{content:""}.fa-khanda:before{content:""}.fa-kickstarter:before{content:""}.fa-kickstarter-k:before{content:""}.fa-kiss:before{content:""}.fa-kiss-beam:before{content:""}.fa-kiss-wink-heart:before{content:""}.fa-kiwi-bird:before{content:""}.fa-korvue:before{content:""}.fa-landmark:before{content:""}.fa-language:before{content:""}.fa-laptop:before{content:""}.fa-laptop-code:before{content:""}.fa-laptop-house:before{content:""}.fa-laptop-medical:before{content:""}.fa-laravel:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-laugh:before{content:""}.fa-laugh-beam:before{content:""}.fa-laugh-squint:before{content:""}.fa-laugh-wink:before{content:""}.fa-layer-group:before{content:""}.fa-leaf:before{content:""}.fa-leanpub:before{content:""}.fa-lemon:before{content:""}.fa-less:before{content:""}.fa-less-than:before{content:""}.fa-less-than-equal:before{content:""}.fa-level-down-alt:before{content:""}.fa-level-up-alt:before{content:""}.fa-life-ring:before{content:""}.fa-lightbulb:before{content:""}.fa-line:before{content:""}.fa-link:before{content:""}.fa-linkedin:before{content:""}.fa-linkedin-in:before{content:""}.fa-linode:before{content:""}.fa-linux:before{content:""}.fa-lira-sign:before{content:""}.fa-list:before{content:""}.fa-list-alt:before{content:""}.fa-list-ol:before{content:""}.fa-list-ul:before{content:""}.fa-location-arrow:before{content:""}.fa-lock:before{content:""}.fa-lock-open:before{content:""}.fa-long-arrow-alt-down:before{content:""}.fa-long-arrow-alt-left:before{content:""}.fa-long-arrow-alt-right:before{content:""}.fa-long-arrow-alt-up:before{content:""}.fa-low-vision:before{content:""}.fa-luggage-cart:before{content:""}.fa-lungs:before{content:""}.fa-lungs-virus:before{content:""}.fa-lyft:before{content:""}.fa-magento:before{content:""}.fa-magic:before{content:""}.fa-magnet:before{content:""}.fa-mail-bulk:before{content:""}.fa-mailchimp:before{content:""}.fa-male:before{content:""}.fa-mandalorian:before{content:""}.fa-map:before{content:""}.fa-map-marked:before{content:""}.fa-map-marked-alt:before{content:""}.fa-map-marker:before{content:""}.fa-map-marker-alt:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-markdown:before{content:""}.fa-marker:before{content:""}.fa-mars:before{content:""}.fa-mars-double:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mask:before{content:""}.fa-mastodon:before{content:""}.fa-maxcdn:before{content:""}.fa-mdb:before{content:""}.fa-medal:before{content:""}.fa-medapps:before{content:""}.fa-medium:before{content:""}.fa-medium-m:before{content:""}.fa-medkit:before{content:""}.fa-medrt:before{content:""}.fa-meetup:before{content:""}.fa-megaport:before{content:""}.fa-meh:before{content:""}.fa-meh-blank:before{content:""}.fa-meh-rolling-eyes:before{content:""}.fa-memory:before{content:""}.fa-mendeley:before{content:""}.fa-menorah:before{content:""}.fa-mercury:before{content:""}.fa-meteor:before{content:""}.fa-microblog:before{content:""}.fa-microchip:before{content:""}.fa-microphone:before{content:""}.fa-microphone-alt:before{content:""}.fa-microphone-alt-slash:before{content:""}.fa-microphone-slash:before{content:""}.fa-microscope:before{content:""}.fa-microsoft:before{content:""}.fa-minus:before{content:""}.fa-minus-circle:before{content:""}.fa-minus-square:before{content:""}.fa-mitten:before{content:""}.fa-mix:before{content:""}.fa-mixcloud:before{content:""}.fa-mixer:before{content:""}.fa-mizuni:before{content:""}.fa-mobile:before{content:""}.fa-mobile-alt:before{content:""}.fa-modx:before{content:""}.fa-monero:before{content:""}.fa-money-bill:before{content:""}.fa-money-bill-alt:before{content:""}.fa-money-bill-wave:before{content:""}.fa-money-bill-wave-alt:before{content:""}.fa-money-check:before{content:""}.fa-money-check-alt:before{content:""}.fa-monument:before{content:""}.fa-moon:before{content:""}.fa-mortar-pestle:before{content:""}.fa-mosque:before{content:""}.fa-motorcycle:before{content:""}.fa-mountain:before{content:""}.fa-mouse:before{content:""}.fa-mouse-pointer:before{content:""}.fa-mug-hot:before{content:""}.fa-music:before{content:""}.fa-napster:before{content:""}.fa-neos:before{content:""}.fa-network-wired:before{content:""}.fa-neuter:before{content:""}.fa-newspaper:before{content:""}.fa-nimblr:before{content:""}.fa-node:before{content:""}.fa-node-js:before{content:""}.fa-not-equal:before{content:""}.fa-notes-medical:before{content:""}.fa-npm:before{content:""}.fa-ns8:before{content:""}.fa-nutritionix:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-oil-can:before{content:""}.fa-old-republic:before{content:""}.fa-om:before{content:""}.fa-opencart:before{content:""}.fa-openid:before{content:""}.fa-opera:before{content:""}.fa-optin-monster:before{content:""}.fa-orcid:before{content:""}.fa-osi:before{content:""}.fa-otter:before{content:""}.fa-outdent:before{content:""}.fa-page4:before{content:""}.fa-pagelines:before{content:""}.fa-pager:before{content:""}.fa-paint-brush:before{content:""}.fa-paint-roller:before{content:""}.fa-palette:before{content:""}.fa-palfed:before{content:""}.fa-pallet:before{content:""}.fa-paper-plane:before{content:""}.fa-paperclip:before{content:""}.fa-parachute-box:before{content:""}.fa-paragraph:before{content:""}.fa-parking:before{content:""}.fa-passport:before{content:""}.fa-pastafarianism:before{content:""}.fa-paste:before{content:""}.fa-patreon:before{content:""}.fa-pause:before{content:""}.fa-pause-circle:before{content:""}.fa-paw:before{content:""}.fa-paypal:before{content:""}.fa-peace:before{content:""}.fa-pen:before{content:""}.fa-pen-alt:before{content:""}.fa-pen-fancy:before{content:""}.fa-pen-nib:before{content:""}.fa-pen-square:before{content:""}.fa-pencil-alt:before{content:""}.fa-pencil-ruler:before{content:""}.fa-penny-arcade:before{content:""}.fa-people-arrows:before{content:""}.fa-people-carry:before{content:""}.fa-pepper-hot:before{content:""}.fa-percent:before{content:""}.fa-percentage:before{content:""}.fa-periscope:before{content:""}.fa-person-booth:before{content:""}.fa-phabricator:before{content:""}.fa-phoenix-framework:before{content:""}.fa-phoenix-squadron:before{content:""}.fa-phone:before{content:""}.fa-phone-alt:before{content:""}.fa-phone-slash:before{content:""}.fa-phone-square:before{content:""}.fa-phone-square-alt:before{content:""}.fa-phone-volume:before{content:""}.fa-photo-video:before{content:""}.fa-php:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-pied-piper-hat:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-square:before{content:""}.fa-piggy-bank:before{content:""}.fa-pills:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-p:before{content:""}.fa-pinterest-square:before{content:""}.fa-pizza-slice:before{content:""}.fa-place-of-worship:before{content:""}.fa-plane:before{content:""}.fa-plane-arrival:before{content:""}.fa-plane-departure:before{content:""}.fa-plane-slash:before{content:""}.fa-play:before{content:""}.fa-play-circle:before{content:""}.fa-playstation:before{content:""}.fa-plug:before{content:""}.fa-plus:before{content:""}.fa-plus-circle:before{content:""}.fa-plus-square:before{content:""}.fa-podcast:before{content:""}.fa-poll:before{content:""}.fa-poll-h:before{content:""}.fa-poo:before{content:""}.fa-poo-storm:before{content:""}.fa-poop:before{content:""}.fa-portrait:before{content:""}.fa-pound-sign:before{content:""}.fa-power-off:before{content:""}.fa-pray:before{content:""}.fa-praying-hands:before{content:""}.fa-prescription:before{content:""}.fa-prescription-bottle:before{content:""}.fa-prescription-bottle-alt:before{content:""}.fa-print:before{content:""}.fa-procedures:before{content:""}.fa-product-hunt:before{content:""}.fa-project-diagram:before{content:""}.fa-pump-medical:before{content:""}.fa-pump-soap:before{content:""}.fa-pushed:before{content:""}.fa-puzzle-piece:before{content:""}.fa-python:before{content:""}.fa-qq:before{content:""}.fa-qrcode:before{content:""}.fa-question:before{content:""}.fa-question-circle:before{content:""}.fa-quidditch:before{content:""}.fa-quinscape:before{content:""}.fa-quora:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-quran:before{content:""}.fa-r-project:before{content:""}.fa-radiation:before{content:""}.fa-radiation-alt:before{content:""}.fa-rainbow:before{content:""}.fa-random:before{content:""}.fa-raspberry-pi:before{content:""}.fa-ravelry:before{content:""}.fa-react:before{content:""}.fa-reacteurope:before{content:""}.fa-readme:before{content:""}.fa-rebel:before{content:""}.fa-receipt:before{content:""}.fa-record-vinyl:before{content:""}.fa-recycle:before{content:""}.fa-red-river:before{content:""}.fa-reddit:before{content:""}.fa-reddit-alien:before{content:""}.fa-reddit-square:before{content:""}.fa-redhat:before{content:""}.fa-redo:before{content:""}.fa-redo-alt:before{content:""}.fa-registered:before{content:""}.fa-remove-format:before{content:""}.fa-renren:before{content:""}.fa-reply:before{content:""}.fa-reply-all:before{content:""}.fa-replyd:before{content:""}.fa-republican:before{content:""}.fa-researchgate:before{content:""}.fa-resolving:before{content:""}.fa-restroom:before{content:""}.fa-retweet:before{content:""}.fa-rev:before{content:""}.fa-ribbon:before{content:""}.fa-ring:before{content:""}.fa-road:before{content:""}.fa-robot:before{content:""}.fa-rocket:before{content:""}.fa-rocketchat:before{content:""}.fa-rockrms:before{content:""}.fa-route:before{content:""}.fa-rss:before{content:""}.fa-rss-square:before{content:""}.fa-ruble-sign:before{content:""}.fa-ruler:before{content:""}.fa-ruler-combined:before{content:""}.fa-ruler-horizontal:before{content:""}.fa-ruler-vertical:before{content:""}.fa-running:before{content:""}.fa-rupee-sign:before{content:""}.fa-rust:before{content:""}.fa-sad-cry:before{content:""}.fa-sad-tear:before{content:""}.fa-safari:before{content:""}.fa-salesforce:before{content:""}.fa-sass:before{content:""}.fa-satellite:before{content:""}.fa-satellite-dish:before{content:""}.fa-save:before{content:""}.fa-schlix:before{content:""}.fa-school:before{content:""}.fa-screwdriver:before{content:""}.fa-scribd:before{content:""}.fa-scroll:before{content:""}.fa-sd-card:before{content:""}.fa-search:before{content:""}.fa-search-dollar:before{content:""}.fa-search-location:before{content:""}.fa-search-minus:before{content:""}.fa-search-plus:before{content:""}.fa-searchengin:before{content:""}.fa-seedling:before{content:""}.fa-sellcast:before{content:""}.fa-sellsy:before{content:""}.fa-server:before{content:""}.fa-servicestack:before{content:""}.fa-shapes:before{content:""}.fa-share:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-share-square:before{content:""}.fa-shekel-sign:before{content:""}.fa-shield-alt:before{content:""}.fa-shield-virus:before{content:""}.fa-ship:before{content:""}.fa-shipping-fast:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-shoe-prints:before{content:""}.fa-shopify:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-shopping-cart:before{content:""}.fa-shopware:before{content:""}.fa-shower:before{content:""}.fa-shuttle-van:before{content:""}.fa-sign:before{content:""}.fa-sign-in-alt:before{content:""}.fa-sign-language:before{content:""}.fa-sign-out-alt:before{content:""}.fa-signal:before{content:""}.fa-signature:before{content:""}.fa-sim-card:before{content:""}.fa-simplybuilt:before{content:""}.fa-sink:before{content:""}.fa-sistrix:before{content:""}.fa-sitemap:before{content:""}.fa-sith:before{content:""}.fa-skating:before{content:""}.fa-sketch:before{content:""}.fa-skiing:before{content:""}.fa-skiing-nordic:before{content:""}.fa-skull:before{content:""}.fa-skull-crossbones:before{content:""}.fa-skyatlas:before{content:""}.fa-skype:before{content:""}.fa-slack:before{content:""}.fa-slack-hash:before{content:""}.fa-slash:before{content:""}.fa-sleigh:before{content:""}.fa-sliders-h:before{content:""}.fa-slideshare:before{content:""}.fa-smile:before{content:""}.fa-smile-beam:before{content:""}.fa-smile-wink:before{content:""}.fa-smog:before{content:""}.fa-smoking:before{content:""}.fa-smoking-ban:before{content:""}.fa-sms:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-snowboarding:before{content:""}.fa-snowflake:before{content:""}.fa-snowman:before{content:""}.fa-snowplow:before{content:""}.fa-soap:before{content:""}.fa-socks:before{content:""}.fa-solar-panel:before{content:""}.fa-sort:before{content:""}.fa-sort-alpha-down:before{content:""}.fa-sort-alpha-down-alt:before{content:""}.fa-sort-alpha-up:before{content:""}.fa-sort-alpha-up-alt:before{content:""}.fa-sort-amount-down:before{content:""}.fa-sort-amount-down-alt:before{content:""}.fa-sort-amount-up:before{content:""}.fa-sort-amount-up-alt:before{content:""}.fa-sort-down:before{content:""}.fa-sort-numeric-down:before{content:""}.fa-sort-numeric-down-alt:before{content:""}.fa-sort-numeric-up:before{content:""}.fa-sort-numeric-up-alt:before{content:""}.fa-sort-up:before{content:""}.fa-soundcloud:before{content:""}.fa-sourcetree:before{content:""}.fa-spa:before{content:""}.fa-space-shuttle:before{content:""}.fa-speakap:before{content:""}.fa-speaker-deck:before{content:""}.fa-spell-check:before{content:""}.fa-spider:before{content:""}.fa-spinner:before{content:""}.fa-splotch:before{content:""}.fa-spotify:before{content:""}.fa-spray-can:before{content:""}.fa-square:before{content:""}.fa-square-full:before{content:""}.fa-square-root-alt:before{content:""}.fa-squarespace:before{content:""}.fa-stack-exchange:before{content:""}.fa-stack-overflow:before{content:""}.fa-stackpath:before{content:""}.fa-stamp:before{content:""}.fa-star:before{content:""}.fa-star-and-crescent:before{content:""}.fa-star-half:before{content:""}.fa-star-half-alt:before{content:""}.fa-star-of-david:before{content:""}.fa-star-of-life:before{content:""}.fa-staylinked:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-steam-symbol:before{content:""}.fa-step-backward:before{content:""}.fa-step-forward:before{content:""}.fa-stethoscope:before{content:""}.fa-sticker-mule:before{content:""}.fa-sticky-note:before{content:""}.fa-stop:before{content:""}.fa-stop-circle:before{content:""}.fa-stopwatch:before{content:""}.fa-stopwatch-20:before{content:""}.fa-store:before{content:""}.fa-store-alt:before{content:""}.fa-store-alt-slash:before{content:""}.fa-store-slash:before{content:""}.fa-strava:before{content:""}.fa-stream:before{content:""}.fa-street-view:before{content:""}.fa-strikethrough:before{content:""}.fa-stripe:before{content:""}.fa-stripe-s:before{content:""}.fa-stroopwafel:before{content:""}.fa-studiovinari:before{content:""}.fa-stumbleupon:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-subscript:before{content:""}.fa-subway:before{content:""}.fa-suitcase:before{content:""}.fa-suitcase-rolling:before{content:""}.fa-sun:before{content:""}.fa-superpowers:before{content:""}.fa-superscript:before{content:""}.fa-supple:before{content:""}.fa-surprise:before{content:""}.fa-suse:before{content:""}.fa-swatchbook:before{content:""}.fa-swift:before{content:""}.fa-swimmer:before{content:""}.fa-swimming-pool:before{content:""}.fa-symfony:before{content:""}.fa-synagogue:before{content:""}.fa-sync:before{content:""}.fa-sync-alt:before{content:""}.fa-syringe:before{content:""}.fa-table:before{content:""}.fa-table-tennis:before{content:""}.fa-tablet:before{content:""}.fa-tablet-alt:before{content:""}.fa-tablets:before{content:""}.fa-tachometer-alt:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-tape:before{content:""}.fa-tasks:before{content:""}.fa-taxi:before{content:""}.fa-teamspeak:before{content:""}.fa-teeth:before{content:""}.fa-teeth-open:before{content:""}.fa-telegram:before{content:""}.fa-telegram-plane:before{content:""}.fa-temperature-high:before{content:""}.fa-temperature-low:before{content:""}.fa-tencent-weibo:before{content:""}.fa-tenge:before{content:""}.fa-terminal:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-th:before{content:""}.fa-th-large:before{content:""}.fa-th-list:before{content:""}.fa-the-red-yeti:before{content:""}.fa-theater-masks:before{content:""}.fa-themeco:before{content:""}.fa-themeisle:before{content:""}.fa-thermometer:before{content:""}.fa-thermometer-empty:before{content:""}.fa-thermometer-full:before{content:""}.fa-thermometer-half:before{content:""}.fa-thermometer-quarter:before{content:""}.fa-thermometer-three-quarters:before{content:""}.fa-think-peaks:before{content:""}.fa-thumbs-down:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbtack:before{content:""}.fa-ticket-alt:before{content:""}.fa-tiktok:before{content:""}.fa-times:before{content:""}.fa-times-circle:before{content:""}.fa-tint:before{content:""}.fa-tint-slash:before{content:""}.fa-tired:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-toilet:before{content:""}.fa-toilet-paper:before{content:""}.fa-toilet-paper-slash:before{content:""}.fa-toolbox:before{content:""}.fa-tools:before{content:""}.fa-tooth:before{content:""}.fa-torah:before{content:""}.fa-torii-gate:before{content:""}.fa-tractor:before{content:""}.fa-trade-federation:before{content:""}.fa-trademark:before{content:""}.fa-traffic-light:before{content:""}.fa-trailer:before{content:""}.fa-train:before{content:""}.fa-tram:before{content:""}.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-trash:before{content:""}.fa-trash-alt:before{content:""}.fa-trash-restore:before{content:""}.fa-trash-restore-alt:before{content:""}.fa-tree:before{content:""}.fa-trello:before{content:""}.fa-tripadvisor:before{content:""}.fa-trophy:before{content:""}.fa-truck:before{content:""}.fa-truck-loading:before{content:""}.fa-truck-monster:before{content:""}.fa-truck-moving:before{content:""}.fa-truck-pickup:before{content:""}.fa-tshirt:before{content:""}.fa-tty:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-tv:before{content:""}.fa-twitch:before{content:""}.fa-twitter:before{content:""}.fa-twitter-square:before{content:""}.fa-typo3:before{content:""}.fa-uber:before{content:""}.fa-ubuntu:before{content:""}.fa-uikit:before{content:""}.fa-umbraco:before{content:""}.fa-umbrella:before{content:""}.fa-umbrella-beach:before{content:""}.fa-underline:before{content:""}.fa-undo:before{content:""}.fa-undo-alt:before{content:""}.fa-uniregistry:before{content:""}.fa-unity:before{content:""}.fa-universal-access:before{content:""}.fa-university:before{content:""}.fa-unlink:before{content:""}.fa-unlock:before{content:""}.fa-unlock-alt:before{content:""}.fa-unsplash:before{content:""}.fa-untappd:before{content:""}.fa-upload:before{content:""}.fa-ups:before{content:""}.fa-usb:before{content:""}.fa-user:before{content:""}.fa-user-alt:before{content:""}.fa-user-alt-slash:before{content:""}.fa-user-astronaut:before{content:""}.fa-user-check:before{content:""}.fa-user-circle:before{content:""}.fa-user-clock:before{content:""}.fa-user-cog:before{content:""}.fa-user-edit:before{content:""}.fa-user-friends:before{content:""}.fa-user-graduate:before{content:""}.fa-user-injured:before{content:""}.fa-user-lock:before{content:""}.fa-user-md:before{content:""}.fa-user-minus:before{content:""}.fa-user-ninja:before{content:""}.fa-user-nurse:before{content:""}.fa-user-plus:before{content:""}.fa-user-secret:before{content:""}.fa-user-shield:before{content:""}.fa-user-slash:before{content:""}.fa-user-tag:before{content:""}.fa-user-tie:before{content:""}.fa-user-times:before{content:""}.fa-users:before{content:""}.fa-users-cog:before{content:""}.fa-users-slash:before{content:""}.fa-usps:before{content:""}.fa-ussunnah:before{content:""}.fa-utensil-spoon:before{content:""}.fa-utensils:before{content:""}.fa-vaadin:before{content:""}.fa-vector-square:before{content:""}.fa-venus:before{content:""}.fa-venus-double:before{content:""}.fa-venus-mars:before{content:""}.fa-viacoin:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-vial:before{content:""}.fa-vials:before{content:""}.fa-viber:before{content:""}.fa-video:before{content:""}.fa-video-slash:before{content:""}.fa-vihara:before{content:""}.fa-vimeo:before{content:""}.fa-vimeo-square:before{content:""}.fa-vimeo-v:before{content:""}.fa-vine:before{content:""}.fa-virus:before{content:""}.fa-virus-slash:before{content:""}.fa-viruses:before{content:""}.fa-vk:before{content:""}.fa-vnv:before{content:""}.fa-voicemail:before{content:""}.fa-volleyball-ball:before{content:""}.fa-volume-down:before{content:""}.fa-volume-mute:before{content:""}.fa-volume-off:before{content:""}.fa-volume-up:before{content:""}.fa-vote-yea:before{content:""}.fa-vr-cardboard:before{content:""}.fa-vuejs:before{content:""}.fa-walking:before{content:""}.fa-wallet:before{content:""}.fa-warehouse:before{content:""}.fa-water:before{content:""}.fa-wave-square:before{content:""}.fa-waze:before{content:""}.fa-weebly:before{content:""}.fa-weibo:before{content:""}.fa-weight:before{content:""}.fa-weight-hanging:before{content:""}.fa-weixin:before{content:""}.fa-whatsapp:before{content:""}.fa-whatsapp-square:before{content:""}.fa-wheelchair:before{content:""}.fa-whmcs:before{content:""}.fa-wifi:before{content:""}.fa-wikipedia-w:before{content:""}.fa-wind:before{content:""}.fa-window-close:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-windows:before{content:""}.fa-wine-bottle:before{content:""}.fa-wine-glass:before{content:""}.fa-wine-glass-alt:before{content:""}.fa-wix:before{content:""}.fa-wizards-of-the-coast:before{content:""}.fa-wolf-pack-battalion:before{content:""}.fa-won-sign:before{content:""}.fa-wordpress:before{content:""}.fa-wordpress-simple:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpexplorer:before{content:""}.fa-wpforms:before{content:""}.fa-wpressr:before{content:""}.fa-wrench:before{content:""}.fa-x-ray:before{content:""}.fa-xbox:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-y-combinator:before{content:""}.fa-yahoo:before{content:""}.fa-yammer:before{content:""}.fa-yandex:before{content:""}.fa-yandex-international:before{content:""}.fa-yarn:before{content:""}.fa-yelp:before{content:""}.fa-yen-sign:before{content:""}.fa-yin-yang:before{content:""}.fa-yoast:before{content:""}.fa-youtube:before{content:""}.fa-youtube-square:before{content:""}.fa-zhihu:before{content:""}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.converse-website converse-icon:before,.conversejs converse-icon:before{content:none!important}.converse-website .far:not(converse-icon),.conversejs .far:not(converse-icon){font-family:ConverseFontAwesomeRegular!important;font-weight:400}.converse-website .fa:not(converse-icon),.converse-website .fas:not(converse-icon),.conversejs .fa:not(converse-icon),.conversejs .fas:not(converse-icon){font-family:ConverseFontAwesomeSolid!important;font-weight:900}.converse-website .fab:not(converse-icon),.conversejs .fab:not(converse-icon){font-family:ConverseFontAwesomeBrands}.converse-website .fa:not(converse-icon),.converse-website .fab:not(converse-icon),.converse-website .far:not(converse-icon),.converse-website .fas:not(converse-icon),.conversejs .fa:not(converse-icon),.conversejs .fab:not(converse-icon),.conversejs .far:not(converse-icon),.conversejs .fas:not(converse-icon){display:inline-block;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.converse-website .fa-info-circle,.conversejs .fa-info-circle{height:1em}.conversejs :root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.conversejs *,.conversejs ::after,.conversejs ::before{box-sizing:border-box}.conversejs html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}.conversejs article,.conversejs aside,.conversejs figcaption,.conversejs figure,.conversejs footer,.conversejs header,.conversejs hgroup,.conversejs main,.conversejs nav,.conversejs section{display:block}.conversejs body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}.conversejs [tabindex="-1"]:focus:not(:focus-visible){outline:0!important}.conversejs hr{box-sizing:content-box;height:0;overflow:visible}.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6{margin-top:0;margin-bottom:.5rem}.conversejs p{margin-top:0;margin-bottom:1rem}.conversejs abbr[data-original-title],.conversejs abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}.conversejs address{margin-bottom:1rem;font-style:normal;line-height:inherit}.conversejs dl,.conversejs ol,.conversejs ul{margin-top:0;margin-bottom:1rem}.conversejs ol ol,.conversejs ol ul,.conversejs ul ol,.conversejs ul ul{margin-bottom:0}.conversejs dt{font-weight:700}.conversejs dd{margin-bottom:.5rem;margin-left:0}.conversejs blockquote{margin:0 0 1rem}.conversejs b,.conversejs strong{font-weight:bolder}.conversejs small{font-size:80%}.conversejs sub,.conversejs sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.conversejs sub{bottom:-.25em}.conversejs sup{top:-.5em}.conversejs a{color:#007bff;text-decoration:none;background-color:transparent}.conversejs a:hover{color:#0056b3;text-decoration:underline}.conversejs a:not([href]):not([class]){color:inherit;text-decoration:none}.conversejs a:not([href]):not([class]):hover{color:inherit;text-decoration:none}.conversejs code,.conversejs kbd,.conversejs pre,.conversejs samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}.conversejs pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}.conversejs figure{margin:0 0 1rem}.conversejs img{vertical-align:middle;border-style:none}.conversejs svg{overflow:hidden;vertical-align:middle}.conversejs table{border-collapse:collapse}.conversejs caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}.conversejs th{text-align:inherit;text-align:-webkit-match-parent}.conversejs label{display:inline-block;margin-bottom:.5rem}.conversejs button{border-radius:0}.conversejs button:focus:not(:focus-visible){outline:0}.conversejs button,.conversejs input,.conversejs optgroup,.conversejs select,.conversejs textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}.conversejs button,.conversejs input{overflow:visible}.conversejs button,.conversejs select{text-transform:none}.conversejs [role=button]{cursor:pointer}.conversejs select{word-wrap:normal}.conversejs [type=button],.conversejs [type=reset],.conversejs [type=submit],.conversejs button{-webkit-appearance:button}.conversejs [type=button]:not(:disabled),.conversejs [type=reset]:not(:disabled),.conversejs [type=submit]:not(:disabled),.conversejs button:not(:disabled){cursor:pointer}.conversejs [type=button]::-moz-focus-inner,.conversejs [type=reset]::-moz-focus-inner,.conversejs [type=submit]::-moz-focus-inner,.conversejs button::-moz-focus-inner{padding:0;border-style:none}.conversejs input[type=checkbox],.conversejs input[type=radio]{box-sizing:border-box;padding:0}.conversejs textarea{overflow:auto;resize:vertical}.conversejs fieldset{min-width:0;padding:0;margin:0;border:0}.conversejs legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}.conversejs progress{vertical-align:baseline}.conversejs [type=number]::-webkit-inner-spin-button,.conversejs [type=number]::-webkit-outer-spin-button{height:auto}.conversejs [type=search]{outline-offset:-2px;-webkit-appearance:none}.conversejs [type=search]::-webkit-search-decoration{-webkit-appearance:none}.conversejs ::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.conversejs output{display:inline-block}.conversejs summary{display:list-item;cursor:pointer}.conversejs template{display:none}.conversejs [hidden]{display:none!important}.conversejs .h1,.conversejs .h2,.conversejs .h3,.conversejs .h4,.conversejs .h5,.conversejs .h6,.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.conversejs .h1,.conversejs h1{font-size:2.5rem}.conversejs .h2,.conversejs h2{font-size:2rem}.conversejs .h3,.conversejs h3{font-size:1.75rem}.conversejs .h4,.conversejs h4{font-size:1.5rem}.conversejs .h5,.conversejs h5{font-size:1.25rem}.conversejs .h6,.conversejs h6{font-size:1rem}.conversejs .lead{font-size:1.25rem;font-weight:300}.conversejs .display-1{font-size:6rem;font-weight:300;line-height:1.2}.conversejs .display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.conversejs .display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.conversejs .display-4{font-size:3.5rem;font-weight:300;line-height:1.2}.conversejs hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.conversejs .small,.conversejs small{font-size:80%;font-weight:400}.conversejs .mark,.conversejs mark{padding:.2em;background-color:#fcf8e3}.conversejs .list-unstyled{padding-left:0;list-style:none}.conversejs .list-inline{padding-left:0;list-style:none}.conversejs .list-inline-item{display:inline-block}.conversejs .list-inline-item:not(:last-child){margin-right:.5rem}.conversejs .initialism{font-size:90%;text-transform:uppercase}.conversejs .blockquote{margin-bottom:1rem;font-size:1.25rem}.conversejs .blockquote-footer{display:block;font-size:80%;color:#6c757d}.conversejs .blockquote-footer::before{content:"— "}.conversejs .img-fluid{max-width:100%;height:auto}.conversejs .img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.conversejs .figure{display:inline-block}.conversejs .figure-img{margin-bottom:.5rem;line-height:1}.conversejs .figure-caption{font-size:90%;color:#6c757d}.conversejs .container,.conversejs .container-fluid,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm,.conversejs .container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media(min-width:576px){.conversejs .container,.conversejs .container-sm{max-width:540px}}@media(min-width:768px){.conversejs .container,.conversejs .container-md,.conversejs .container-sm{max-width:720px}}@media(min-width:992px){.conversejs .container,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm{max-width:960px}}@media(min-width:1200px){.conversejs .container,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm,.conversejs .container-xl{max-width:1140px}}.conversejs .row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.conversejs .no-gutters{margin-right:0;margin-left:0}.conversejs .no-gutters>.col,.conversejs .no-gutters>[class*=col-]{padding-right:0;padding-left:0}.conversejs .col,.conversejs .col-1,.conversejs .col-10,.conversejs .col-11,.conversejs .col-12,.conversejs .col-2,.conversejs .col-3,.conversejs .col-4,.conversejs .col-5,.conversejs .col-6,.conversejs .col-7,.conversejs .col-8,.conversejs .col-9,.conversejs .col-auto,.conversejs .col-lg,.conversejs .col-lg-1,.conversejs .col-lg-10,.conversejs .col-lg-11,.conversejs .col-lg-12,.conversejs .col-lg-2,.conversejs .col-lg-3,.conversejs .col-lg-4,.conversejs .col-lg-5,.conversejs .col-lg-6,.conversejs .col-lg-7,.conversejs .col-lg-8,.conversejs .col-lg-9,.conversejs .col-lg-auto,.conversejs .col-md,.conversejs .col-md-1,.conversejs .col-md-10,.conversejs .col-md-11,.conversejs .col-md-12,.conversejs .col-md-2,.conversejs .col-md-3,.conversejs .col-md-4,.conversejs .col-md-5,.conversejs .col-md-6,.conversejs .col-md-7,.conversejs .col-md-8,.conversejs .col-md-9,.conversejs .col-md-auto,.conversejs .col-sm,.conversejs .col-sm-1,.conversejs .col-sm-10,.conversejs .col-sm-11,.conversejs .col-sm-12,.conversejs .col-sm-2,.conversejs .col-sm-3,.conversejs .col-sm-4,.conversejs .col-sm-5,.conversejs .col-sm-6,.conversejs .col-sm-7,.conversejs .col-sm-8,.conversejs .col-sm-9,.conversejs .col-sm-auto,.conversejs .col-xl,.conversejs .col-xl-1,.conversejs .col-xl-10,.conversejs .col-xl-11,.conversejs .col-xl-12,.conversejs .col-xl-2,.conversejs .col-xl-3,.conversejs .col-xl-4,.conversejs .col-xl-5,.conversejs .col-xl-6,.conversejs .col-xl-7,.conversejs .col-xl-8,.conversejs .col-xl-9,.conversejs .col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.conversejs .col{flex-basis:0;flex-grow:1;max-width:100%}.conversejs .row-cols-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-md-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-md-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-md-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-md-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.conversejs .fade{transition:none}}.conversejs .fade:not(.show){opacity:0}.conversejs .collapse:not(.show){display:none}.conversejs .collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.conversejs .collapsing{transition:none}}.conversejs .nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.conversejs .nav-link{display:block;padding:.5rem 1rem}.conversejs .nav-link:focus,.conversejs .nav-link:hover{text-decoration:none}.conversejs .nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.conversejs .nav-tabs{border-bottom:1px solid #dee2e6}.conversejs .nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.conversejs .nav-tabs .nav-link:focus,.conversejs .nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.conversejs .nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.conversejs .nav-tabs .nav-item.show .nav-link,.conversejs .nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.conversejs .nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.conversejs .nav-pills .nav-link{border-radius:.25rem}.conversejs .nav-pills .nav-link.active,.conversejs .nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.conversejs .nav-fill .nav-item,.conversejs .nav-fill>.nav-link{flex:1 1 auto;text-align:center}.conversejs .nav-justified .nav-item,.conversejs .nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.conversejs .tab-content>.tab-pane{display:none}.conversejs .tab-content>.active{display:block}.conversejs .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.conversejs .alert-heading{color:inherit}.conversejs .alert-link{font-weight:700}.conversejs .alert-dismissible{padding-right:4rem}.conversejs .alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.conversejs .alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.conversejs .alert-primary hr{border-top-color:#9fcdff}.conversejs .alert-primary .alert-link{color:#002752}.conversejs .alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.conversejs .alert-secondary hr{border-top-color:#c8cbcf}.conversejs .alert-secondary .alert-link{color:#202326}.conversejs .alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.conversejs .alert-success hr{border-top-color:#b1dfbb}.conversejs .alert-success .alert-link{color:#0b2e13}.conversejs .alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.conversejs .alert-info hr{border-top-color:#abdde5}.conversejs .alert-info .alert-link{color:#062c33}.conversejs .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.conversejs .alert-warning hr{border-top-color:#ffe8a1}.conversejs .alert-warning .alert-link{color:#533f03}.conversejs .alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.conversejs .alert-danger hr{border-top-color:#f1b0b7}.conversejs .alert-danger .alert-link{color:#491217}.conversejs .alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.conversejs .alert-light hr{border-top-color:#ececf6}.conversejs .alert-light .alert-link{color:#686868}.conversejs .alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.conversejs .alert-dark hr{border-top-color:#b9bbbe}.conversejs .alert-dark .alert-link{color:#040505}.conversejs .media{display:flex;align-items:flex-start}.conversejs .media-body{flex:1}.conversejs .close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.conversejs .close:hover{color:#000;text-decoration:none}.conversejs .close:not(:disabled):not(.disabled):focus,.conversejs .close:not(:disabled):not(.disabled):hover{opacity:.75}.conversejs button.close{padding:0;background-color:transparent;border:0}.conversejs a.close.disabled{pointer-events:none}.conversejs .popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.conversejs .popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.conversejs .popover .arrow::after,.conversejs .popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.conversejs .bs-popover-auto[x-placement^=top],.conversejs .bs-popover-top{margin-bottom:.5rem}.conversejs .bs-popover-auto[x-placement^=top]>.arrow,.conversejs .bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.conversejs .bs-popover-auto[x-placement^=top]>.arrow::before,.conversejs .bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=top]>.arrow::after,.conversejs .bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.conversejs .bs-popover-auto[x-placement^=right],.conversejs .bs-popover-right{margin-left:.5rem}.conversejs .bs-popover-auto[x-placement^=right]>.arrow,.conversejs .bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.conversejs .bs-popover-auto[x-placement^=right]>.arrow::before,.conversejs .bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=right]>.arrow::after,.conversejs .bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.conversejs .bs-popover-auto[x-placement^=bottom],.conversejs .bs-popover-bottom{margin-top:.5rem}.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow,.conversejs .bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::before,.conversejs .bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::after,.conversejs .bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.conversejs .bs-popover-auto[x-placement^=bottom] .popover-header::before,.conversejs .bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.conversejs .bs-popover-auto[x-placement^=left],.conversejs .bs-popover-left{margin-right:.5rem}.conversejs .bs-popover-auto[x-placement^=left]>.arrow,.conversejs .bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.conversejs .bs-popover-auto[x-placement^=left]>.arrow::before,.conversejs .bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=left]>.arrow::after,.conversejs .bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.conversejs .popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.conversejs .popover-header:empty{display:none}.conversejs .popover-body{padding:.5rem .75rem;color:#212529}.conversejs .align-baseline{vertical-align:baseline!important}.conversejs .align-top{vertical-align:top!important}.conversejs .align-middle{vertical-align:middle!important}.conversejs .align-bottom{vertical-align:bottom!important}.conversejs .align-text-bottom{vertical-align:text-bottom!important}.conversejs .align-text-top{vertical-align:text-top!important}.conversejs .bg-primary{background-color:#007bff!important}.conversejs a.bg-primary:focus,.conversejs a.bg-primary:hover,.conversejs button.bg-primary:focus,.conversejs button.bg-primary:hover{background-color:#0062cc!important}.conversejs .bg-secondary{background-color:#6c757d!important}.conversejs a.bg-secondary:focus,.conversejs a.bg-secondary:hover,.conversejs button.bg-secondary:focus,.conversejs button.bg-secondary:hover{background-color:#545b62!important}.conversejs .bg-success{background-color:#28a745!important}.conversejs a.bg-success:focus,.conversejs a.bg-success:hover,.conversejs button.bg-success:focus,.conversejs button.bg-success:hover{background-color:#1e7e34!important}.conversejs .bg-info{background-color:#17a2b8!important}.conversejs a.bg-info:focus,.conversejs a.bg-info:hover,.conversejs button.bg-info:focus,.conversejs button.bg-info:hover{background-color:#117a8b!important}.conversejs .bg-warning{background-color:#ffc107!important}.conversejs a.bg-warning:focus,.conversejs a.bg-warning:hover,.conversejs button.bg-warning:focus,.conversejs button.bg-warning:hover{background-color:#d39e00!important}.conversejs .bg-danger{background-color:#dc3545!important}.conversejs a.bg-danger:focus,.conversejs a.bg-danger:hover,.conversejs button.bg-danger:focus,.conversejs button.bg-danger:hover{background-color:#bd2130!important}.conversejs .bg-light{background-color:#f8f9fa!important}.conversejs a.bg-light:focus,.conversejs a.bg-light:hover,.conversejs button.bg-light:focus,.conversejs button.bg-light:hover{background-color:#dae0e5!important}.conversejs .bg-dark{background-color:#343a40!important}.conversejs a.bg-dark:focus,.conversejs a.bg-dark:hover,.conversejs button.bg-dark:focus,.conversejs button.bg-dark:hover{background-color:#1d2124!important}.conversejs .bg-white{background-color:#fff!important}.conversejs .bg-transparent{background-color:transparent!important}.conversejs .border{border:1px solid #dee2e6!important}.conversejs .border-top{border-top:1px solid #dee2e6!important}.conversejs .border-right{border-right:1px solid #dee2e6!important}.conversejs .border-bottom{border-bottom:1px solid #dee2e6!important}.conversejs .border-left{border-left:1px solid #dee2e6!important}.conversejs .border-0{border:0!important}.conversejs .border-top-0{border-top:0!important}.conversejs .border-right-0{border-right:0!important}.conversejs .border-bottom-0{border-bottom:0!important}.conversejs .border-left-0{border-left:0!important}.conversejs .border-primary{border-color:#007bff!important}.conversejs .border-secondary{border-color:#6c757d!important}.conversejs .border-success{border-color:#28a745!important}.conversejs .border-info{border-color:#17a2b8!important}.conversejs .border-warning{border-color:#ffc107!important}.conversejs .border-danger{border-color:#dc3545!important}.conversejs .border-light{border-color:#f8f9fa!important}.conversejs .border-dark{border-color:#343a40!important}.conversejs .border-white{border-color:#fff!important}.conversejs .rounded-sm{border-radius:.2rem!important}.conversejs .rounded{border-radius:.25rem!important}.conversejs .rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.conversejs .rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.conversejs .rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.conversejs .rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.conversejs .rounded-lg{border-radius:.3rem!important}.conversejs .rounded-circle{border-radius:50%!important}.conversejs .rounded-pill{border-radius:50rem!important}.conversejs .rounded-0{border-radius:0!important}.conversejs .clearfix::after{display:block;clear:both;content:""}.conversejs .d-none{display:none!important}.conversejs .d-inline{display:inline!important}.conversejs .d-inline-block{display:inline-block!important}.conversejs .d-block{display:block!important}.conversejs .d-table{display:table!important}.conversejs .d-table-row{display:table-row!important}.conversejs .d-table-cell{display:table-cell!important}.conversejs .d-flex{display:flex!important}.conversejs .d-inline-flex{display:inline-flex!important}@media(min-width:576px){.conversejs .d-sm-none{display:none!important}.conversejs .d-sm-inline{display:inline!important}.conversejs .d-sm-inline-block{display:inline-block!important}.conversejs .d-sm-block{display:block!important}.conversejs .d-sm-table{display:table!important}.conversejs .d-sm-table-row{display:table-row!important}.conversejs .d-sm-table-cell{display:table-cell!important}.conversejs .d-sm-flex{display:flex!important}.conversejs .d-sm-inline-flex{display:inline-flex!important}}@media(min-width:768px){.conversejs .d-md-none{display:none!important}.conversejs .d-md-inline{display:inline!important}.conversejs .d-md-inline-block{display:inline-block!important}.conversejs .d-md-block{display:block!important}.conversejs .d-md-table{display:table!important}.conversejs .d-md-table-row{display:table-row!important}.conversejs .d-md-table-cell{display:table-cell!important}.conversejs .d-md-flex{display:flex!important}.conversejs .d-md-inline-flex{display:inline-flex!important}}@media(min-width:992px){.conversejs .d-lg-none{display:none!important}.conversejs .d-lg-inline{display:inline!important}.conversejs .d-lg-inline-block{display:inline-block!important}.conversejs .d-lg-block{display:block!important}.conversejs .d-lg-table{display:table!important}.conversejs .d-lg-table-row{display:table-row!important}.conversejs .d-lg-table-cell{display:table-cell!important}.conversejs .d-lg-flex{display:flex!important}.conversejs .d-lg-inline-flex{display:inline-flex!important}}@media(min-width:1200px){.conversejs .d-xl-none{display:none!important}.conversejs .d-xl-inline{display:inline!important}.conversejs .d-xl-inline-block{display:inline-block!important}.conversejs .d-xl-block{display:block!important}.conversejs .d-xl-table{display:table!important}.conversejs .d-xl-table-row{display:table-row!important}.conversejs .d-xl-table-cell{display:table-cell!important}.conversejs .d-xl-flex{display:flex!important}.conversejs .d-xl-inline-flex{display:inline-flex!important}}@media print{.conversejs .d-print-none{display:none!important}.conversejs .d-print-inline{display:inline!important}.conversejs .d-print-inline-block{display:inline-block!important}.conversejs .d-print-block{display:block!important}.conversejs .d-print-table{display:table!important}.conversejs .d-print-table-row{display:table-row!important}.conversejs .d-print-table-cell{display:table-cell!important}.conversejs .d-print-flex{display:flex!important}.conversejs .d-print-inline-flex{display:inline-flex!important}}.conversejs .embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.conversejs .embed-responsive::before{display:block;content:""}.conversejs .embed-responsive .embed-responsive-item,.conversejs .embed-responsive embed,.conversejs .embed-responsive iframe,.conversejs .embed-responsive object,.conversejs .embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.conversejs .embed-responsive-21by9::before{padding-top:42.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 .flex-fill{flex:1 1 auto!important}.conversejs .flex-grow-0{flex-grow:0!important}.conversejs .flex-grow-1{flex-grow:1!important}.conversejs .flex-shrink-0{flex-shrink:0!important}.conversejs .flex-shrink-1{flex-shrink:1!important}.conversejs .justify-content-start{justify-content:flex-start!important}.conversejs .justify-content-end{justify-content:flex-end!important}.conversejs .justify-content-center{justify-content:center!important}.conversejs .justify-content-between{justify-content:space-between!important}.conversejs .justify-content-around{justify-content:space-around!important}.conversejs .align-items-start{align-items:flex-start!important}.conversejs .align-items-end{align-items:flex-end!important}.conversejs .align-items-center{align-items:center!important}.conversejs .align-items-baseline{align-items:baseline!important}.conversejs .align-items-stretch{align-items:stretch!important}.conversejs .align-content-start{align-content:flex-start!important}.conversejs .align-content-end{align-content:flex-end!important}.conversejs .align-content-center{align-content:center!important}.conversejs .align-content-between{align-content:space-between!important}.conversejs .align-content-around{align-content:space-around!important}.conversejs .align-content-stretch{align-content:stretch!important}.conversejs .align-self-auto{align-self:auto!important}.conversejs .align-self-start{align-self:flex-start!important}.conversejs .align-self-end{align-self:flex-end!important}.conversejs .align-self-center{align-self:center!important}.conversejs .align-self-baseline{align-self:baseline!important}.conversejs .align-self-stretch{align-self:stretch!important}@media(min-width:576px){.conversejs .flex-sm-row{flex-direction:row!important}.conversejs .flex-sm-column{flex-direction:column!important}.conversejs .flex-sm-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-sm-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-sm-wrap{flex-wrap:wrap!important}.conversejs .flex-sm-nowrap{flex-wrap:nowrap!important}.conversejs .flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-sm-fill{flex:1 1 auto!important}.conversejs .flex-sm-grow-0{flex-grow:0!important}.conversejs .flex-sm-grow-1{flex-grow:1!important}.conversejs .flex-sm-shrink-0{flex-shrink:0!important}.conversejs .flex-sm-shrink-1{flex-shrink:1!important}.conversejs .justify-content-sm-start{justify-content:flex-start!important}.conversejs .justify-content-sm-end{justify-content:flex-end!important}.conversejs .justify-content-sm-center{justify-content:center!important}.conversejs .justify-content-sm-between{justify-content:space-between!important}.conversejs .justify-content-sm-around{justify-content:space-around!important}.conversejs .align-items-sm-start{align-items:flex-start!important}.conversejs .align-items-sm-end{align-items:flex-end!important}.conversejs .align-items-sm-center{align-items:center!important}.conversejs .align-items-sm-baseline{align-items:baseline!important}.conversejs .align-items-sm-stretch{align-items:stretch!important}.conversejs .align-content-sm-start{align-content:flex-start!important}.conversejs .align-content-sm-end{align-content:flex-end!important}.conversejs .align-content-sm-center{align-content:center!important}.conversejs .align-content-sm-between{align-content:space-between!important}.conversejs .align-content-sm-around{align-content:space-around!important}.conversejs .align-content-sm-stretch{align-content:stretch!important}.conversejs .align-self-sm-auto{align-self:auto!important}.conversejs .align-self-sm-start{align-self:flex-start!important}.conversejs .align-self-sm-end{align-self:flex-end!important}.conversejs .align-self-sm-center{align-self:center!important}.conversejs .align-self-sm-baseline{align-self:baseline!important}.conversejs .align-self-sm-stretch{align-self:stretch!important}}@media(min-width:768px){.conversejs .flex-md-row{flex-direction:row!important}.conversejs .flex-md-column{flex-direction:column!important}.conversejs .flex-md-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-md-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-md-wrap{flex-wrap:wrap!important}.conversejs .flex-md-nowrap{flex-wrap:nowrap!important}.conversejs .flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-md-fill{flex:1 1 auto!important}.conversejs .flex-md-grow-0{flex-grow:0!important}.conversejs .flex-md-grow-1{flex-grow:1!important}.conversejs .flex-md-shrink-0{flex-shrink:0!important}.conversejs .flex-md-shrink-1{flex-shrink:1!important}.conversejs .justify-content-md-start{justify-content:flex-start!important}.conversejs .justify-content-md-end{justify-content:flex-end!important}.conversejs .justify-content-md-center{justify-content:center!important}.conversejs .justify-content-md-between{justify-content:space-between!important}.conversejs .justify-content-md-around{justify-content:space-around!important}.conversejs .align-items-md-start{align-items:flex-start!important}.conversejs .align-items-md-end{align-items:flex-end!important}.conversejs .align-items-md-center{align-items:center!important}.conversejs .align-items-md-baseline{align-items:baseline!important}.conversejs .align-items-md-stretch{align-items:stretch!important}.conversejs .align-content-md-start{align-content:flex-start!important}.conversejs .align-content-md-end{align-content:flex-end!important}.conversejs .align-content-md-center{align-content:center!important}.conversejs .align-content-md-between{align-content:space-between!important}.conversejs .align-content-md-around{align-content:space-around!important}.conversejs .align-content-md-stretch{align-content:stretch!important}.conversejs .align-self-md-auto{align-self:auto!important}.conversejs .align-self-md-start{align-self:flex-start!important}.conversejs .align-self-md-end{align-self:flex-end!important}.conversejs .align-self-md-center{align-self:center!important}.conversejs .align-self-md-baseline{align-self:baseline!important}.conversejs .align-self-md-stretch{align-self:stretch!important}}@media(min-width:992px){.conversejs .flex-lg-row{flex-direction:row!important}.conversejs .flex-lg-column{flex-direction:column!important}.conversejs .flex-lg-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-lg-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-lg-wrap{flex-wrap:wrap!important}.conversejs .flex-lg-nowrap{flex-wrap:nowrap!important}.conversejs .flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-lg-fill{flex:1 1 auto!important}.conversejs .flex-lg-grow-0{flex-grow:0!important}.conversejs .flex-lg-grow-1{flex-grow:1!important}.conversejs .flex-lg-shrink-0{flex-shrink:0!important}.conversejs .flex-lg-shrink-1{flex-shrink:1!important}.conversejs .justify-content-lg-start{justify-content:flex-start!important}.conversejs .justify-content-lg-end{justify-content:flex-end!important}.conversejs .justify-content-lg-center{justify-content:center!important}.conversejs .justify-content-lg-between{justify-content:space-between!important}.conversejs .justify-content-lg-around{justify-content:space-around!important}.conversejs .align-items-lg-start{align-items:flex-start!important}.conversejs .align-items-lg-end{align-items:flex-end!important}.conversejs .align-items-lg-center{align-items:center!important}.conversejs .align-items-lg-baseline{align-items:baseline!important}.conversejs .align-items-lg-stretch{align-items:stretch!important}.conversejs .align-content-lg-start{align-content:flex-start!important}.conversejs .align-content-lg-end{align-content:flex-end!important}.conversejs .align-content-lg-center{align-content:center!important}.conversejs .align-content-lg-between{align-content:space-between!important}.conversejs .align-content-lg-around{align-content:space-around!important}.conversejs .align-content-lg-stretch{align-content:stretch!important}.conversejs .align-self-lg-auto{align-self:auto!important}.conversejs .align-self-lg-start{align-self:flex-start!important}.conversejs .align-self-lg-end{align-self:flex-end!important}.conversejs .align-self-lg-center{align-self:center!important}.conversejs .align-self-lg-baseline{align-self:baseline!important}.conversejs .align-self-lg-stretch{align-self:stretch!important}}@media(min-width:1200px){.conversejs .flex-xl-row{flex-direction:row!important}.conversejs .flex-xl-column{flex-direction:column!important}.conversejs .flex-xl-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-xl-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-xl-wrap{flex-wrap:wrap!important}.conversejs .flex-xl-nowrap{flex-wrap:nowrap!important}.conversejs .flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-xl-fill{flex:1 1 auto!important}.conversejs .flex-xl-grow-0{flex-grow:0!important}.conversejs .flex-xl-grow-1{flex-grow:1!important}.conversejs .flex-xl-shrink-0{flex-shrink:0!important}.conversejs .flex-xl-shrink-1{flex-shrink:1!important}.conversejs .justify-content-xl-start{justify-content:flex-start!important}.conversejs .justify-content-xl-end{justify-content:flex-end!important}.conversejs .justify-content-xl-center{justify-content:center!important}.conversejs .justify-content-xl-between{justify-content:space-between!important}.conversejs .justify-content-xl-around{justify-content:space-around!important}.conversejs .align-items-xl-start{align-items:flex-start!important}.conversejs .align-items-xl-end{align-items:flex-end!important}.conversejs .align-items-xl-center{align-items:center!important}.conversejs .align-items-xl-baseline{align-items:baseline!important}.conversejs .align-items-xl-stretch{align-items:stretch!important}.conversejs .align-content-xl-start{align-content:flex-start!important}.conversejs .align-content-xl-end{align-content:flex-end!important}.conversejs .align-content-xl-center{align-content:center!important}.conversejs .align-content-xl-between{align-content:space-between!important}.conversejs .align-content-xl-around{align-content:space-around!important}.conversejs .align-content-xl-stretch{align-content:stretch!important}.conversejs .align-self-xl-auto{align-self:auto!important}.conversejs .align-self-xl-start{align-self:flex-start!important}.conversejs .align-self-xl-end{align-self:flex-end!important}.conversejs .align-self-xl-center{align-self:center!important}.conversejs .align-self-xl-baseline{align-self:baseline!important}.conversejs .align-self-xl-stretch{align-self:stretch!important}}.conversejs .float-left{float:left!important}.conversejs .float-right{float:right!important}.conversejs .float-none{float:none!important}@media(min-width:576px){.conversejs .float-sm-left{float:left!important}.conversejs .float-sm-right{float:right!important}.conversejs .float-sm-none{float:none!important}}@media(min-width:768px){.conversejs .float-md-left{float:left!important}.conversejs .float-md-right{float:right!important}.conversejs .float-md-none{float:none!important}}@media(min-width:992px){.conversejs .float-lg-left{float:left!important}.conversejs .float-lg-right{float:right!important}.conversejs .float-lg-none{float:none!important}}@media(min-width:1200px){.conversejs .float-xl-left{float:left!important}.conversejs .float-xl-right{float:right!important}.conversejs .float-xl-none{float:none!important}}.conversejs .user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.conversejs .user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.conversejs .user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.conversejs .overflow-auto{overflow:auto!important}.conversejs .overflow-hidden{overflow:hidden!important}.conversejs .position-static{position:static!important}.conversejs .position-relative{position:relative!important}.conversejs .position-absolute{position:absolute!important}.conversejs .position-fixed{position:fixed!important}.conversejs .position-sticky{position: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;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.conversejs .sr-only-focusable:active,.conversejs .sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.conversejs .shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.conversejs .shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.conversejs .shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.conversejs .shadow-none{box-shadow:none!important}.conversejs .w-25{width:25%!important}.conversejs .w-50{width:50%!important}.conversejs .w-75{width:75%!important}.conversejs .w-100{width:100%!important}.conversejs .w-auto{width:auto!important}.conversejs .h-25{height:25%!important}.conversejs .h-50{height:50%!important}.conversejs .h-75{height:75%!important}.conversejs .h-100{height:100%!important}.conversejs .h-auto{height:auto!important}.conversejs .mw-100{max-width:100%!important}.conversejs .mh-100{max-height:100%!important}.conversejs .min-vw-100{min-width:100vw!important}.conversejs .min-vh-100{min-height:100vh!important}.conversejs .vw-100{width:100vw!important}.conversejs .vh-100{height:100vh!important}.conversejs .m-0{margin:0!important}.conversejs .mt-0,.conversejs .my-0{margin-top:0!important}.conversejs .mr-0,.conversejs .mx-0{margin-right:0!important}.conversejs .mb-0,.conversejs .my-0{margin-bottom:0!important}.conversejs .ml-0,.conversejs .mx-0{margin-left:0!important}.conversejs .m-1{margin:.25rem!important}.conversejs .mt-1,.conversejs .my-1{margin-top:.25rem!important}.conversejs .mr-1,.conversejs .mx-1{margin-right:.25rem!important}.conversejs .mb-1,.conversejs .my-1{margin-bottom:.25rem!important}.conversejs .ml-1,.conversejs .mx-1{margin-left:.25rem!important}.conversejs .m-2{margin:.5rem!important}.conversejs .mt-2,.conversejs .my-2{margin-top:.5rem!important}.conversejs .mr-2,.conversejs .mx-2{margin-right:.5rem!important}.conversejs .mb-2,.conversejs .my-2{margin-bottom:.5rem!important}.conversejs .ml-2,.conversejs .mx-2{margin-left:.5rem!important}.conversejs .m-3{margin:1rem!important}.conversejs .mt-3,.conversejs .my-3{margin-top:1rem!important}.conversejs .mr-3,.conversejs .mx-3{margin-right:1rem!important}.conversejs .mb-3,.conversejs .my-3{margin-bottom:1rem!important}.conversejs .ml-3,.conversejs .mx-3{margin-left:1rem!important}.conversejs .m-4{margin:1.5rem!important}.conversejs .mt-4,.conversejs .my-4{margin-top:1.5rem!important}.conversejs .mr-4,.conversejs .mx-4{margin-right:1.5rem!important}.conversejs .mb-4,.conversejs .my-4{margin-bottom:1.5rem!important}.conversejs .ml-4,.conversejs .mx-4{margin-left:1.5rem!important}.conversejs .m-5{margin:3rem!important}.conversejs .mt-5,.conversejs .my-5{margin-top:3rem!important}.conversejs .mr-5,.conversejs .mx-5{margin-right:3rem!important}.conversejs .mb-5,.conversejs .my-5{margin-bottom:3rem!important}.conversejs .ml-5,.conversejs .mx-5{margin-left:3rem!important}.conversejs .p-0{padding:0!important}.conversejs .pt-0,.conversejs .py-0{padding-top:0!important}.conversejs .pr-0,.conversejs .px-0{padding-right:0!important}.conversejs .pb-0,.conversejs .py-0{padding-bottom:0!important}.conversejs .pl-0,.conversejs .px-0{padding-left:0!important}.conversejs .p-1{padding:.25rem!important}.conversejs .pt-1,.conversejs .py-1{padding-top:.25rem!important}.conversejs .pr-1,.conversejs .px-1{padding-right:.25rem!important}.conversejs .pb-1,.conversejs .py-1{padding-bottom:.25rem!important}.conversejs .pl-1,.conversejs .px-1{padding-left:.25rem!important}.conversejs .p-2{padding:.5rem!important}.conversejs .pt-2,.conversejs .py-2{padding-top:.5rem!important}.conversejs .pr-2,.conversejs .px-2{padding-right:.5rem!important}.conversejs .pb-2,.conversejs .py-2{padding-bottom:.5rem!important}.conversejs .pl-2,.conversejs .px-2{padding-left:.5rem!important}.conversejs .p-3{padding:1rem!important}.conversejs .pt-3,.conversejs .py-3{padding-top:1rem!important}.conversejs .pr-3,.conversejs .px-3{padding-right:1rem!important}.conversejs .pb-3,.conversejs .py-3{padding-bottom:1rem!important}.conversejs .pl-3,.conversejs .px-3{padding-left:1rem!important}.conversejs .p-4{padding:1.5rem!important}.conversejs .pt-4,.conversejs .py-4{padding-top:1.5rem!important}.conversejs .pr-4,.conversejs .px-4{padding-right:1.5rem!important}.conversejs .pb-4,.conversejs .py-4{padding-bottom:1.5rem!important}.conversejs .pl-4,.conversejs .px-4{padding-left:1.5rem!important}.conversejs .p-5{padding:3rem!important}.conversejs .pt-5,.conversejs .py-5{padding-top:3rem!important}.conversejs .pr-5,.conversejs .px-5{padding-right:3rem!important}.conversejs .pb-5,.conversejs .py-5{padding-bottom:3rem!important}.conversejs .pl-5,.conversejs .px-5{padding-left:3rem!important}.conversejs .m-n1{margin:-.25rem!important}.conversejs .mt-n1,.conversejs .my-n1{margin-top:-.25rem!important}.conversejs .mr-n1,.conversejs .mx-n1{margin-right:-.25rem!important}.conversejs .mb-n1,.conversejs .my-n1{margin-bottom:-.25rem!important}.conversejs .ml-n1,.conversejs .mx-n1{margin-left:-.25rem!important}.conversejs .m-n2{margin:-.5rem!important}.conversejs .mt-n2,.conversejs .my-n2{margin-top:-.5rem!important}.conversejs .mr-n2,.conversejs .mx-n2{margin-right:-.5rem!important}.conversejs .mb-n2,.conversejs .my-n2{margin-bottom:-.5rem!important}.conversejs .ml-n2,.conversejs .mx-n2{margin-left:-.5rem!important}.conversejs .m-n3{margin:-1rem!important}.conversejs .mt-n3,.conversejs .my-n3{margin-top:-1rem!important}.conversejs .mr-n3,.conversejs .mx-n3{margin-right:-1rem!important}.conversejs .mb-n3,.conversejs .my-n3{margin-bottom:-1rem!important}.conversejs .ml-n3,.conversejs .mx-n3{margin-left:-1rem!important}.conversejs .m-n4{margin:-1.5rem!important}.conversejs .mt-n4,.conversejs .my-n4{margin-top:-1.5rem!important}.conversejs .mr-n4,.conversejs .mx-n4{margin-right:-1.5rem!important}.conversejs .mb-n4,.conversejs .my-n4{margin-bottom:-1.5rem!important}.conversejs .ml-n4,.conversejs .mx-n4{margin-left:-1.5rem!important}.conversejs .m-n5{margin:-3rem!important}.conversejs .mt-n5,.conversejs .my-n5{margin-top:-3rem!important}.conversejs .mr-n5,.conversejs .mx-n5{margin-right:-3rem!important}.conversejs .mb-n5,.conversejs .my-n5{margin-bottom:-3rem!important}.conversejs .ml-n5,.conversejs .mx-n5{margin-left:-3rem!important}.conversejs .m-auto{margin:auto!important}.conversejs .mt-auto,.conversejs .my-auto{margin-top:auto!important}.conversejs .mr-auto,.conversejs .mx-auto{margin-right:auto!important}.conversejs .mb-auto,.conversejs .my-auto{margin-bottom:auto!important}.conversejs .ml-auto,.conversejs .mx-auto{margin-left:auto!important}@media(min-width:576px){.conversejs .m-sm-0{margin:0!important}.conversejs .mt-sm-0,.conversejs .my-sm-0{margin-top:0!important}.conversejs .mr-sm-0,.conversejs .mx-sm-0{margin-right:0!important}.conversejs .mb-sm-0,.conversejs .my-sm-0{margin-bottom:0!important}.conversejs .ml-sm-0,.conversejs .mx-sm-0{margin-left:0!important}.conversejs .m-sm-1{margin:.25rem!important}.conversejs .mt-sm-1,.conversejs .my-sm-1{margin-top:.25rem!important}.conversejs .mr-sm-1,.conversejs .mx-sm-1{margin-right:.25rem!important}.conversejs .mb-sm-1,.conversejs .my-sm-1{margin-bottom:.25rem!important}.conversejs .ml-sm-1,.conversejs .mx-sm-1{margin-left:.25rem!important}.conversejs .m-sm-2{margin:.5rem!important}.conversejs .mt-sm-2,.conversejs .my-sm-2{margin-top:.5rem!important}.conversejs .mr-sm-2,.conversejs .mx-sm-2{margin-right:.5rem!important}.conversejs .mb-sm-2,.conversejs .my-sm-2{margin-bottom:.5rem!important}.conversejs .ml-sm-2,.conversejs .mx-sm-2{margin-left:.5rem!important}.conversejs .m-sm-3{margin:1rem!important}.conversejs .mt-sm-3,.conversejs .my-sm-3{margin-top:1rem!important}.conversejs .mr-sm-3,.conversejs .mx-sm-3{margin-right:1rem!important}.conversejs .mb-sm-3,.conversejs .my-sm-3{margin-bottom:1rem!important}.conversejs .ml-sm-3,.conversejs .mx-sm-3{margin-left:1rem!important}.conversejs .m-sm-4{margin:1.5rem!important}.conversejs .mt-sm-4,.conversejs .my-sm-4{margin-top:1.5rem!important}.conversejs .mr-sm-4,.conversejs .mx-sm-4{margin-right:1.5rem!important}.conversejs .mb-sm-4,.conversejs .my-sm-4{margin-bottom:1.5rem!important}.conversejs .ml-sm-4,.conversejs .mx-sm-4{margin-left:1.5rem!important}.conversejs .m-sm-5{margin:3rem!important}.conversejs .mt-sm-5,.conversejs .my-sm-5{margin-top:3rem!important}.conversejs .mr-sm-5,.conversejs .mx-sm-5{margin-right:3rem!important}.conversejs .mb-sm-5,.conversejs .my-sm-5{margin-bottom:3rem!important}.conversejs .ml-sm-5,.conversejs .mx-sm-5{margin-left:3rem!important}.conversejs .p-sm-0{padding:0!important}.conversejs .pt-sm-0,.conversejs .py-sm-0{padding-top:0!important}.conversejs .pr-sm-0,.conversejs .px-sm-0{padding-right:0!important}.conversejs .pb-sm-0,.conversejs .py-sm-0{padding-bottom:0!important}.conversejs .pl-sm-0,.conversejs .px-sm-0{padding-left:0!important}.conversejs .p-sm-1{padding:.25rem!important}.conversejs .pt-sm-1,.conversejs .py-sm-1{padding-top:.25rem!important}.conversejs .pr-sm-1,.conversejs .px-sm-1{padding-right:.25rem!important}.conversejs .pb-sm-1,.conversejs .py-sm-1{padding-bottom:.25rem!important}.conversejs .pl-sm-1,.conversejs .px-sm-1{padding-left:.25rem!important}.conversejs .p-sm-2{padding:.5rem!important}.conversejs .pt-sm-2,.conversejs .py-sm-2{padding-top:.5rem!important}.conversejs .pr-sm-2,.conversejs .px-sm-2{padding-right:.5rem!important}.conversejs .pb-sm-2,.conversejs .py-sm-2{padding-bottom:.5rem!important}.conversejs .pl-sm-2,.conversejs .px-sm-2{padding-left:.5rem!important}.conversejs .p-sm-3{padding:1rem!important}.conversejs .pt-sm-3,.conversejs .py-sm-3{padding-top:1rem!important}.conversejs .pr-sm-3,.conversejs .px-sm-3{padding-right:1rem!important}.conversejs .pb-sm-3,.conversejs .py-sm-3{padding-bottom:1rem!important}.conversejs .pl-sm-3,.conversejs .px-sm-3{padding-left:1rem!important}.conversejs .p-sm-4{padding:1.5rem!important}.conversejs .pt-sm-4,.conversejs .py-sm-4{padding-top:1.5rem!important}.conversejs .pr-sm-4,.conversejs .px-sm-4{padding-right:1.5rem!important}.conversejs .pb-sm-4,.conversejs .py-sm-4{padding-bottom:1.5rem!important}.conversejs .pl-sm-4,.conversejs .px-sm-4{padding-left:1.5rem!important}.conversejs .p-sm-5{padding:3rem!important}.conversejs .pt-sm-5,.conversejs .py-sm-5{padding-top:3rem!important}.conversejs .pr-sm-5,.conversejs .px-sm-5{padding-right:3rem!important}.conversejs .pb-sm-5,.conversejs .py-sm-5{padding-bottom:3rem!important}.conversejs .pl-sm-5,.conversejs .px-sm-5{padding-left:3rem!important}.conversejs .m-sm-n1{margin:-.25rem!important}.conversejs .mt-sm-n1,.conversejs .my-sm-n1{margin-top:-.25rem!important}.conversejs .mr-sm-n1,.conversejs .mx-sm-n1{margin-right:-.25rem!important}.conversejs .mb-sm-n1,.conversejs .my-sm-n1{margin-bottom:-.25rem!important}.conversejs .ml-sm-n1,.conversejs .mx-sm-n1{margin-left:-.25rem!important}.conversejs .m-sm-n2{margin:-.5rem!important}.conversejs .mt-sm-n2,.conversejs .my-sm-n2{margin-top:-.5rem!important}.conversejs .mr-sm-n2,.conversejs .mx-sm-n2{margin-right:-.5rem!important}.conversejs .mb-sm-n2,.conversejs .my-sm-n2{margin-bottom:-.5rem!important}.conversejs .ml-sm-n2,.conversejs .mx-sm-n2{margin-left:-.5rem!important}.conversejs .m-sm-n3{margin:-1rem!important}.conversejs .mt-sm-n3,.conversejs .my-sm-n3{margin-top:-1rem!important}.conversejs .mr-sm-n3,.conversejs .mx-sm-n3{margin-right:-1rem!important}.conversejs .mb-sm-n3,.conversejs .my-sm-n3{margin-bottom:-1rem!important}.conversejs .ml-sm-n3,.conversejs .mx-sm-n3{margin-left:-1rem!important}.conversejs .m-sm-n4{margin:-1.5rem!important}.conversejs .mt-sm-n4,.conversejs .my-sm-n4{margin-top:-1.5rem!important}.conversejs .mr-sm-n4,.conversejs .mx-sm-n4{margin-right:-1.5rem!important}.conversejs .mb-sm-n4,.conversejs .my-sm-n4{margin-bottom:-1.5rem!important}.conversejs .ml-sm-n4,.conversejs .mx-sm-n4{margin-left:-1.5rem!important}.conversejs .m-sm-n5{margin:-3rem!important}.conversejs .mt-sm-n5,.conversejs .my-sm-n5{margin-top:-3rem!important}.conversejs .mr-sm-n5,.conversejs .mx-sm-n5{margin-right:-3rem!important}.conversejs .mb-sm-n5,.conversejs .my-sm-n5{margin-bottom:-3rem!important}.conversejs .ml-sm-n5,.conversejs .mx-sm-n5{margin-left:-3rem!important}.conversejs .m-sm-auto{margin:auto!important}.conversejs .mt-sm-auto,.conversejs .my-sm-auto{margin-top:auto!important}.conversejs .mr-sm-auto,.conversejs .mx-sm-auto{margin-right:auto!important}.conversejs .mb-sm-auto,.conversejs .my-sm-auto{margin-bottom:auto!important}.conversejs .ml-sm-auto,.conversejs .mx-sm-auto{margin-left:auto!important}}@media(min-width:768px){.conversejs .m-md-0{margin:0!important}.conversejs .mt-md-0,.conversejs .my-md-0{margin-top:0!important}.conversejs .mr-md-0,.conversejs .mx-md-0{margin-right:0!important}.conversejs .mb-md-0,.conversejs .my-md-0{margin-bottom:0!important}.conversejs .ml-md-0,.conversejs .mx-md-0{margin-left:0!important}.conversejs .m-md-1{margin:.25rem!important}.conversejs .mt-md-1,.conversejs .my-md-1{margin-top:.25rem!important}.conversejs .mr-md-1,.conversejs .mx-md-1{margin-right:.25rem!important}.conversejs .mb-md-1,.conversejs .my-md-1{margin-bottom:.25rem!important}.conversejs .ml-md-1,.conversejs .mx-md-1{margin-left:.25rem!important}.conversejs .m-md-2{margin:.5rem!important}.conversejs .mt-md-2,.conversejs .my-md-2{margin-top:.5rem!important}.conversejs .mr-md-2,.conversejs .mx-md-2{margin-right:.5rem!important}.conversejs .mb-md-2,.conversejs .my-md-2{margin-bottom:.5rem!important}.conversejs .ml-md-2,.conversejs .mx-md-2{margin-left:.5rem!important}.conversejs .m-md-3{margin:1rem!important}.conversejs .mt-md-3,.conversejs .my-md-3{margin-top:1rem!important}.conversejs .mr-md-3,.conversejs .mx-md-3{margin-right:1rem!important}.conversejs .mb-md-3,.conversejs .my-md-3{margin-bottom:1rem!important}.conversejs .ml-md-3,.conversejs .mx-md-3{margin-left:1rem!important}.conversejs .m-md-4{margin:1.5rem!important}.conversejs .mt-md-4,.conversejs .my-md-4{margin-top:1.5rem!important}.conversejs .mr-md-4,.conversejs .mx-md-4{margin-right:1.5rem!important}.conversejs .mb-md-4,.conversejs .my-md-4{margin-bottom:1.5rem!important}.conversejs .ml-md-4,.conversejs .mx-md-4{margin-left:1.5rem!important}.conversejs .m-md-5{margin:3rem!important}.conversejs .mt-md-5,.conversejs .my-md-5{margin-top:3rem!important}.conversejs .mr-md-5,.conversejs .mx-md-5{margin-right:3rem!important}.conversejs .mb-md-5,.conversejs .my-md-5{margin-bottom:3rem!important}.conversejs .ml-md-5,.conversejs .mx-md-5{margin-left:3rem!important}.conversejs .p-md-0{padding:0!important}.conversejs .pt-md-0,.conversejs .py-md-0{padding-top:0!important}.conversejs .pr-md-0,.conversejs .px-md-0{padding-right:0!important}.conversejs .pb-md-0,.conversejs .py-md-0{padding-bottom:0!important}.conversejs .pl-md-0,.conversejs .px-md-0{padding-left:0!important}.conversejs .p-md-1{padding:.25rem!important}.conversejs .pt-md-1,.conversejs .py-md-1{padding-top:.25rem!important}.conversejs .pr-md-1,.conversejs .px-md-1{padding-right:.25rem!important}.conversejs .pb-md-1,.conversejs .py-md-1{padding-bottom:.25rem!important}.conversejs .pl-md-1,.conversejs .px-md-1{padding-left:.25rem!important}.conversejs .p-md-2{padding:.5rem!important}.conversejs .pt-md-2,.conversejs .py-md-2{padding-top:.5rem!important}.conversejs .pr-md-2,.conversejs .px-md-2{padding-right:.5rem!important}.conversejs .pb-md-2,.conversejs .py-md-2{padding-bottom:.5rem!important}.conversejs .pl-md-2,.conversejs .px-md-2{padding-left:.5rem!important}.conversejs .p-md-3{padding:1rem!important}.conversejs .pt-md-3,.conversejs .py-md-3{padding-top:1rem!important}.conversejs .pr-md-3,.conversejs .px-md-3{padding-right:1rem!important}.conversejs .pb-md-3,.conversejs .py-md-3{padding-bottom:1rem!important}.conversejs .pl-md-3,.conversejs .px-md-3{padding-left:1rem!important}.conversejs .p-md-4{padding:1.5rem!important}.conversejs .pt-md-4,.conversejs .py-md-4{padding-top:1.5rem!important}.conversejs .pr-md-4,.conversejs .px-md-4{padding-right:1.5rem!important}.conversejs .pb-md-4,.conversejs .py-md-4{padding-bottom:1.5rem!important}.conversejs .pl-md-4,.conversejs .px-md-4{padding-left:1.5rem!important}.conversejs .p-md-5{padding:3rem!important}.conversejs .pt-md-5,.conversejs .py-md-5{padding-top:3rem!important}.conversejs .pr-md-5,.conversejs .px-md-5{padding-right:3rem!important}.conversejs .pb-md-5,.conversejs .py-md-5{padding-bottom:3rem!important}.conversejs .pl-md-5,.conversejs .px-md-5{padding-left:3rem!important}.conversejs .m-md-n1{margin:-.25rem!important}.conversejs .mt-md-n1,.conversejs .my-md-n1{margin-top:-.25rem!important}.conversejs .mr-md-n1,.conversejs .mx-md-n1{margin-right:-.25rem!important}.conversejs .mb-md-n1,.conversejs .my-md-n1{margin-bottom:-.25rem!important}.conversejs .ml-md-n1,.conversejs .mx-md-n1{margin-left:-.25rem!important}.conversejs .m-md-n2{margin:-.5rem!important}.conversejs .mt-md-n2,.conversejs .my-md-n2{margin-top:-.5rem!important}.conversejs .mr-md-n2,.conversejs .mx-md-n2{margin-right:-.5rem!important}.conversejs .mb-md-n2,.conversejs .my-md-n2{margin-bottom:-.5rem!important}.conversejs .ml-md-n2,.conversejs .mx-md-n2{margin-left:-.5rem!important}.conversejs .m-md-n3{margin:-1rem!important}.conversejs .mt-md-n3,.conversejs .my-md-n3{margin-top:-1rem!important}.conversejs .mr-md-n3,.conversejs .mx-md-n3{margin-right:-1rem!important}.conversejs .mb-md-n3,.conversejs .my-md-n3{margin-bottom:-1rem!important}.conversejs .ml-md-n3,.conversejs .mx-md-n3{margin-left:-1rem!important}.conversejs .m-md-n4{margin:-1.5rem!important}.conversejs .mt-md-n4,.conversejs .my-md-n4{margin-top:-1.5rem!important}.conversejs .mr-md-n4,.conversejs .mx-md-n4{margin-right:-1.5rem!important}.conversejs .mb-md-n4,.conversejs .my-md-n4{margin-bottom:-1.5rem!important}.conversejs .ml-md-n4,.conversejs .mx-md-n4{margin-left:-1.5rem!important}.conversejs .m-md-n5{margin:-3rem!important}.conversejs .mt-md-n5,.conversejs .my-md-n5{margin-top:-3rem!important}.conversejs .mr-md-n5,.conversejs .mx-md-n5{margin-right:-3rem!important}.conversejs .mb-md-n5,.conversejs .my-md-n5{margin-bottom:-3rem!important}.conversejs .ml-md-n5,.conversejs .mx-md-n5{margin-left:-3rem!important}.conversejs .m-md-auto{margin:auto!important}.conversejs .mt-md-auto,.conversejs .my-md-auto{margin-top:auto!important}.conversejs .mr-md-auto,.conversejs .mx-md-auto{margin-right:auto!important}.conversejs .mb-md-auto,.conversejs .my-md-auto{margin-bottom:auto!important}.conversejs .ml-md-auto,.conversejs .mx-md-auto{margin-left:auto!important}}@media(min-width:992px){.conversejs .m-lg-0{margin:0!important}.conversejs .mt-lg-0,.conversejs .my-lg-0{margin-top:0!important}.conversejs .mr-lg-0,.conversejs .mx-lg-0{margin-right:0!important}.conversejs .mb-lg-0,.conversejs .my-lg-0{margin-bottom:0!important}.conversejs .ml-lg-0,.conversejs .mx-lg-0{margin-left:0!important}.conversejs .m-lg-1{margin:.25rem!important}.conversejs .mt-lg-1,.conversejs .my-lg-1{margin-top:.25rem!important}.conversejs .mr-lg-1,.conversejs .mx-lg-1{margin-right:.25rem!important}.conversejs .mb-lg-1,.conversejs .my-lg-1{margin-bottom:.25rem!important}.conversejs .ml-lg-1,.conversejs .mx-lg-1{margin-left:.25rem!important}.conversejs .m-lg-2{margin:.5rem!important}.conversejs .mt-lg-2,.conversejs .my-lg-2{margin-top:.5rem!important}.conversejs .mr-lg-2,.conversejs .mx-lg-2{margin-right:.5rem!important}.conversejs .mb-lg-2,.conversejs .my-lg-2{margin-bottom:.5rem!important}.conversejs .ml-lg-2,.conversejs .mx-lg-2{margin-left:.5rem!important}.conversejs .m-lg-3{margin:1rem!important}.conversejs .mt-lg-3,.conversejs .my-lg-3{margin-top:1rem!important}.conversejs .mr-lg-3,.conversejs .mx-lg-3{margin-right:1rem!important}.conversejs .mb-lg-3,.conversejs .my-lg-3{margin-bottom:1rem!important}.conversejs .ml-lg-3,.conversejs .mx-lg-3{margin-left:1rem!important}.conversejs .m-lg-4{margin:1.5rem!important}.conversejs .mt-lg-4,.conversejs .my-lg-4{margin-top:1.5rem!important}.conversejs .mr-lg-4,.conversejs .mx-lg-4{margin-right:1.5rem!important}.conversejs .mb-lg-4,.conversejs .my-lg-4{margin-bottom:1.5rem!important}.conversejs .ml-lg-4,.conversejs .mx-lg-4{margin-left:1.5rem!important}.conversejs .m-lg-5{margin:3rem!important}.conversejs .mt-lg-5,.conversejs .my-lg-5{margin-top:3rem!important}.conversejs .mr-lg-5,.conversejs .mx-lg-5{margin-right:3rem!important}.conversejs .mb-lg-5,.conversejs .my-lg-5{margin-bottom:3rem!important}.conversejs .ml-lg-5,.conversejs .mx-lg-5{margin-left:3rem!important}.conversejs .p-lg-0{padding:0!important}.conversejs .pt-lg-0,.conversejs .py-lg-0{padding-top:0!important}.conversejs .pr-lg-0,.conversejs .px-lg-0{padding-right:0!important}.conversejs .pb-lg-0,.conversejs .py-lg-0{padding-bottom:0!important}.conversejs .pl-lg-0,.conversejs .px-lg-0{padding-left:0!important}.conversejs .p-lg-1{padding:.25rem!important}.conversejs .pt-lg-1,.conversejs .py-lg-1{padding-top:.25rem!important}.conversejs .pr-lg-1,.conversejs .px-lg-1{padding-right:.25rem!important}.conversejs .pb-lg-1,.conversejs .py-lg-1{padding-bottom:.25rem!important}.conversejs .pl-lg-1,.conversejs .px-lg-1{padding-left:.25rem!important}.conversejs .p-lg-2{padding:.5rem!important}.conversejs .pt-lg-2,.conversejs .py-lg-2{padding-top:.5rem!important}.conversejs .pr-lg-2,.conversejs .px-lg-2{padding-right:.5rem!important}.conversejs .pb-lg-2,.conversejs .py-lg-2{padding-bottom:.5rem!important}.conversejs .pl-lg-2,.conversejs .px-lg-2{padding-left:.5rem!important}.conversejs .p-lg-3{padding:1rem!important}.conversejs .pt-lg-3,.conversejs .py-lg-3{padding-top:1rem!important}.conversejs .pr-lg-3,.conversejs .px-lg-3{padding-right:1rem!important}.conversejs .pb-lg-3,.conversejs .py-lg-3{padding-bottom:1rem!important}.conversejs .pl-lg-3,.conversejs .px-lg-3{padding-left:1rem!important}.conversejs .p-lg-4{padding:1.5rem!important}.conversejs .pt-lg-4,.conversejs .py-lg-4{padding-top:1.5rem!important}.conversejs .pr-lg-4,.conversejs .px-lg-4{padding-right:1.5rem!important}.conversejs .pb-lg-4,.conversejs .py-lg-4{padding-bottom:1.5rem!important}.conversejs .pl-lg-4,.conversejs .px-lg-4{padding-left:1.5rem!important}.conversejs .p-lg-5{padding:3rem!important}.conversejs .pt-lg-5,.conversejs .py-lg-5{padding-top:3rem!important}.conversejs .pr-lg-5,.conversejs .px-lg-5{padding-right:3rem!important}.conversejs .pb-lg-5,.conversejs .py-lg-5{padding-bottom:3rem!important}.conversejs .pl-lg-5,.conversejs .px-lg-5{padding-left:3rem!important}.conversejs .m-lg-n1{margin:-.25rem!important}.conversejs .mt-lg-n1,.conversejs .my-lg-n1{margin-top:-.25rem!important}.conversejs .mr-lg-n1,.conversejs .mx-lg-n1{margin-right:-.25rem!important}.conversejs .mb-lg-n1,.conversejs .my-lg-n1{margin-bottom:-.25rem!important}.conversejs .ml-lg-n1,.conversejs .mx-lg-n1{margin-left:-.25rem!important}.conversejs .m-lg-n2{margin:-.5rem!important}.conversejs .mt-lg-n2,.conversejs .my-lg-n2{margin-top:-.5rem!important}.conversejs .mr-lg-n2,.conversejs .mx-lg-n2{margin-right:-.5rem!important}.conversejs .mb-lg-n2,.conversejs .my-lg-n2{margin-bottom:-.5rem!important}.conversejs .ml-lg-n2,.conversejs .mx-lg-n2{margin-left:-.5rem!important}.conversejs .m-lg-n3{margin:-1rem!important}.conversejs .mt-lg-n3,.conversejs .my-lg-n3{margin-top:-1rem!important}.conversejs .mr-lg-n3,.conversejs .mx-lg-n3{margin-right:-1rem!important}.conversejs .mb-lg-n3,.conversejs .my-lg-n3{margin-bottom:-1rem!important}.conversejs .ml-lg-n3,.conversejs .mx-lg-n3{margin-left:-1rem!important}.conversejs .m-lg-n4{margin:-1.5rem!important}.conversejs .mt-lg-n4,.conversejs .my-lg-n4{margin-top:-1.5rem!important}.conversejs .mr-lg-n4,.conversejs .mx-lg-n4{margin-right:-1.5rem!important}.conversejs .mb-lg-n4,.conversejs .my-lg-n4{margin-bottom:-1.5rem!important}.conversejs .ml-lg-n4,.conversejs .mx-lg-n4{margin-left:-1.5rem!important}.conversejs .m-lg-n5{margin:-3rem!important}.conversejs .mt-lg-n5,.conversejs .my-lg-n5{margin-top:-3rem!important}.conversejs .mr-lg-n5,.conversejs .mx-lg-n5{margin-right:-3rem!important}.conversejs .mb-lg-n5,.conversejs .my-lg-n5{margin-bottom:-3rem!important}.conversejs .ml-lg-n5,.conversejs .mx-lg-n5{margin-left:-3rem!important}.conversejs .m-lg-auto{margin:auto!important}.conversejs .mt-lg-auto,.conversejs .my-lg-auto{margin-top:auto!important}.conversejs .mr-lg-auto,.conversejs .mx-lg-auto{margin-right:auto!important}.conversejs .mb-lg-auto,.conversejs .my-lg-auto{margin-bottom:auto!important}.conversejs .ml-lg-auto,.conversejs .mx-lg-auto{margin-left:auto!important}}@media(min-width:1200px){.conversejs .m-xl-0{margin:0!important}.conversejs .mt-xl-0,.conversejs .my-xl-0{margin-top:0!important}.conversejs .mr-xl-0,.conversejs .mx-xl-0{margin-right:0!important}.conversejs .mb-xl-0,.conversejs .my-xl-0{margin-bottom:0!important}.conversejs .ml-xl-0,.conversejs .mx-xl-0{margin-left:0!important}.conversejs .m-xl-1{margin:.25rem!important}.conversejs .mt-xl-1,.conversejs .my-xl-1{margin-top:.25rem!important}.conversejs .mr-xl-1,.conversejs .mx-xl-1{margin-right:.25rem!important}.conversejs .mb-xl-1,.conversejs .my-xl-1{margin-bottom:.25rem!important}.conversejs .ml-xl-1,.conversejs .mx-xl-1{margin-left:.25rem!important}.conversejs .m-xl-2{margin:.5rem!important}.conversejs .mt-xl-2,.conversejs .my-xl-2{margin-top:.5rem!important}.conversejs .mr-xl-2,.conversejs .mx-xl-2{margin-right:.5rem!important}.conversejs .mb-xl-2,.conversejs .my-xl-2{margin-bottom:.5rem!important}.conversejs .ml-xl-2,.conversejs .mx-xl-2{margin-left:.5rem!important}.conversejs .m-xl-3{margin:1rem!important}.conversejs .mt-xl-3,.conversejs .my-xl-3{margin-top:1rem!important}.conversejs .mr-xl-3,.conversejs .mx-xl-3{margin-right:1rem!important}.conversejs .mb-xl-3,.conversejs .my-xl-3{margin-bottom:1rem!important}.conversejs .ml-xl-3,.conversejs .mx-xl-3{margin-left:1rem!important}.conversejs .m-xl-4{margin:1.5rem!important}.conversejs .mt-xl-4,.conversejs .my-xl-4{margin-top:1.5rem!important}.conversejs .mr-xl-4,.conversejs .mx-xl-4{margin-right:1.5rem!important}.conversejs .mb-xl-4,.conversejs .my-xl-4{margin-bottom:1.5rem!important}.conversejs .ml-xl-4,.conversejs .mx-xl-4{margin-left:1.5rem!important}.conversejs .m-xl-5{margin:3rem!important}.conversejs .mt-xl-5,.conversejs .my-xl-5{margin-top:3rem!important}.conversejs .mr-xl-5,.conversejs .mx-xl-5{margin-right:3rem!important}.conversejs .mb-xl-5,.conversejs .my-xl-5{margin-bottom:3rem!important}.conversejs .ml-xl-5,.conversejs .mx-xl-5{margin-left:3rem!important}.conversejs .p-xl-0{padding:0!important}.conversejs .pt-xl-0,.conversejs .py-xl-0{padding-top:0!important}.conversejs .pr-xl-0,.conversejs .px-xl-0{padding-right:0!important}.conversejs .pb-xl-0,.conversejs .py-xl-0{padding-bottom:0!important}.conversejs .pl-xl-0,.conversejs .px-xl-0{padding-left:0!important}.conversejs .p-xl-1{padding:.25rem!important}.conversejs .pt-xl-1,.conversejs .py-xl-1{padding-top:.25rem!important}.conversejs .pr-xl-1,.conversejs .px-xl-1{padding-right:.25rem!important}.conversejs .pb-xl-1,.conversejs .py-xl-1{padding-bottom:.25rem!important}.conversejs .pl-xl-1,.conversejs .px-xl-1{padding-left:.25rem!important}.conversejs .p-xl-2{padding:.5rem!important}.conversejs .pt-xl-2,.conversejs .py-xl-2{padding-top:.5rem!important}.conversejs .pr-xl-2,.conversejs .px-xl-2{padding-right:.5rem!important}.conversejs .pb-xl-2,.conversejs .py-xl-2{padding-bottom:.5rem!important}.conversejs .pl-xl-2,.conversejs .px-xl-2{padding-left:.5rem!important}.conversejs .p-xl-3{padding:1rem!important}.conversejs .pt-xl-3,.conversejs .py-xl-3{padding-top:1rem!important}.conversejs .pr-xl-3,.conversejs .px-xl-3{padding-right:1rem!important}.conversejs .pb-xl-3,.conversejs .py-xl-3{padding-bottom:1rem!important}.conversejs .pl-xl-3,.conversejs .px-xl-3{padding-left:1rem!important}.conversejs .p-xl-4{padding:1.5rem!important}.conversejs .pt-xl-4,.conversejs .py-xl-4{padding-top:1.5rem!important}.conversejs .pr-xl-4,.conversejs .px-xl-4{padding-right:1.5rem!important}.conversejs .pb-xl-4,.conversejs .py-xl-4{padding-bottom:1.5rem!important}.conversejs .pl-xl-4,.conversejs .px-xl-4{padding-left:1.5rem!important}.conversejs .p-xl-5{padding:3rem!important}.conversejs .pt-xl-5,.conversejs .py-xl-5{padding-top:3rem!important}.conversejs .pr-xl-5,.conversejs .px-xl-5{padding-right:3rem!important}.conversejs .pb-xl-5,.conversejs .py-xl-5{padding-bottom:3rem!important}.conversejs .pl-xl-5,.conversejs .px-xl-5{padding-left:3rem!important}.conversejs .m-xl-n1{margin:-.25rem!important}.conversejs .mt-xl-n1,.conversejs .my-xl-n1{margin-top:-.25rem!important}.conversejs .mr-xl-n1,.conversejs .mx-xl-n1{margin-right:-.25rem!important}.conversejs .mb-xl-n1,.conversejs .my-xl-n1{margin-bottom:-.25rem!important}.conversejs .ml-xl-n1,.conversejs .mx-xl-n1{margin-left:-.25rem!important}.conversejs .m-xl-n2{margin:-.5rem!important}.conversejs .mt-xl-n2,.conversejs .my-xl-n2{margin-top:-.5rem!important}.conversejs .mr-xl-n2,.conversejs .mx-xl-n2{margin-right:-.5rem!important}.conversejs .mb-xl-n2,.conversejs .my-xl-n2{margin-bottom:-.5rem!important}.conversejs .ml-xl-n2,.conversejs .mx-xl-n2{margin-left:-.5rem!important}.conversejs .m-xl-n3{margin:-1rem!important}.conversejs .mt-xl-n3,.conversejs .my-xl-n3{margin-top:-1rem!important}.conversejs .mr-xl-n3,.conversejs .mx-xl-n3{margin-right:-1rem!important}.conversejs .mb-xl-n3,.conversejs .my-xl-n3{margin-bottom:-1rem!important}.conversejs .ml-xl-n3,.conversejs .mx-xl-n3{margin-left:-1rem!important}.conversejs .m-xl-n4{margin:-1.5rem!important}.conversejs .mt-xl-n4,.conversejs .my-xl-n4{margin-top:-1.5rem!important}.conversejs .mr-xl-n4,.conversejs .mx-xl-n4{margin-right:-1.5rem!important}.conversejs .mb-xl-n4,.conversejs .my-xl-n4{margin-bottom:-1.5rem!important}.conversejs .ml-xl-n4,.conversejs .mx-xl-n4{margin-left:-1.5rem!important}.conversejs .m-xl-n5{margin:-3rem!important}.conversejs .mt-xl-n5,.conversejs .my-xl-n5{margin-top:-3rem!important}.conversejs .mr-xl-n5,.conversejs .mx-xl-n5{margin-right:-3rem!important}.conversejs .mb-xl-n5,.conversejs .my-xl-n5{margin-bottom:-3rem!important}.conversejs .ml-xl-n5,.conversejs .mx-xl-n5{margin-left:-3rem!important}.conversejs .m-xl-auto{margin:auto!important}.conversejs .mt-xl-auto,.conversejs .my-xl-auto{margin-top:auto!important}.conversejs .mr-xl-auto,.conversejs .mx-xl-auto{margin-right:auto!important}.conversejs .mb-xl-auto,.conversejs .my-xl-auto{margin-bottom:auto!important}.conversejs .ml-xl-auto,.conversejs .mx-xl-auto{margin-left:auto!important}}.conversejs .stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.conversejs .text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.conversejs .text-justify{text-align:justify!important}.conversejs .text-wrap{white-space:normal!important}.conversejs .text-nowrap{white-space:nowrap!important}.conversejs .text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .text-left{text-align:left!important}.conversejs .text-right{text-align:right!important}.conversejs .text-center{text-align:center!important}@media(min-width:576px){.conversejs .text-sm-left{text-align:left!important}.conversejs .text-sm-right{text-align:right!important}.conversejs .text-sm-center{text-align:center!important}}@media(min-width:768px){.conversejs .text-md-left{text-align:left!important}.conversejs .text-md-right{text-align:right!important}.conversejs .text-md-center{text-align:center!important}}@media(min-width:992px){.conversejs .text-lg-left{text-align:left!important}.conversejs .text-lg-right{text-align:right!important}.conversejs .text-lg-center{text-align:center!important}}@media(min-width:1200px){.conversejs .text-xl-left{text-align:left!important}.conversejs .text-xl-right{text-align:right!important}.conversejs .text-xl-center{text-align:center!important}}.conversejs .text-lowercase{text-transform:lowercase!important}.conversejs .text-uppercase{text-transform:uppercase!important}.conversejs .text-capitalize{text-transform:capitalize!important}.conversejs .font-weight-light{font-weight:300!important}.conversejs .font-weight-lighter{font-weight:lighter!important}.conversejs .font-weight-normal{font-weight:400!important}.conversejs .font-weight-bold{font-weight:700!important}.conversejs .font-weight-bolder{font-weight:bolder!important}.conversejs .font-italic{font-style:italic!important}.conversejs .text-white{color:#fff!important}.conversejs .text-primary{color:#007bff!important}.conversejs a.text-primary:focus,.conversejs a.text-primary:hover{color:#0056b3!important}.conversejs .text-secondary{color:#6c757d!important}.conversejs a.text-secondary:focus,.conversejs a.text-secondary:hover{color:#494f54!important}.conversejs .text-success{color:#28a745!important}.conversejs a.text-success:focus,.conversejs a.text-success:hover{color:#19692c!important}.conversejs .text-info{color:#17a2b8!important}.conversejs a.text-info:focus,.conversejs a.text-info:hover{color:#0f6674!important}.conversejs .text-warning{color:#ffc107!important}.conversejs a.text-warning:focus,.conversejs a.text-warning:hover{color:#ba8b00!important}.conversejs .text-danger{color:#dc3545!important}.conversejs a.text-danger:focus,.conversejs a.text-danger:hover{color:#a71d2a!important}.conversejs .text-light{color:#f8f9fa!important}.conversejs a.text-light:focus,.conversejs a.text-light:hover{color:#cbd3da!important}.conversejs .text-dark{color:#343a40!important}.conversejs a.text-dark:focus,.conversejs a.text-dark:hover{color:#121416!important}.conversejs .text-body{color:#212529!important}.conversejs .text-muted{color:#6c757d!important}.conversejs .text-black-50{color:rgba(0,0,0,.5)!important}.conversejs .text-white-50{color:rgba(255,255,255,.5)!important}.conversejs .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.conversejs .text-decoration-none{text-decoration:none!important}.conversejs .text-break{word-break:break-word!important;word-wrap:break-word!important}.conversejs .text-reset{color:inherit!important}.conversejs .visible{visibility:visible!important}.conversejs .invisible{visibility:hidden!important}#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs{bottom:0;height:100%;position:fixed;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);color:var(--text-color);font-family:var(--normal-font);font-size:var(--font-size);direction:ltr;z-index:1031}.conversejs .flyout{position:absolute}.conversejs textarea:disabled{background-color:#eee!important}.conversejs .subdued{opacity:.35}.conversejs .fit-content{width:-webkit-fit-content!important;width:-moz-fit-content!important;width:fit-content!important;max-width:-webkit-fit-content!important;max-width:-moz-fit-content!important;max-width:fit-content!important}.conversejs .nopadding{padding:0!important}.conversejs .no-scrolling{overflow-x:none;overflow-y:none}.conversejs converse-brand-heading{text-align:center}.conversejs .brand-heading{display:inline-flex;flex-direction:row;align-items:flex-start;font-family:var(--branding-font);color:var(--link-color);margin-bottom:.75em}.conversejs .brand-heading .brand-name-wrapper{display:flex;white-space:nowrap;margin:auto}.conversejs .brand-heading .brand-name{color:var(--link-color);display:flex;flex-direction:column;align-items:center;margin-top:-.25em}.conversejs .brand-heading .brand-name .byline{font-family:var(--heading-font);font-size:.3em;margin-bottom:.75em;margin-left:-2.7em;opacity:.55;word-spacing:5px}.conversejs .brand-heading .brand-subtitle{color:var(--text-color)}.conversejs .brand-heading .brand-name__text{font-size:120%;vertical-align:text-bottom}.conversejs .brand-heading .converse-svg-logo{color:var(--link-color);height:1.5em;margin-right:.25em;margin-bottom:-.25em}.conversejs .brand-heading .converse-svg-logo .cls-1{isolation:isolate}.conversejs .brand-heading .converse-svg-logo .cls-2{opacity:.5;mix-blend-mode:multiply}.conversejs .brand-heading .converse-svg-logo .cls-3{fill:var(--link-color)}.conversejs .brand-heading .converse-svg-logo .cls-4{fill:var(--link-color)}.conversejs .brand-heading--inverse .converse-svg-logo{margin-bottom:0;margin-top:-.2em}.conversejs .brand-heading--inverse .byline{margin:0;font-family:var(--heading-font);font-size:.25em;opacity:.55;margin-left:-7em;word-spacing:5px}.conversejs .popover{position:fixed}.conversejs ::-moz-placeholder{color:var(--subdued-color)}.conversejs :-ms-input-placeholder{color:var(--subdued-color)}.conversejs ::placeholder{color:var(--subdued-color)}.conversejs ::-moz-selection{background-color:var(--highlight-color)}.conversejs ::selection{background-color:var(--highlight-color)}.conversejs ::-moz-selection{background-color:var(--highlight-color)}@media screen and (max-width:480px){.conversejs{margin:0;right:10px;left:10px;bottom:5px}}@media screen and (max-height:450px){.conversejs{margin:0;right:10px;left:10px;bottom:5px}}.conversejs ul li{height:auto}.conversejs a,.conversejs article,.conversejs aside,.conversejs audio,.conversejs blockquote,.conversejs caption,.conversejs dd,.conversejs details,.conversejs div,.conversejs dl,.conversejs dt,.conversejs em,.conversejs embed,.conversejs fieldset,.conversejs figcaption,.conversejs figure,.conversejs footer,.conversejs form,.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6,.conversejs header,.conversejs hgroup,.conversejs img,.conversejs legend,.conversejs li,.conversejs mark,.conversejs menu,.conversejs nav,.conversejs ol,.conversejs output,.conversejs p,.conversejs pre,.conversejs ruby,.conversejs section,.conversejs span,.conversejs strong,.conversejs summary,.conversejs table,.conversejs tbody,.conversejs td,.conversejs tfoot,.conversejs th,.conversejs thead,.conversejs time,.conversejs tr,.conversejs ul,.conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}.conversejs button,.conversejs input[type=button],.conversejs input[type=password],.conversejs input[type=submit],.conversejs input[type=text],.conversejs textarea{font-size:var(--font-size);min-height:0}.conversejs strong{font-weight:700}.conversejs em{font-style:italic}.conversejs ol,.conversejs ul{list-style:none}.conversejs li{height:10px}.conversejs dl,.conversejs ol,.conversejs ul{font:inherit;margin:0}.conversejs a{cursor:pointer}.conversejs a,.conversejs a:not([href]):not([tabindex]),.conversejs a:visited{text-decoration:none;color:var(--link-color);text-shadow:none;cursor:pointer}.conversejs a:hover,.conversejs a:not([href]):not([tabindex]):hover,.conversejs a:visited:hover{color:var(--link-hover-color);text-decoration:none;text-shadow:none}.conversejs a.fa,.conversejs a.far,.conversejs a.fas,.conversejs a:not([href]):not([tabindex]).fa,.conversejs a:not([href]):not([tabindex]).far,.conversejs a:not([href]):not([tabindex]).fas,.conversejs a:visited.fa,.conversejs a:visited.far,.conversejs a:visited.fas{color:var(--subdued-color)}.conversejs a.fa:hover,.conversejs a.far:hover,.conversejs a.fas:hover,.conversejs a:not([href]):not([tabindex]).fa:hover,.conversejs a:not([href]):not([tabindex]).far:hover,.conversejs a:not([href]):not([tabindex]).fas:hover,.conversejs a:visited.fa:hover,.conversejs a:visited.far:hover,.conversejs a:visited.fas:hover{color:var(--gray-color)}.conversejs svg{border-radius:var(--chatbox-border-radius)}.conversejs .fa,.conversejs .far,.conversejs .fas{color:var(--subdued-color)}.conversejs .fa:hover,.conversejs .far:hover,.conversejs .fas:hover{color:var(--gray-color)}.conversejs q{quotes:"“" "”" "‘" "’"}.conversejs q.reason{display:inline}.conversejs q:before{content:open-quote}.conversejs q:after{content:close-quote}.conversejs .helptext{font-size:var(--font-size-tiny);color:var(--text-color-lighten-15-percent)}.conversejs .selected{color:var(--link-color)!important}.conversejs .circle{border-radius:50%}.conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}@keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}.conversejs .fade-in{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}.conversejs .visible{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}.conversejs .hidden{opacity:0!important;display:none!important}.conversejs .fade-out{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}.conversejs .collapsed{height:0!important;overflow:hidden!important;padding:0!important}.conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}.conversejs .spinner__container{width:100%}.conversejs .spinner{-webkit-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;width:1em;display:block;text-align:center;padding:.5em 0;font-size:24px}.conversejs .left{float:left}.conversejs .right{float:right}.conversejs .centered{text-align:center;display:block;margin:auto}.conversejs .hor_centered{text-align:center;display:block!important;margin:0 auto;clear:both}.conversejs .error{color:var(--error-color)!important}.conversejs .info{color:var(--info-color)}.conversejs .reg-feedback{font-size:85%;margin-bottom:1em}.conversejs #converse-login .conn-feedback,.conversejs .reg-feedback{display:block;text-align:center;width:100%}.conversejs .avatar{border-radius:var(--avatar-border-radius);border:var(--avatar-border);background-color:var(--avatar-background-color)}.conversejs .avatar-autocomplete{margin-right:.5em;vertical-align:middle}.conversejs .activated{display:block!important}.conversejs .form-help{color:var(--subdued-color);font-size:90%}.conversejs .form-control--labeled{margin-top:.5em}.conversejs .nav-pills .nav-link.active,.conversejs .nav-pills .show>.nav-link{background-color:var(--primary-color)}@media screen and (max-width:575px){body .converse-brand{font-size:3.75em}.conversejs:not(.converse-embedded) .chatbox .chat-body{border-radius:var(--chatbox-border-radius)}.conversejs:not(.converse-embedded) .flyout{border-radius:var(--chatbox-border-radius)}}@media screen and (min-width:576px){.conversejs .offset-sm-2{margin-left:16.666667%}}@media screen and (min-width:768px){.conversejs .offset-md-2{margin-left:16.666667%}.conversejs .offset-md-3{margin-left:25%}}@media screen and (min-width:992px){.conversejs .offset-lg-2{margin-left:16.666667%}.conversejs .offset-lg-3{margin-left:25%}}@media screen and (min-width:1200px){.conversejs .offset-xl-2{margin-left:16.666667%}}@media screen and (max-height:450px){.conversejs{left:0}}.conversejs .btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .btn{transition:none}}.conversejs .btn:hover{color:#212529;text-decoration:none}.conversejs .btn.focus,.conversejs .btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .btn.disabled,.conversejs .btn:disabled{opacity:.65}.conversejs .btn:not(:disabled):not(.disabled){cursor:pointer}.conversejs a.btn.disabled,.conversejs fieldset:disabled a.btn{pointer-events:none}.conversejs .btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.conversejs .btn-primary.focus,.conversejs .btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.conversejs .btn-primary.disabled,.conversejs .btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-primary:not(:disabled):not(.disabled).active,.conversejs .btn-primary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.conversejs .btn-primary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-primary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.conversejs .btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.conversejs .btn-secondary.focus,.conversejs .btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.conversejs .btn-secondary.disabled,.conversejs .btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-secondary:not(:disabled):not(.disabled).active,.conversejs .btn-secondary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.conversejs .btn-secondary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.conversejs .btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.conversejs .btn-success.focus,.conversejs .btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.conversejs .btn-success.disabled,.conversejs .btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-success:not(:disabled):not(.disabled).active,.conversejs .btn-success:not(:disabled):not(.disabled):active,.show>.conversejs .btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.conversejs .btn-success:not(:disabled):not(.disabled).active:focus,.conversejs .btn-success:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.conversejs .btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.conversejs .btn-info.focus,.conversejs .btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.conversejs .btn-info.disabled,.conversejs .btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-info:not(:disabled):not(.disabled).active,.conversejs .btn-info:not(:disabled):not(.disabled):active,.show>.conversejs .btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.conversejs .btn-info:not(:disabled):not(.disabled).active:focus,.conversejs .btn-info:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.conversejs .btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.conversejs .btn-warning.focus,.conversejs .btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.conversejs .btn-warning.disabled,.conversejs .btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-warning:not(:disabled):not(.disabled).active,.conversejs .btn-warning:not(:disabled):not(.disabled):active,.show>.conversejs .btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.conversejs .btn-warning:not(:disabled):not(.disabled).active:focus,.conversejs .btn-warning:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.conversejs .btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.conversejs .btn-danger.focus,.conversejs .btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.conversejs .btn-danger.disabled,.conversejs .btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-danger:not(:disabled):not(.disabled).active,.conversejs .btn-danger:not(:disabled):not(.disabled):active,.show>.conversejs .btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.conversejs .btn-danger:not(:disabled):not(.disabled).active:focus,.conversejs .btn-danger:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.conversejs .btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.conversejs .btn-light.focus,.conversejs .btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.conversejs .btn-light.disabled,.conversejs .btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-light:not(:disabled):not(.disabled).active,.conversejs .btn-light:not(:disabled):not(.disabled):active,.show>.conversejs .btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.conversejs .btn-light:not(:disabled):not(.disabled).active:focus,.conversejs .btn-light:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.conversejs .btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.conversejs .btn-dark.focus,.conversejs .btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.conversejs .btn-dark.disabled,.conversejs .btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-dark:not(:disabled):not(.disabled).active,.conversejs .btn-dark:not(:disabled):not(.disabled):active,.show>.conversejs .btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.conversejs .btn-dark:not(:disabled):not(.disabled).active:focus,.conversejs .btn-dark:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.conversejs .btn-outline-primary{color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary.focus,.conversejs .btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .btn-outline-primary.disabled,.conversejs .btn-outline-primary:disabled{color:#007bff;background-color:transparent}.conversejs .btn-outline-primary:not(:disabled):not(.disabled).active,.conversejs .btn-outline-primary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .btn-outline-secondary{color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary.focus,.conversejs .btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .btn-outline-secondary.disabled,.conversejs .btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active,.conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .btn-outline-success{color:#28a745;border-color:#28a745}.conversejs .btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-outline-success.focus,.conversejs .btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .btn-outline-success.disabled,.conversejs .btn-outline-success:disabled{color:#28a745;background-color:transparent}.conversejs .btn-outline-success:not(:disabled):not(.disabled).active,.conversejs .btn-outline-success:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-outline-success:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .btn-outline-info{color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info.focus,.conversejs .btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .btn-outline-info.disabled,.conversejs .btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.conversejs .btn-outline-info:not(:disabled):not(.disabled).active,.conversejs .btn-outline-info:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .btn-outline-warning{color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning.focus,.conversejs .btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .btn-outline-warning.disabled,.conversejs .btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.conversejs .btn-outline-warning:not(:disabled):not(.disabled).active,.conversejs .btn-outline-warning:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .btn-outline-danger{color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger.focus,.conversejs .btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .btn-outline-danger.disabled,.conversejs .btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.conversejs .btn-outline-danger:not(:disabled):not(.disabled).active,.conversejs .btn-outline-danger:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light.focus,.conversejs .btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .btn-outline-light.disabled,.conversejs .btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.conversejs .btn-outline-light:not(:disabled):not(.disabled).active,.conversejs .btn-outline-light:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .btn-outline-dark{color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark.focus,.conversejs .btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .btn-outline-dark.disabled,.conversejs .btn-outline-dark:disabled{color:#343a40;background-color:transparent}.conversejs .btn-outline-dark:not(:disabled):not(.disabled).active,.conversejs .btn-outline-dark:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .btn-link{font-weight:400;color:#007bff;text-decoration:none}.conversejs .btn-link:hover{color:#0056b3;text-decoration:underline}.conversejs .btn-link.focus,.conversejs .btn-link:focus{text-decoration:underline}.conversejs .btn-link.disabled,.conversejs .btn-link:disabled{color:#6c757d;pointer-events:none}.conversejs .btn-group-lg>.btn,.conversejs .btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs .btn-group-sm>.btn,.conversejs .btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.conversejs .btn-block{display:block;width:100%}.conversejs .btn-block+.btn-block{margin-top:.5rem}.conversejs input[type=button].btn-block,.conversejs input[type=reset].btn-block,.conversejs input[type=submit].btn-block{width:100%}.conversejs .btn-group,.conversejs .btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.conversejs .btn-group-vertical>.btn,.conversejs .btn-group>.btn{position:relative;flex:1 1 auto}.conversejs .btn-group-vertical>.btn:hover,.conversejs .btn-group>.btn:hover{z-index:1}.conversejs .btn-group-vertical>.btn.active,.conversejs .btn-group-vertical>.btn:active,.conversejs .btn-group-vertical>.btn:focus,.conversejs .btn-group>.btn.active,.conversejs .btn-group>.btn:active,.conversejs .btn-group>.btn:focus{z-index:1}.conversejs .btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.conversejs .btn-toolbar .input-group{width:auto}.conversejs .btn-group>.btn-group:not(:first-child),.conversejs .btn-group>.btn:not(:first-child){margin-left:-1px}.conversejs .btn-group>.btn-group:not(:last-child)>.btn,.conversejs .btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .btn-group>.btn-group:not(:first-child)>.btn,.conversejs .btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.conversejs .dropdown-toggle-split::after,.dropright .conversejs .dropdown-toggle-split::after,.dropup .conversejs .dropdown-toggle-split::after{margin-left:0}.dropleft .conversejs .dropdown-toggle-split::before{margin-right:0}.conversejs .btn-group-sm>.btn+.dropdown-toggle-split,.conversejs .btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.conversejs .btn-group-lg>.btn+.dropdown-toggle-split,.conversejs .btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.conversejs .btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.conversejs .btn-group-vertical>.btn,.conversejs .btn-group-vertical>.btn-group{width:100%}.conversejs .btn-group-vertical>.btn-group:not(:first-child),.conversejs .btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.conversejs .btn-group-vertical>.btn-group:not(:last-child)>.btn,.conversejs .btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.conversejs .btn-group-vertical>.btn-group:not(:first-child)>.btn,.conversejs .btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.conversejs .btn-group-toggle>.btn,.conversejs .btn-group-toggle>.btn-group>.btn{margin-bottom:0}.conversejs .btn-group-toggle>.btn input[type=checkbox],.conversejs .btn-group-toggle>.btn input[type=radio],.conversejs .btn-group-toggle>.btn-group>.btn input[type=checkbox],.conversejs .btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.conversejs .btn{font-weight:400;color:var(--button-text-color)}.conversejs .btn.fa{color:var(--button-text-color)!important}.conversejs .btn i.fa,.conversejs .btn i.far,.conversejs .btn i.fas{color:var(--button-text-color);margin-right:.5em}.conversejs .btn i.fa.only-icon,.conversejs .btn i.far.only-icon,.conversejs .btn i.fas.only-icon{margin-right:0}.conversejs .btn converse-icon{display:inline-block;margin-right:0}.conversejs .btn-primary{background-color:var(--primary-color);border-color:transparent}.conversejs .btn-primary:active,.conversejs .btn-primary:focus,.conversejs .btn-primary:hover{background-color:var(--primary-color-dark)!important;border-color:transparent!important}.conversejs .btn--transparent{background:0 0;border:none}.conversejs .btn-circle{width:30px;height:30px;text-align:center;padding:.5em 0;font-size:var(--font-size-small);line-height:1.428571429;border-radius:50%}.conversejs .badge-info,.conversejs .btn-info{background-color:var(--primary-color);border-color:var(--primary-color)}.conversejs .badge-info:hover,.conversejs .btn-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}.conversejs .badge-secondary,.conversejs .btn-secondary,.conversejs .button-cancel{color:var(--button-text-color);background-color:var(--secondary-color);border-color:var(--secondary-color)}.conversejs .badge-secondary:hover,.conversejs .btn-secondary:hover,.conversejs .button-cancel:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}.conversejs .btn-warning{color:var(--button-text-color);background-color:var(--warning-color);border-color:var(--warning-color)}.conversejs .btn-warning:hover{color:var(--button-text-color);background-color:var(--warning-color-dark);border-color:var(--warning-color-dark)}.conversejs .btn-danger{color:var(--button-text-color);background-color:var(--danger-color);border-color:var(--danger-color)!important}.conversejs .btn-danger:hover{background-color:var(--danger-color-dark);border-color:var(--danger-color-dark)}.conversejs .badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .badge{transition:none}}a.conversejs .badge:focus,a.conversejs .badge:hover{text-decoration:none}.conversejs .badge:empty{display:none}.conversejs .btn .badge{position:relative;top:-1px}.conversejs .badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.conversejs .badge-primary{color:#fff;background-color:#007bff}a.conversejs .badge-primary:focus,a.conversejs .badge-primary:hover{color:#fff;background-color:#0062cc}a.conversejs .badge-primary.focus,a.conversejs .badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .badge-secondary{color:#fff;background-color:#6c757d}a.conversejs .badge-secondary:focus,a.conversejs .badge-secondary:hover{color:#fff;background-color:#545b62}a.conversejs .badge-secondary.focus,a.conversejs .badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .badge-success{color:#fff;background-color:#28a745}a.conversejs .badge-success:focus,a.conversejs .badge-success:hover{color:#fff;background-color:#1e7e34}a.conversejs .badge-success.focus,a.conversejs .badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .badge-info{color:#fff;background-color:#17a2b8}a.conversejs .badge-info:focus,a.conversejs .badge-info:hover{color:#fff;background-color:#117a8b}a.conversejs .badge-info.focus,a.conversejs .badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .badge-warning{color:#212529;background-color:#ffc107}a.conversejs .badge-warning:focus,a.conversejs .badge-warning:hover{color:#212529;background-color:#d39e00}a.conversejs .badge-warning.focus,a.conversejs .badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .badge-danger{color:#fff;background-color:#dc3545}a.conversejs .badge-danger:focus,a.conversejs .badge-danger:hover{color:#fff;background-color:#bd2130}a.conversejs .badge-danger.focus,a.conversejs .badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .badge-light{color:#212529;background-color:#f8f9fa}a.conversejs .badge-light:focus,a.conversejs .badge-light:hover{color:#212529;background-color:#dae0e5}a.conversejs .badge-light.focus,a.conversejs .badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .badge-dark{color:#fff;background-color:#343a40}a.conversejs .badge-dark:focus,a.conversejs .badge-dark:hover{color:#fff;background-color:#1d2124}a.conversejs .badge-dark.focus,a.conversejs .badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .badge{color:#fff;font-size:90%;font-weight:400;line-height:1;text-shadow:none}.conversejs .badge-light{color:var(--text-color)}.conversejs .badge-primary{background-color:var(--primary-color);border-color:transparent}.conversejs .badge-primary:active,.conversejs .badge-primary:focus,.conversejs .badge-primary:hover{background-color:var(--primary-color-dark)!important;border-color:transparent!important}.conversejs .badge-info{background-color:var(--primary-color);border-color:var(--primary-color)}.conversejs .badge-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}.conversejs .badge-secondary{color:#fff;background-color:var(--secondary-color);border-color:var(--secondary-color)}.conversejs .badge-secondary:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}.conversejs .form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .form-control{transition:none}}.conversejs .form-control::-ms-expand{background-color:transparent;border:0}.conversejs .form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.conversejs .form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .form-control::-moz-placeholder{color:#6c757d;opacity:1}.conversejs .form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.conversejs .form-control::placeholder{color:#6c757d;opacity:1}.conversejs .form-control:disabled,.conversejs .form-control[readonly]{background-color:#e9ecef;opacity:1}.conversejs input[type=date].form-control,.conversejs input[type=datetime-local].form-control,.conversejs input[type=month].form-control,.conversejs input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.conversejs .form-control-file,.conversejs .form-control-range{display:block;width:100%}.conversejs .col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.conversejs .col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.conversejs .col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.conversejs .form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.conversejs .form-control-plaintext.form-control-lg,.conversejs .form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.conversejs .form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.conversejs .form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs select.form-control[multiple],.conversejs select.form-control[size]{height:auto}.conversejs textarea.form-control{height:auto}.conversejs .form-group{margin-bottom:1rem}.conversejs .form-text{display:block;margin-top:.25rem}.conversejs .form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.conversejs .form-row>.col,.conversejs .form-row>[class*=col-]{padding-right:5px;padding-left:5px}.conversejs .form-check{position:relative;display:block;padding-left:1.25rem}.conversejs .form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.conversejs .form-check-input:disabled~.form-check-label,.conversejs .form-check-input[disabled]~.form-check-label{color:#6c757d}.conversejs .form-check-label{margin-bottom:0}.conversejs .form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.conversejs .form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.conversejs .valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.conversejs .valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.conversejs .valid-tooltip,.form-row>[class*=col-]>.conversejs .valid-tooltip{left:5px}.conversejs.is-valid~.valid-feedback,.conversejs.is-valid~.valid-tooltip,.was-validated .conversejs:valid~.valid-feedback,.was-validated .conversejs:valid~.valid-tooltip{display:block}.conversejs .form-control.is-valid,.was-validated .conversejs .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.conversejs .form-control.is-valid:focus,.was-validated .conversejs .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs textarea.form-control.is-valid,.was-validated .conversejs textarea.form-control:valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.conversejs .custom-select.is-valid,.was-validated .conversejs .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.conversejs .custom-select.is-valid:focus,.was-validated .conversejs .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs .form-check-input.is-valid~.form-check-label,.was-validated .conversejs .form-check-input:valid~.form-check-label{color:#28a745}.conversejs .form-check-input.is-valid~.valid-feedback,.conversejs .form-check-input.is-valid~.valid-tooltip,.was-validated .conversejs .form-check-input:valid~.valid-feedback,.was-validated .conversejs .form-check-input:valid~.valid-tooltip{display:block}.conversejs .custom-control-input.is-valid~.custom-control-label,.was-validated .conversejs .custom-control-input:valid~.custom-control-label{color:#28a745}.conversejs .custom-control-input.is-valid~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.conversejs .custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.conversejs .custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.conversejs .custom-file-input.is-valid~.custom-file-label,.was-validated .conversejs .custom-file-input:valid~.custom-file-label{border-color:#28a745}.conversejs .custom-file-input.is-valid:focus~.custom-file-label,.was-validated .conversejs .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs .invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.conversejs .invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.conversejs .invalid-tooltip,.form-row>[class*=col-]>.conversejs .invalid-tooltip{left:5px}.conversejs.is-invalid~.invalid-feedback,.conversejs.is-invalid~.invalid-tooltip,.was-validated .conversejs:invalid~.invalid-feedback,.was-validated .conversejs:invalid~.invalid-tooltip{display:block}.conversejs .form-control.is-invalid,.was-validated .conversejs .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.conversejs .form-control.is-invalid:focus,.was-validated .conversejs .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs textarea.form-control.is-invalid,.was-validated .conversejs textarea.form-control:invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.conversejs .custom-select.is-invalid,.was-validated .conversejs .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.conversejs .custom-select.is-invalid:focus,.was-validated .conversejs .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs .form-check-input.is-invalid~.form-check-label,.was-validated .conversejs .form-check-input:invalid~.form-check-label{color:#dc3545}.conversejs .form-check-input.is-invalid~.invalid-feedback,.conversejs .form-check-input.is-invalid~.invalid-tooltip,.was-validated .conversejs .form-check-input:invalid~.invalid-feedback,.was-validated .conversejs .form-check-input:invalid~.invalid-tooltip{display:block}.conversejs .custom-control-input.is-invalid~.custom-control-label,.was-validated .conversejs .custom-control-input:invalid~.custom-control-label{color:#dc3545}.conversejs .custom-control-input.is-invalid~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.conversejs .custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.conversejs .custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.conversejs .custom-file-input.is-invalid~.custom-file-label,.was-validated .conversejs .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.conversejs .custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .conversejs .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs .form-inline{display:flex;flex-flow:row wrap;align-items:center}.conversejs .form-inline .form-check{width:100%}@media(min-width:576px){.conversejs .form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.conversejs .form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.conversejs .form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.conversejs .form-inline .form-control-plaintext{display:inline-block}.conversejs .form-inline .custom-select,.conversejs .form-inline .input-group{width:auto}.conversejs .form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.conversejs .form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.conversejs .form-inline .custom-control{align-items:center;justify-content:center}.conversejs .form-inline .custom-control-label{margin-bottom:0}}.conversejs .input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.conversejs .input-group>.custom-file,.conversejs .input-group>.custom-select,.conversejs .input-group>.form-control,.conversejs .input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.conversejs .input-group>.custom-file+.custom-file,.conversejs .input-group>.custom-file+.custom-select,.conversejs .input-group>.custom-file+.form-control,.conversejs .input-group>.custom-select+.custom-file,.conversejs .input-group>.custom-select+.custom-select,.conversejs .input-group>.custom-select+.form-control,.conversejs .input-group>.form-control+.custom-file,.conversejs .input-group>.form-control+.custom-select,.conversejs .input-group>.form-control+.form-control,.conversejs .input-group>.form-control-plaintext+.custom-file,.conversejs .input-group>.form-control-plaintext+.custom-select,.conversejs .input-group>.form-control-plaintext+.form-control{margin-left:-1px}.conversejs .input-group>.custom-file .custom-file-input:focus~.custom-file-label,.conversejs .input-group>.custom-select:focus,.conversejs .input-group>.form-control:focus{z-index:3}.conversejs .input-group>.custom-file .custom-file-input:focus{z-index:4}.conversejs .input-group>.custom-select:not(:first-child),.conversejs .input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .input-group>.custom-file{display:flex;align-items:center}.conversejs .input-group>.custom-file:not(:first-child) .custom-file-label,.conversejs .input-group>.custom-file:not(:last-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.conversejs .input-group:not(.has-validation)>.custom-select:not(:last-child),.conversejs .input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.conversejs .input-group.has-validation>.custom-select:nth-last-child(n+3),.conversejs .input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group-append,.conversejs .input-group-prepend{display:flex}.conversejs .input-group-append .btn,.conversejs .input-group-prepend .btn{position:relative;z-index:2}.conversejs .input-group-append .btn:focus,.conversejs .input-group-prepend .btn:focus{z-index:3}.conversejs .input-group-append .btn+.btn,.conversejs .input-group-append .btn+.input-group-text,.conversejs .input-group-append .input-group-text+.btn,.conversejs .input-group-append .input-group-text+.input-group-text,.conversejs .input-group-prepend .btn+.btn,.conversejs .input-group-prepend .btn+.input-group-text,.conversejs .input-group-prepend .input-group-text+.btn,.conversejs .input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.conversejs .input-group-prepend{margin-right:-1px}.conversejs .input-group-append{margin-left:-1px}.conversejs .input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.conversejs .input-group-text input[type=checkbox],.conversejs .input-group-text input[type=radio]{margin-top:0}.conversejs .input-group-lg>.custom-select,.conversejs .input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.conversejs .input-group-lg>.custom-select,.conversejs .input-group-lg>.form-control,.conversejs .input-group-lg>.input-group-append>.btn,.conversejs .input-group-lg>.input-group-append>.input-group-text,.conversejs .input-group-lg>.input-group-prepend>.btn,.conversejs .input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs .input-group-sm>.custom-select,.conversejs .input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.conversejs .input-group-sm>.custom-select,.conversejs .input-group-sm>.form-control,.conversejs .input-group-sm>.input-group-append>.btn,.conversejs .input-group-sm>.input-group-append>.input-group-text,.conversejs .input-group-sm>.input-group-prepend>.btn,.conversejs .input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.conversejs .input-group-lg>.custom-select,.conversejs .input-group-sm>.custom-select{padding-right:1.75rem}.conversejs .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.conversejs .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.conversejs .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.conversejs .input-group:not(.has-validation)>.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),.conversejs .input-group>.input-group-prepend>.btn,.conversejs .input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group>.input-group-append>.btn,.conversejs .input-group>.input-group-append>.input-group-text,.conversejs .input-group>.input-group-prepend:first-child>.btn:not(:first-child),.conversejs .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.conversejs .input-group>.input-group-prepend:not(:first-child)>.btn,.conversejs .input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}.conversejs .custom-control-inline{display:inline-flex;margin-right:1rem}.conversejs .custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.conversejs .custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.conversejs .custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.conversejs .custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.conversejs .custom-control-input:disabled~.custom-control-label,.conversejs .custom-control-input[disabled]~.custom-control-label{color:#6c757d}.conversejs .custom-control-input:disabled~.custom-control-label::before,.conversejs .custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.conversejs .custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.conversejs .custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.conversejs .custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.conversejs .custom-checkbox .custom-control-label::before{border-radius:.25rem}.conversejs .custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.conversejs .custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-radio .custom-control-label::before{border-radius:50%}.conversejs .custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.conversejs .custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-switch{padding-left:2.25rem}.conversejs .custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.conversejs .custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .custom-switch .custom-control-label::after{transition:none}}.conversejs .custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}.conversejs .custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs .custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-select:focus::-ms-value{color:#495057;background-color:#fff}.conversejs .custom-select[multiple],.conversejs .custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.conversejs .custom-select:disabled{color:#6c757d;background-color:#e9ecef}.conversejs .custom-select::-ms-expand{display:none}.conversejs .custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.conversejs .custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.conversejs .custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.conversejs .custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.conversejs .custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.conversejs .custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-file-input:disabled~.custom-file-label,.conversejs .custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.conversejs .custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.conversejs .custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.conversejs .custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.conversejs .custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.conversejs .custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs .custom-range:focus{outline:0}.conversejs .custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range::-moz-focus-outer{border:0}.conversejs .custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media(prefers-reduced-motion:reduce){.conversejs .custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.conversejs .custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.conversejs .custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media(prefers-reduced-motion:reduce){.conversejs .custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.conversejs .custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.conversejs .custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion:reduce){.conversejs .custom-range::-ms-thumb{-ms-transition:none;transition:none}}.conversejs .custom-range::-ms-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.conversejs .custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.conversejs .custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.conversejs .custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.conversejs .custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.conversejs .custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.conversejs .custom-range:disabled::-moz-range-track{cursor:default}.conversejs .custom-range:disabled::-ms-thumb{background-color:#adb5bd}.conversejs .custom-control-label::before,.conversejs .custom-file-label,.conversejs .custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .custom-control-label::before,.conversejs .custom-file-label,.conversejs .custom-select{transition:none}}.conversejs .btn--small{font-size:80%;font-weight:400}.conversejs form .hidden-username{opacity:0!important;height:0!important;padding:0!important}.conversejs form .error-feedback{margin-bottom:.5em}.conversejs form .form-check-label{margin-top:.3rem}.conversejs form .form-control::-moz-placeholder{color:var(--subdued-color)}.conversejs form .form-control:-ms-input-placeholder{color:var(--subdued-color)}.conversejs form .form-control::placeholder{color:var(--subdued-color)}.conversejs form .clear-input{margin-top:.5em;margin-bottom:.5em;position:absolute;right:.2em;cursor:pointer;font-size:var(--font-size)}.conversejs form#converse-login,.conversejs form#converse-register{background:var(--controlbox-pane-background-color)}.conversejs form#converse-login legend,.conversejs form#converse-register legend{width:100%;text-align:center;margin:0 auto .5em auto}.conversejs form#converse-login fieldset.buttons,.conversejs form#converse-register fieldset.buttons{text-align:center}.conversejs form#converse-login .login-anon,.conversejs form#converse-register .login-anon{height:auto;white-space:normal}.conversejs form#converse-login .save-submit,.conversejs form#converse-register .save-submit{color:var(--save-button-color)}.conversejs form#converse-login .form-url,.conversejs form#converse-register .form-url{display:block;font-weight:400;margin:1em 0}.conversejs form.converse-form{padding:1.2rem}.conversejs form.converse-form legend{color:var(--text-color);font-size:125%;margin-bottom:1.5em}.conversejs form.converse-form input[type=number],.conversejs form.converse-form input[type=password],.conversejs form.converse-form input[type=text],.conversejs form.converse-form select{min-width:50%}.conversejs form.converse-form input[type=button],.conversejs form.converse-form input[type=number],.conversejs form.converse-form input[type=password],.conversejs form.converse-form input[type=submit],.conversejs form.converse-form input[type=text]{padding:.5em}.conversejs form.converse-form input[type=button],.conversejs form.converse-form input[type=submit]{padding-left:1em;padding-right:1em;border:none}.conversejs form.converse-form input.error{border:1px solid var(--error-color);color:var(--text-color)}.conversejs form.converse-form .text-muted{color:var(--subdued-color)!important;font-size:85%;padding-top:.5em}.conversejs form.converse-form .text-muted a{color:var(--link-color-lighten-10-percent)}.conversejs form.converse-form .text-muted.error{color:var(--error-color)}.conversejs form.converse-form--modal{padding-bottom:0}.conversejs form.converse-form--spinner{height:100%}.conversejs form.converse-centered-form{min-height:66%;text-align:center}.conversejs form.converse-centered-form input{max-width:30em;margin:auto}.conversejs .list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.conversejs .list-group-item-action{width:100%;color:#495057;text-align:inherit}.conversejs .list-group-item-action:focus,.conversejs .list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.conversejs .list-group-item-action:active{color:#212529;background-color:#e9ecef}.conversejs .list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.conversejs .list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.conversejs .list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.conversejs .list-group-item.disabled,.conversejs .list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.conversejs .list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .list-group-item+.conversejs .list-group-item{border-top-width:0}.conversejs .list-group-item+.conversejs .list-group-item.active{margin-top:-1px;border-top-width:1px}.conversejs .list-group-horizontal{flex-direction:row}.conversejs .list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width:576px){.conversejs .list-group-horizontal-sm{flex-direction:row}.conversejs .list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-sm>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:768px){.conversejs .list-group-horizontal-md{flex-direction:row}.conversejs .list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-md>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:992px){.conversejs .list-group-horizontal-lg{flex-direction:row}.conversejs .list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-lg>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:1200px){.conversejs .list-group-horizontal-xl{flex-direction:row}.conversejs .list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-xl>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.conversejs .list-group-flush{border-radius:0}.conversejs .list-group-flush>.list-group-item{border-width:0 0 1px}.conversejs .list-group-flush>.list-group-item:last-child{border-bottom-width:0}.conversejs .list-group-item-primary{color:#004085;background-color:#b8daff}.conversejs .list-group-item-primary.list-group-item-action:focus,.conversejs .list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.conversejs .list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.conversejs .list-group-item-secondary{color:#383d41;background-color:#d6d8db}.conversejs .list-group-item-secondary.list-group-item-action:focus,.conversejs .list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.conversejs .list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.conversejs .list-group-item-success{color:#155724;background-color:#c3e6cb}.conversejs .list-group-item-success.list-group-item-action:focus,.conversejs .list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.conversejs .list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.conversejs .list-group-item-info{color:#0c5460;background-color:#bee5eb}.conversejs .list-group-item-info.list-group-item-action:focus,.conversejs .list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.conversejs .list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.conversejs .list-group-item-warning{color:#856404;background-color:#ffeeba}.conversejs .list-group-item-warning.list-group-item-action:focus,.conversejs .list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.conversejs .list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.conversejs .list-group-item-danger{color:#721c24;background-color:#f5c6cb}.conversejs .list-group-item-danger.list-group-item-action:focus,.conversejs .list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.conversejs .list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.conversejs .list-group-item-light{color:#818182;background-color:#fdfdfe}.conversejs .list-group-item-light.list-group-item-action:focus,.conversejs .list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.conversejs .list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.conversejs .list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.conversejs .list-group-item-dark.list-group-item-action:focus,.conversejs .list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.conversejs .list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.conversejs .list-group-item.active{background-color:var(--primary-color);border-color:var(--primary-color-dark)}.conversejs .list-container{text-align:left;padding:.3em 0}.conversejs .list-container .list-toggle{font-family:var(--heading-font);font-weight:var(--list-toggle-font-weight);display:block;color:var(--list-toggle-color);padding:0 0 .5rem 0}.conversejs .list-container .list-toggle:hover{color:var(--list-toggle-hover-color)}.conversejs .items-list{text-align:left}.conversejs .items-list .list-item{border:none;clear:both;color:var(--text-color);overflow:hidden;padding:.5em 0;text-shadow:0 1px 0 var(--text-shadow-color);word-wrap:break-word;height:2.5em}.conversejs .items-list .list-item.unread-msgs{font-weight:700}.conversejs .items-list .list-item .list-item-link{color:var(--list-item-link-color);margin:auto;font-size:var(--font-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;vertical-align:baseline}.conversejs .items-list .list-item .list-item-link:hover{color:var(--list-item-link-hover-color)}.conversejs .items-list .list-item .list-item-badge{opacity:1;border-radius:25%;color:#fff;font-size:var(--font-size-small);line-height:var(--font-size-small)}.conversejs .items-list .list-item .list-item-action{opacity:0;font-size:var(--font-size-tiny);padding:.3em 0 0 0;margin:0 0 0 var(--inline-action-margin);width:2em;height:2em;color:var(--subdued-color)}.conversejs .items-list .list-item .list-item-action:before{font-size:var(--font-size)}.conversejs .items-list .list-item .list-item-action.button-on{color:var(--list-item-link-color)}.conversejs .items-list .list-item .list-item-action.button-on:hover{color:var(--list-item-link-hover-color)}.conversejs .items-list .list-item .list-item-action:hover{color:var(--list-toggle-hover-color);opacity:1}.conversejs .items-list .list-item .list-item-action--visible{opacity:1!important}.conversejs .items-list .list-item.open{background-color:var(--list-item-open-color)}.conversejs .items-list .list-item.open:hover{background-color:var(--list-item-open-hover-color)!important}.conversejs .items-list .list-item.open a{color:#fff}.conversejs .items-list .list-item.open .list-item-link:hover{color:#fff}.conversejs .items-list .list-item.open .list-item-action{color:var(--list-item-action-color)}.conversejs .items-list .list-item.open .list-item-action:hover{color:#fff}.conversejs .items-list .list-item:hover{background-color:var(--controlbox-pane-bg-hover-color)}.conversejs .items-list .list-item:hover .fa,.conversejs .items-list .list-item:hover .far,.conversejs .items-list .list-item:hover .fas{opacity:1}.conversejs .styling-directive{color:var(--subdued-color)}.conversejs .older-msg time{font-weight:700}.conversejs .message .show-msg-author-modal{align-self:flex-start;color:var(--text-color)!important}.conversejs .message blockquote{margin-left:.5em;margin-bottom:.25em;padding-right:1em;color:var(--subdued-color);border-left:.3em solid var(--subdued-color);padding-left:.5em;display:inline-block}.conversejs .message code{font-family:monospace}.conversejs .message .mention{font-weight:700}.conversejs .message .mention--self{font-weight:400}.conversejs .message.date-separator,.conversejs .message.separator{height:2em;margin:0;position:relative;text-align:center;z-index:0}.conversejs .message.date-separator .separator,.conversejs .message.separator .separator{border-top:0;border-bottom:var(--chat-separator-border-bottom);margin:0 1em;position:relative;top:1em;z-index:5}.conversejs .message.date-separator .separator-text,.conversejs .message.separator .separator-text{background:#fff;bottom:1px;color:var(--separator-text-color);display:inline-block;line-height:2em;padding:0 1em;position:relative;z-index:5}.conversejs .message.chat-msg--retracted .chat-msg__message{color:var(--subdued-color)}.conversejs .message.chat-info{color:var(--chat-head-color);font-size:var(--message-font-size);line-height:var(--line-height-small);font-size:90%;padding:.17rem 1rem}.conversejs .message.chat-info.badge{color:var(--chat-head-text-color)}.conversejs .message.chat-info.chat-state-notification{font-style:italic}.conversejs .message.chat-info.chat-event{clear:left;font-style:italic}.conversejs .message.chat-info.chat-error{color:var(--error-color);font-weight:700}.conversejs .message.chat-info .q{font-style:italic}.conversejs .message .chat-image{height:auto;width:auto;max-height:15em;max-width:100%}.conversejs .message.chat-msg--action{font-style:italic}.conversejs .message.chat-msg--action .chat-msg__author{padding-right:.2em}.conversejs .message.chat-msg{display:inline-flex;width:100%;flex-direction:row;padding:.125rem 1rem}.conversejs .message.chat-msg.onload{animation:colorchange-chatmessage 1s;-webkit-animation:colorchange-chatmessage 1s}.conversejs .message.chat-msg:hover{background-color:var(--list-item-hover-color)}.conversejs .message.chat-msg.correcting.groupchat{background-color:var(--chatroom-correcting-color)}.conversejs .message.chat-msg.correcting:not(.groupchat){background-color:var(--chat-correcting-color)}.conversejs .message.chat-msg .spoiler{margin-top:.5em}.conversejs .message.chat-msg .spoiler-hint{margin-bottom:.5em}.conversejs .message.chat-msg .spoiler-toggle{color:#fff}.conversejs .message.chat-msg .spoiler-toggle i{color:#fff;padding-right:.5em}.conversejs .message.chat-msg .spoiler-toggle:before{padding-right:.25em;whitespace:nowrap}.conversejs .message.chat-msg .chat-msg__content{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-left:.5rem;width:calc(100% - var(--message-avatar-width))}.conversejs .message.chat-msg .chat-msg__content:hover .btn--standalone{opacity:1}.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat .chat-msg__text{color:var(--subdued-color)}.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--delayed .chat-msg__text,.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--received .chat-msg__text{color:var(--message-text-color)}.conversejs .message.chat-msg .chat-msg__content--action{width:100%;margin-left:0}.conversejs .message.chat-msg .chat-msg__body{display:flex;flex-direction:row;justify-content:space-between}.conversejs .message.chat-msg converse-chat-message-body{display:inline}.conversejs .message.chat-msg .chat-msg__message{line-height:1.5em;display:inline-flex;flex-direction:column;width:100%;overflow-wrap:break-word}.conversejs .message.chat-msg .chat-msg__edit-modal{cursor:pointer;padding-right:.5em}.conversejs .message.chat-msg .chat-msg__subject{font-weight:700;clear:right}.conversejs .message.chat-msg .chat-msg__text{color:var(--message-text-color);padding:0;white-space:pre-wrap;word-wrap:break-word;word-break:break-word}.conversejs .message.chat-msg .chat-msg__text a{word-wrap:break-word;word-break:break-all;display:inline}.conversejs .message.chat-msg .chat-msg__text a.chat-image__link{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:block}.conversejs .message.chat-msg .chat-msg__text img.emoji{height:1.5em;width:1.5em;margin:0 .05em 0 .1em;vertical-align:-.1em}.conversejs .message.chat-msg .chat-msg__text .emojione{margin-bottom:-6px}.conversejs .message.chat-msg .chat-msg__text--larger{font-size:1.6em;padding-top:.25em;padding-bottom:.25em}.conversejs .message.chat-msg .chat-msg__error{color:var(--error-color)}.conversejs .message.chat-msg .chat-msg__media{margin-top:.25rem;word-break:break-all}.conversejs .message.chat-msg .chat-msg__media a{word-wrap:break-word}.conversejs .message.chat-msg .chat-msg__media audio{width:100%}.conversejs .message.chat-msg converse-message-actions{margin-left:.5em}.conversejs .message.chat-msg .chat-msg__actions .dropdown-menu{min-width:5rem}.conversejs .message.chat-msg .chat-msg__actions i{color:var(--text-color-lighten-15-percent);font-size:70%}.conversejs .message.chat-msg .chat-msg__actions button{border:none;background:0 0;color:var(--text-color-lighten-15-percent);padding:0 .25em}.conversejs .message.chat-msg .chat-msg__actions .btn--standalone{opacity:0;margin-top:-.2em}.conversejs .message.chat-msg .chat-msg__actions .chat-msg__action{width:100%;padding:.5em 1em;text-align:left;white-space:nowrap}.conversejs .message.chat-msg .chat-msg__actions .chat-msg__action converse-icon{margin-right:.25em}.conversejs .message.chat-msg .chat-msg__actions .chat-msg__action:hover{color:var(--text-color);background-color:var(--list-item-hover-color)}.conversejs .message.chat-msg .chat-msg__avatar{margin-top:.5em;vertical-align:middle;height:var(--message-avatar-height);width:var(--message-avatar-width);min-height:var(--message-avatar-height);min-width:var(--message-avatar-width)}.conversejs .message.chat-msg .chat-msg__author{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--heading-font);font-size:115%;font-weight:700;padding-bottom:1px}.conversejs .message.chat-msg .chat-msg__heading{width:100%;margin-top:.5em;padding-right:.25rem;padding-bottom:.25rem}.conversejs .message.chat-msg .chat-msg__heading .badge{margin-left:.5em;font-family:var(--normal_font)}.conversejs .message.chat-msg .chat-msg__heading .chat-msg__time{padding-left:.25em;padding-right:.25em;color:var(--text-color-lighten-15-percent)}.conversejs .message.chat-msg.chat-msg--action .chat-msg__message{flex-direction:row}.conversejs .message.chat-msg.chat-msg--action .chat-msg__text{width:auto}.conversejs .message.chat-msg.chat-msg--action .chat-msg__heading{margin-top:0;padding-bottom:0;width:auto}.conversejs .message.chat-msg.chat-msg--action .chat-msg__heading .fa{margin-left:.5em}.conversejs .message.chat-msg.chat-msg--action .chat-msg__author{font-size:var(--message-font-size)}.conversejs .message.chat-msg.chat-msg--action .chat-msg__time{margin-left:0}.conversejs .message.chat-msg.chat-msg--followup .chat-msg__avatar,.conversejs .message.chat-msg.chat-msg--followup .chat-msg__heading{display:none}.conversejs .message.chat-msg.chat-msg--followup.chat-msg--with-avatar .chat-msg__content{margin-left:2.75rem;width:100%}.conversejs .message.chat-msg .chat-msg__receipt{margin-left:.5em;margin-right:.5em;color:var(--message-receipt-color)}.conversejs .chatroom-body .message.onload{animation:colorchange-chatmessage-muc 1s;-webkit-animation:colorchange-chatmessage-muc 1s}.conversejs .chatroom-body .message .separator{border-top:0;border-bottom:var(--chatroom-separator-border-bottom)}.conversejs converse-chats.converse-overlayed .message.chat-msg.chat-msg--followup .chat-msg__content{margin-left:0}@media screen and (max-width:767px){converse-chats:not(.converse-embedded) .message.chat-msg .chat-msg__author{white-space:normal}}#conversejs-bg .subdued{opacity:.35}#conversejs-bg .converse-brand{display:flex;justify-content:space-between;margin-top:15vh;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:5s;animation-duration:5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs-bg .converse-brand__text{color:#fff;font-family:var(--branding-font);font-weight:400;text-align:center;font-size:140%;margin-left:.2em}#conversejs-bg .converse-brand__text .byline{margin:0;font-family:var(--heading-font);font-size:.3em;opacity:.55;margin-bottom:2em;margin-left:-2.7em;word-spacing:5px}.converse-fullscreen #conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media(min-width:768px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 33.3333333333%;max-width:33.3333333333%}}@media(min-width:992px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 25%;max-width:25%}}@media(min-width:1200px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 16.6666666667%;max-width:16.6666666667%}}.converse-fullscreen #conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media(min-width:768px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.6666666667%;max-width:66.6666666667%}}@media(min-width:992px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 75%;max-width:75%}}@media(min-width:1200px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.3333333333%;max-width:83.3333333333%}}.converse-fullscreen #conversejs-bg .converse-brand__heading svg{margin-top:.3em}.converse-overlayed #conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media(min-width:768px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 16.6666666667%;max-width:16.6666666667%}}@media(min-width:992px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 8.3333333333%;max-width:8.3333333333%}}@media(min-width:1200px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 8.3333333333%;max-width:8.3333333333%}}.converse-overlayed #conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media(min-width:768px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.6666666667%;max-width:66.6666666667%}}@media(min-width:992px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 83.3333333333%;max-width:83.3333333333%}}@media(min-width:1200px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.3333333333%;max-width:83.3333333333%}}.converse-overlayed #conversejs-bg .converse-brand__heading svg{margin-top:.3em} + */@font-face{font-family:Baumans;font-style:normal;font-weight:400;src:local("Baumans Regular"),local("Baumans-Regular"),url(webfonts/baumans.ttf) format("truetype")}@font-face{font-family:Muli;font-style:normal;font-weight:400;src:local("Muli Regular"),local("Muli-Regular"),url(webfonts/muli.ttf) format("truetype")}@font-face{font-family:ConverseFontAwesomeBrands;font-style:normal;font-weight:400;src:url(webfonts/fa-brands-400.eot);src:url(webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(webfonts/fa-brands-400.woff2) format("woff2"),url(webfonts/fa-brands-400.woff) format("woff"),url(webfonts/fa-brands-400.ttf) format("truetype"),url(webfonts/fa-brands-400.svg#fontawesome) format("svg")}@font-face{font-family:ConverseFontAwesomeRegular;font-style:normal;font-weight:400;src:url(webfonts/fa-regular-400.eot);src:url(webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(webfonts/fa-regular-400.woff2) format("woff2"),url(webfonts/fa-regular-400.woff) format("woff"),url(webfonts/fa-regular-400.ttf) format("truetype"),url(webfonts/fa-regular-400.svg#fontawesome) format("svg");font-weight:400;font-style:normal}@font-face{font-family:ConverseFontAwesomeSolid;font-style:normal;font-weight:900;src:url(webfonts/fa-solid-900.eot);src:url(webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(webfonts/fa-solid-900.svg#fontawesome) format("svg"),url(webfonts/fa-solid-900.woff2) format("woff2"),url(webfonts/fa-solid-900.woff) format("woff"),url(webfonts/fa-solid-900.ttf) format("truetype")}.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scale(-1,1)}.fa-flip-vertical{transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:""}.fa-accessible-icon:before{content:""}.fa-accusoft:before{content:""}.fa-acquisitions-incorporated:before{content:""}.fa-ad:before{content:""}.fa-address-book:before{content:""}.fa-address-card:before{content:""}.fa-adjust:before{content:""}.fa-adn:before{content:""}.fa-adobe:before{content:""}.fa-adversal:before{content:""}.fa-affiliatetheme:before{content:""}.fa-air-freshener:before{content:""}.fa-airbnb:before{content:""}.fa-algolia:before{content:""}.fa-align-center:before{content:""}.fa-align-justify:before{content:""}.fa-align-left:before{content:""}.fa-align-right:before{content:""}.fa-alipay:before{content:""}.fa-allergies:before{content:""}.fa-amazon:before{content:""}.fa-amazon-pay:before{content:""}.fa-ambulance:before{content:""}.fa-american-sign-language-interpreting:before{content:""}.fa-amilia:before{content:""}.fa-anchor:before{content:""}.fa-android:before{content:""}.fa-angellist:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angry:before{content:""}.fa-angrycreative:before{content:""}.fa-angular:before{content:""}.fa-ankh:before{content:""}.fa-app-store:before{content:""}.fa-app-store-ios:before{content:""}.fa-apper:before{content:""}.fa-apple:before{content:""}.fa-apple-alt:before{content:""}.fa-apple-pay:before{content:""}.fa-archive:before{content:""}.fa-archway:before{content:""}.fa-arrow-alt-circle-down:before{content:""}.fa-arrow-alt-circle-left:before{content:""}.fa-arrow-alt-circle-right:before{content:""}.fa-arrow-alt-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-down:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrows-alt:before{content:""}.fa-arrows-alt-h:before{content:""}.fa-arrows-alt-v:before{content:""}.fa-artstation:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asterisk:before{content:""}.fa-asymmetrik:before{content:""}.fa-at:before{content:""}.fa-atlas:before{content:""}.fa-atlassian:before{content:""}.fa-atom:before{content:""}.fa-audible:before{content:""}.fa-audio-description:before{content:""}.fa-autoprefixer:before{content:""}.fa-avianex:before{content:""}.fa-aviato:before{content:""}.fa-award:before{content:""}.fa-aws:before{content:""}.fa-baby:before{content:""}.fa-baby-carriage:before{content:""}.fa-backspace:before{content:""}.fa-backward:before{content:""}.fa-bacon:before{content:""}.fa-bacteria:before{content:""}.fa-bacterium:before{content:""}.fa-bahai:before{content:""}.fa-balance-scale:before{content:""}.fa-balance-scale-left:before{content:""}.fa-balance-scale-right:before{content:""}.fa-ban:before{content:""}.fa-band-aid:before{content:""}.fa-bandcamp:before{content:""}.fa-barcode:before{content:""}.fa-bars:before{content:""}.fa-baseball-ball:before{content:""}.fa-basketball-ball:before{content:""}.fa-bath:before{content:""}.fa-battery-empty:before{content:""}.fa-battery-full:before{content:""}.fa-battery-half:before{content:""}.fa-battery-quarter:before{content:""}.fa-battery-three-quarters:before{content:""}.fa-battle-net:before{content:""}.fa-bed:before{content:""}.fa-beer:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-bell:before{content:""}.fa-bell-slash:before{content:""}.fa-bezier-curve:before{content:""}.fa-bible:before{content:""}.fa-bicycle:before{content:""}.fa-biking:before{content:""}.fa-bimobject:before{content:""}.fa-binoculars:before{content:""}.fa-biohazard:before{content:""}.fa-birthday-cake:before{content:""}.fa-bitbucket:before{content:""}.fa-bitcoin:before{content:""}.fa-bity:before{content:""}.fa-black-tie:before{content:""}.fa-blackberry:before{content:""}.fa-blender:before{content:""}.fa-blender-phone:before{content:""}.fa-blind:before{content:""}.fa-blog:before{content:""}.fa-blogger:before{content:""}.fa-blogger-b:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-bold:before{content:""}.fa-bolt:before{content:""}.fa-bomb:before{content:""}.fa-bone:before{content:""}.fa-bong:before{content:""}.fa-book:before{content:""}.fa-book-dead:before{content:""}.fa-book-medical:before{content:""}.fa-book-open:before{content:""}.fa-book-reader:before{content:""}.fa-bookmark:before{content:""}.fa-bootstrap:before{content:""}.fa-border-all:before{content:""}.fa-border-none:before{content:""}.fa-border-style:before{content:""}.fa-bowling-ball:before{content:""}.fa-box:before{content:""}.fa-box-open:before{content:""}.fa-box-tissue:before{content:""}.fa-boxes:before{content:""}.fa-braille:before{content:""}.fa-brain:before{content:""}.fa-bread-slice:before{content:""}.fa-briefcase:before{content:""}.fa-briefcase-medical:before{content:""}.fa-broadcast-tower:before{content:""}.fa-broom:before{content:""}.fa-brush:before{content:""}.fa-btc:before{content:""}.fa-buffer:before{content:""}.fa-bug:before{content:""}.fa-building:before{content:""}.fa-bullhorn:before{content:""}.fa-bullseye:before{content:""}.fa-burn:before{content:""}.fa-buromobelexperte:before{content:""}.fa-bus:before{content:""}.fa-bus-alt:before{content:""}.fa-business-time:before{content:""}.fa-buy-n-large:before{content:""}.fa-buysellads:before{content:""}.fa-calculator:before{content:""}.fa-calendar:before{content:""}.fa-calendar-alt:before{content:""}.fa-calendar-check:before{content:""}.fa-calendar-day:before{content:""}.fa-calendar-minus:before{content:""}.fa-calendar-plus:before{content:""}.fa-calendar-times:before{content:""}.fa-calendar-week:before{content:""}.fa-camera:before{content:""}.fa-camera-retro:before{content:""}.fa-campground:before{content:""}.fa-canadian-maple-leaf:before{content:""}.fa-candy-cane:before{content:""}.fa-cannabis:before{content:""}.fa-capsules:before{content:""}.fa-car:before{content:""}.fa-car-alt:before{content:""}.fa-car-battery:before{content:""}.fa-car-crash:before{content:""}.fa-car-side:before{content:""}.fa-caravan:before{content:""}.fa-caret-down:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-caret-square-down:before{content:""}.fa-caret-square-left:before{content:""}.fa-caret-square-right:before{content:""}.fa-caret-square-up:before{content:""}.fa-caret-up:before{content:""}.fa-carrot:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-cart-plus:before{content:""}.fa-cash-register:before{content:""}.fa-cat:before{content:""}.fa-cc-amazon-pay:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-apple-pay:before{content:""}.fa-cc-diners-club:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-cc-visa:before{content:""}.fa-centercode:before{content:""}.fa-centos:before{content:""}.fa-certificate:before{content:""}.fa-chair:before{content:""}.fa-chalkboard:before{content:""}.fa-chalkboard-teacher:before{content:""}.fa-charging-station:before{content:""}.fa-chart-area:before{content:""}.fa-chart-bar:before{content:""}.fa-chart-line:before{content:""}.fa-chart-pie:before{content:""}.fa-check:before{content:""}.fa-check-circle:before{content:""}.fa-check-double:before{content:""}.fa-check-square:before{content:""}.fa-cheese:before{content:""}.fa-chess:before{content:""}.fa-chess-bishop:before{content:""}.fa-chess-board:before{content:""}.fa-chess-king:before{content:""}.fa-chess-knight:before{content:""}.fa-chess-pawn:before{content:""}.fa-chess-queen:before{content:""}.fa-chess-rook:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-down:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-chevron-up:before{content:""}.fa-child:before{content:""}.fa-chrome:before{content:""}.fa-chromecast:before{content:""}.fa-church:before{content:""}.fa-circle:before{content:""}.fa-circle-notch:before{content:""}.fa-city:before{content:""}.fa-clinic-medical:before{content:""}.fa-clipboard:before{content:""}.fa-clipboard-check:before{content:""}.fa-clipboard-list:before{content:""}.fa-clock:before{content:""}.fa-clone:before{content:""}.fa-closed-captioning:before{content:""}.fa-cloud:before{content:""}.fa-cloud-download-alt:before{content:""}.fa-cloud-meatball:before{content:""}.fa-cloud-moon:before{content:""}.fa-cloud-moon-rain:before{content:""}.fa-cloud-rain:before{content:""}.fa-cloud-showers-heavy:before{content:""}.fa-cloud-sun:before{content:""}.fa-cloud-sun-rain:before{content:""}.fa-cloud-upload-alt:before{content:""}.fa-cloudscale:before{content:""}.fa-cloudsmith:before{content:""}.fa-cloudversify:before{content:""}.fa-cocktail:before{content:""}.fa-code:before{content:""}.fa-code-branch:before{content:""}.fa-codepen:before{content:""}.fa-codiepie:before{content:""}.fa-coffee:before{content:""}.fa-cog:before{content:""}.fa-cogs:before{content:""}.fa-coins:before{content:""}.fa-columns:before{content:""}.fa-comment:before{content:""}.fa-comment-alt:before{content:""}.fa-comment-dollar:before{content:""}.fa-comment-dots:before{content:""}.fa-comment-medical:before{content:""}.fa-comment-slash:before{content:""}.fa-comments:before{content:""}.fa-comments-dollar:before{content:""}.fa-compact-disc:before{content:""}.fa-compass:before{content:""}.fa-compress:before{content:""}.fa-compress-alt:before{content:""}.fa-compress-arrows-alt:before{content:""}.fa-concierge-bell:before{content:""}.fa-confluence:before{content:""}.fa-connectdevelop:before{content:""}.fa-contao:before{content:""}.fa-cookie:before{content:""}.fa-cookie-bite:before{content:""}.fa-copy:before{content:""}.fa-copyright:before{content:""}.fa-cotton-bureau:before{content:""}.fa-couch:before{content:""}.fa-cpanel:before{content:""}.fa-creative-commons:before{content:""}.fa-creative-commons-by:before{content:""}.fa-creative-commons-nc:before{content:""}.fa-creative-commons-nc-eu:before{content:""}.fa-creative-commons-nc-jp:before{content:""}.fa-creative-commons-nd:before{content:""}.fa-creative-commons-pd:before{content:""}.fa-creative-commons-pd-alt:before{content:""}.fa-creative-commons-remix:before{content:""}.fa-creative-commons-sa:before{content:""}.fa-creative-commons-sampling:before{content:""}.fa-creative-commons-sampling-plus:before{content:""}.fa-creative-commons-share:before{content:""}.fa-creative-commons-zero:before{content:""}.fa-credit-card:before{content:""}.fa-critical-role:before{content:""}.fa-crop:before{content:""}.fa-crop-alt:before{content:""}.fa-cross:before{content:""}.fa-crosshairs:before{content:""}.fa-crow:before{content:""}.fa-crown:before{content:""}.fa-crutch:before{content:""}.fa-css3:before{content:""}.fa-css3-alt:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-cut:before{content:""}.fa-cuttlefish:before{content:""}.fa-d-and-d:before{content:""}.fa-d-and-d-beyond:before{content:""}.fa-dailymotion:before{content:""}.fa-dashcube:before{content:""}.fa-database:before{content:""}.fa-deaf:before{content:""}.fa-deezer:before{content:""}.fa-delicious:before{content:""}.fa-democrat:before{content:""}.fa-deploydog:before{content:""}.fa-deskpro:before{content:""}.fa-desktop:before{content:""}.fa-dev:before{content:""}.fa-deviantart:before{content:""}.fa-dharmachakra:before{content:""}.fa-dhl:before{content:""}.fa-diagnoses:before{content:""}.fa-diaspora:before{content:""}.fa-dice:before{content:""}.fa-dice-d20:before{content:""}.fa-dice-d6:before{content:""}.fa-dice-five:before{content:""}.fa-dice-four:before{content:""}.fa-dice-one:before{content:""}.fa-dice-six:before{content:""}.fa-dice-three:before{content:""}.fa-dice-two:before{content:""}.fa-digg:before{content:""}.fa-digital-ocean:before{content:""}.fa-digital-tachograph:before{content:""}.fa-directions:before{content:""}.fa-discord:before{content:""}.fa-discourse:before{content:""}.fa-disease:before{content:""}.fa-divide:before{content:""}.fa-dizzy:before{content:""}.fa-dna:before{content:""}.fa-dochub:before{content:""}.fa-docker:before{content:""}.fa-dog:before{content:""}.fa-dollar-sign:before{content:""}.fa-dolly:before{content:""}.fa-dolly-flatbed:before{content:""}.fa-donate:before{content:""}.fa-door-closed:before{content:""}.fa-door-open:before{content:""}.fa-dot-circle:before{content:""}.fa-dove:before{content:""}.fa-download:before{content:""}.fa-draft2digital:before{content:""}.fa-drafting-compass:before{content:""}.fa-dragon:before{content:""}.fa-draw-polygon:before{content:""}.fa-dribbble:before{content:""}.fa-dribbble-square:before{content:""}.fa-dropbox:before{content:""}.fa-drum:before{content:""}.fa-drum-steelpan:before{content:""}.fa-drumstick-bite:before{content:""}.fa-drupal:before{content:""}.fa-dumbbell:before{content:""}.fa-dumpster:before{content:""}.fa-dumpster-fire:before{content:""}.fa-dungeon:before{content:""}.fa-dyalog:before{content:""}.fa-earlybirds:before{content:""}.fa-ebay:before{content:""}.fa-edge:before{content:""}.fa-edge-legacy:before{content:""}.fa-edit:before{content:""}.fa-egg:before{content:""}.fa-eject:before{content:""}.fa-elementor:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-ello:before{content:""}.fa-ember:before{content:""}.fa-empire:before{content:""}.fa-envelope:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-text:before{content:""}.fa-envelope-square:before{content:""}.fa-envira:before{content:""}.fa-equals:before{content:""}.fa-eraser:before{content:""}.fa-erlang:before{content:""}.fa-ethereum:before{content:""}.fa-ethernet:before{content:""}.fa-etsy:before{content:""}.fa-euro-sign:before{content:""}.fa-evernote:before{content:""}.fa-exchange-alt:before{content:""}.fa-exclamation:before{content:""}.fa-exclamation-circle:before{content:""}.fa-exclamation-triangle:before{content:""}.fa-expand:before{content:""}.fa-expand-alt:before{content:""}.fa-expand-arrows-alt:before{content:""}.fa-expeditedssl:before{content:""}.fa-external-link-alt:before{content:""}.fa-external-link-square-alt:before{content:""}.fa-eye:before{content:""}.fa-eye-dropper:before{content:""}.fa-eye-slash:before{content:""}.fa-facebook:before{content:""}.fa-facebook-f:before{content:""}.fa-facebook-messenger:before{content:""}.fa-facebook-square:before{content:""}.fa-fan:before{content:""}.fa-fantasy-flight-games:before{content:""}.fa-fast-backward:before{content:""}.fa-fast-forward:before{content:""}.fa-faucet:before{content:""}.fa-fax:before{content:""}.fa-feather:before{content:""}.fa-feather-alt:before{content:""}.fa-fedex:before{content:""}.fa-fedora:before{content:""}.fa-female:before{content:""}.fa-fighter-jet:before{content:""}.fa-figma:before{content:""}.fa-file:before{content:""}.fa-file-alt:before{content:""}.fa-file-archive:before{content:""}.fa-file-audio:before{content:""}.fa-file-code:before{content:""}.fa-file-contract:before{content:""}.fa-file-csv:before{content:""}.fa-file-download:before{content:""}.fa-file-excel:before{content:""}.fa-file-export:before{content:""}.fa-file-image:before{content:""}.fa-file-import:before{content:""}.fa-file-invoice:before{content:""}.fa-file-invoice-dollar:before{content:""}.fa-file-medical:before{content:""}.fa-file-medical-alt:before{content:""}.fa-file-pdf:before{content:""}.fa-file-powerpoint:before{content:""}.fa-file-prescription:before{content:""}.fa-file-signature:before{content:""}.fa-file-upload:before{content:""}.fa-file-video:before{content:""}.fa-file-word:before{content:""}.fa-fill:before{content:""}.fa-fill-drip:before{content:""}.fa-film:before{content:""}.fa-filter:before{content:""}.fa-fingerprint:before{content:""}.fa-fire:before{content:""}.fa-fire-alt:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-firefox:before{content:""}.fa-firefox-browser:before{content:""}.fa-first-aid:before{content:""}.fa-first-order:before{content:""}.fa-first-order-alt:before{content:""}.fa-firstdraft:before{content:""}.fa-fish:before{content:""}.fa-fist-raised:before{content:""}.fa-flag:before{content:""}.fa-flag-checkered:before{content:""}.fa-flag-usa:before{content:""}.fa-flask:before{content:""}.fa-flickr:before{content:""}.fa-flipboard:before{content:""}.fa-flushed:before{content:""}.fa-fly:before{content:""}.fa-folder:before{content:""}.fa-folder-minus:before{content:""}.fa-folder-open:before{content:""}.fa-folder-plus:before{content:""}.fa-font:before{content:""}.fa-font-awesome:before{content:""}.fa-font-awesome-alt:before{content:""}.fa-font-awesome-flag:before{content:""}.fa-font-awesome-logo-full:before{content:""}.fa-fonticons:before{content:""}.fa-fonticons-fi:before{content:""}.fa-football-ball:before{content:""}.fa-fort-awesome:before{content:""}.fa-fort-awesome-alt:before{content:""}.fa-forumbee:before{content:""}.fa-forward:before{content:""}.fa-foursquare:before{content:""}.fa-free-code-camp:before{content:""}.fa-freebsd:before{content:""}.fa-frog:before{content:""}.fa-frown:before{content:""}.fa-frown-open:before{content:""}.fa-fulcrum:before{content:""}.fa-funnel-dollar:before{content:""}.fa-futbol:before{content:""}.fa-galactic-republic:before{content:""}.fa-galactic-senate:before{content:""}.fa-gamepad:before{content:""}.fa-gas-pump:before{content:""}.fa-gavel:before{content:""}.fa-gem:before{content:""}.fa-genderless:before{content:""}.fa-get-pocket:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-ghost:before{content:""}.fa-gift:before{content:""}.fa-gifts:before{content:""}.fa-git:before{content:""}.fa-git-alt:before{content:""}.fa-git-square:before{content:""}.fa-github:before{content:""}.fa-github-alt:before{content:""}.fa-github-square:before{content:""}.fa-gitkraken:before{content:""}.fa-gitlab:before{content:""}.fa-gitter:before{content:""}.fa-glass-cheers:before{content:""}.fa-glass-martini:before{content:""}.fa-glass-martini-alt:before{content:""}.fa-glass-whiskey:before{content:""}.fa-glasses:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-globe:before{content:""}.fa-globe-africa:before{content:""}.fa-globe-americas:before{content:""}.fa-globe-asia:before{content:""}.fa-globe-europe:before{content:""}.fa-gofore:before{content:""}.fa-golf-ball:before{content:""}.fa-goodreads:before{content:""}.fa-goodreads-g:before{content:""}.fa-google:before{content:""}.fa-google-drive:before{content:""}.fa-google-pay:before{content:""}.fa-google-play:before{content:""}.fa-google-plus:before{content:""}.fa-google-plus-g:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-wallet:before{content:""}.fa-gopuram:before{content:""}.fa-graduation-cap:before{content:""}.fa-gratipay:before{content:""}.fa-grav:before{content:""}.fa-greater-than:before{content:""}.fa-greater-than-equal:before{content:""}.fa-grimace:before{content:""}.fa-grin:before{content:""}.fa-grin-alt:before{content:""}.fa-grin-beam:before{content:""}.fa-grin-beam-sweat:before{content:""}.fa-grin-hearts:before{content:""}.fa-grin-squint:before{content:""}.fa-grin-squint-tears:before{content:""}.fa-grin-stars:before{content:""}.fa-grin-tears:before{content:""}.fa-grin-tongue:before{content:""}.fa-grin-tongue-squint:before{content:""}.fa-grin-tongue-wink:before{content:""}.fa-grin-wink:before{content:""}.fa-grip-horizontal:before{content:""}.fa-grip-lines:before{content:""}.fa-grip-lines-vertical:before{content:""}.fa-grip-vertical:before{content:""}.fa-gripfire:before{content:""}.fa-grunt:before{content:""}.fa-guitar:before{content:""}.fa-gulp:before{content:""}.fa-h-square:before{content:""}.fa-hacker-news:before{content:""}.fa-hacker-news-square:before{content:""}.fa-hackerrank:before{content:""}.fa-hamburger:before{content:""}.fa-hammer:before{content:""}.fa-hamsa:before{content:""}.fa-hand-holding:before{content:""}.fa-hand-holding-heart:before{content:""}.fa-hand-holding-medical:before{content:""}.fa-hand-holding-usd:before{content:""}.fa-hand-holding-water:before{content:""}.fa-hand-lizard:before{content:""}.fa-hand-middle-finger:before{content:""}.fa-hand-paper:before{content:""}.fa-hand-peace:before{content:""}.fa-hand-point-down:before{content:""}.fa-hand-point-left:before{content:""}.fa-hand-point-right:before{content:""}.fa-hand-point-up:before{content:""}.fa-hand-pointer:before{content:""}.fa-hand-rock:before{content:""}.fa-hand-scissors:before{content:""}.fa-hand-sparkles:before{content:""}.fa-hand-spock:before{content:""}.fa-hands:before{content:""}.fa-hands-helping:before{content:""}.fa-hands-wash:before{content:""}.fa-handshake:before{content:""}.fa-handshake-alt-slash:before{content:""}.fa-handshake-slash:before{content:""}.fa-hanukiah:before{content:""}.fa-hard-hat:before{content:""}.fa-hashtag:before{content:""}.fa-hat-cowboy:before{content:""}.fa-hat-cowboy-side:before{content:""}.fa-hat-wizard:before{content:""}.fa-hdd:before{content:""}.fa-head-side-cough:before{content:""}.fa-head-side-cough-slash:before{content:""}.fa-head-side-mask:before{content:""}.fa-head-side-virus:before{content:""}.fa-heading:before{content:""}.fa-headphones:before{content:""}.fa-headphones-alt:before{content:""}.fa-headset:before{content:""}.fa-heart:before{content:""}.fa-heart-broken:before{content:""}.fa-heartbeat:before{content:""}.fa-helicopter:before{content:""}.fa-highlighter:before{content:""}.fa-hiking:before{content:""}.fa-hippo:before{content:""}.fa-hips:before{content:""}.fa-hire-a-helper:before{content:""}.fa-history:before{content:""}.fa-hockey-puck:before{content:""}.fa-holly-berry:before{content:""}.fa-home:before{content:""}.fa-hooli:before{content:""}.fa-hornbill:before{content:""}.fa-horse:before{content:""}.fa-horse-head:before{content:""}.fa-hospital:before{content:""}.fa-hospital-alt:before{content:""}.fa-hospital-symbol:before{content:""}.fa-hospital-user:before{content:""}.fa-hot-tub:before{content:""}.fa-hotdog:before{content:""}.fa-hotel:before{content:""}.fa-hotjar:before{content:""}.fa-hourglass:before{content:""}.fa-hourglass-end:before{content:""}.fa-hourglass-half:before{content:""}.fa-hourglass-start:before{content:""}.fa-house-damage:before{content:""}.fa-house-user:before{content:""}.fa-houzz:before{content:""}.fa-hryvnia:before{content:""}.fa-html5:before{content:""}.fa-hubspot:before{content:""}.fa-i-cursor:before{content:""}.fa-ice-cream:before{content:""}.fa-icicles:before{content:""}.fa-icons:before{content:""}.fa-id-badge:before{content:""}.fa-id-card:before{content:""}.fa-id-card-alt:before{content:""}.fa-ideal:before{content:""}.fa-igloo:before{content:""}.fa-image:before{content:""}.fa-images:before{content:""}.fa-imdb:before{content:""}.fa-inbox:before{content:""}.fa-indent:before{content:""}.fa-industry:before{content:""}.fa-infinity:before{content:""}.fa-info:before{content:""}.fa-info-circle:before{content:""}.fa-instagram:before{content:""}.fa-instagram-square:before{content:""}.fa-intercom:before{content:""}.fa-internet-explorer:before{content:""}.fa-invision:before{content:""}.fa-ioxhost:before{content:""}.fa-italic:before{content:""}.fa-itch-io:before{content:""}.fa-itunes:before{content:""}.fa-itunes-note:before{content:""}.fa-java:before{content:""}.fa-jedi:before{content:""}.fa-jedi-order:before{content:""}.fa-jenkins:before{content:""}.fa-jira:before{content:""}.fa-joget:before{content:""}.fa-joint:before{content:""}.fa-joomla:before{content:""}.fa-journal-whills:before{content:""}.fa-js:before{content:""}.fa-js-square:before{content:""}.fa-jsfiddle:before{content:""}.fa-kaaba:before{content:""}.fa-kaggle:before{content:""}.fa-key:before{content:""}.fa-keybase:before{content:""}.fa-keyboard:before{content:""}.fa-keycdn:before{content:""}.fa-khanda:before{content:""}.fa-kickstarter:before{content:""}.fa-kickstarter-k:before{content:""}.fa-kiss:before{content:""}.fa-kiss-beam:before{content:""}.fa-kiss-wink-heart:before{content:""}.fa-kiwi-bird:before{content:""}.fa-korvue:before{content:""}.fa-landmark:before{content:""}.fa-language:before{content:""}.fa-laptop:before{content:""}.fa-laptop-code:before{content:""}.fa-laptop-house:before{content:""}.fa-laptop-medical:before{content:""}.fa-laravel:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-laugh:before{content:""}.fa-laugh-beam:before{content:""}.fa-laugh-squint:before{content:""}.fa-laugh-wink:before{content:""}.fa-layer-group:before{content:""}.fa-leaf:before{content:""}.fa-leanpub:before{content:""}.fa-lemon:before{content:""}.fa-less:before{content:""}.fa-less-than:before{content:""}.fa-less-than-equal:before{content:""}.fa-level-down-alt:before{content:""}.fa-level-up-alt:before{content:""}.fa-life-ring:before{content:""}.fa-lightbulb:before{content:""}.fa-line:before{content:""}.fa-link:before{content:""}.fa-linkedin:before{content:""}.fa-linkedin-in:before{content:""}.fa-linode:before{content:""}.fa-linux:before{content:""}.fa-lira-sign:before{content:""}.fa-list:before{content:""}.fa-list-alt:before{content:""}.fa-list-ol:before{content:""}.fa-list-ul:before{content:""}.fa-location-arrow:before{content:""}.fa-lock:before{content:""}.fa-lock-open:before{content:""}.fa-long-arrow-alt-down:before{content:""}.fa-long-arrow-alt-left:before{content:""}.fa-long-arrow-alt-right:before{content:""}.fa-long-arrow-alt-up:before{content:""}.fa-low-vision:before{content:""}.fa-luggage-cart:before{content:""}.fa-lungs:before{content:""}.fa-lungs-virus:before{content:""}.fa-lyft:before{content:""}.fa-magento:before{content:""}.fa-magic:before{content:""}.fa-magnet:before{content:""}.fa-mail-bulk:before{content:""}.fa-mailchimp:before{content:""}.fa-male:before{content:""}.fa-mandalorian:before{content:""}.fa-map:before{content:""}.fa-map-marked:before{content:""}.fa-map-marked-alt:before{content:""}.fa-map-marker:before{content:""}.fa-map-marker-alt:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-markdown:before{content:""}.fa-marker:before{content:""}.fa-mars:before{content:""}.fa-mars-double:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mask:before{content:""}.fa-mastodon:before{content:""}.fa-maxcdn:before{content:""}.fa-mdb:before{content:""}.fa-medal:before{content:""}.fa-medapps:before{content:""}.fa-medium:before{content:""}.fa-medium-m:before{content:""}.fa-medkit:before{content:""}.fa-medrt:before{content:""}.fa-meetup:before{content:""}.fa-megaport:before{content:""}.fa-meh:before{content:""}.fa-meh-blank:before{content:""}.fa-meh-rolling-eyes:before{content:""}.fa-memory:before{content:""}.fa-mendeley:before{content:""}.fa-menorah:before{content:""}.fa-mercury:before{content:""}.fa-meteor:before{content:""}.fa-microblog:before{content:""}.fa-microchip:before{content:""}.fa-microphone:before{content:""}.fa-microphone-alt:before{content:""}.fa-microphone-alt-slash:before{content:""}.fa-microphone-slash:before{content:""}.fa-microscope:before{content:""}.fa-microsoft:before{content:""}.fa-minus:before{content:""}.fa-minus-circle:before{content:""}.fa-minus-square:before{content:""}.fa-mitten:before{content:""}.fa-mix:before{content:""}.fa-mixcloud:before{content:""}.fa-mixer:before{content:""}.fa-mizuni:before{content:""}.fa-mobile:before{content:""}.fa-mobile-alt:before{content:""}.fa-modx:before{content:""}.fa-monero:before{content:""}.fa-money-bill:before{content:""}.fa-money-bill-alt:before{content:""}.fa-money-bill-wave:before{content:""}.fa-money-bill-wave-alt:before{content:""}.fa-money-check:before{content:""}.fa-money-check-alt:before{content:""}.fa-monument:before{content:""}.fa-moon:before{content:""}.fa-mortar-pestle:before{content:""}.fa-mosque:before{content:""}.fa-motorcycle:before{content:""}.fa-mountain:before{content:""}.fa-mouse:before{content:""}.fa-mouse-pointer:before{content:""}.fa-mug-hot:before{content:""}.fa-music:before{content:""}.fa-napster:before{content:""}.fa-neos:before{content:""}.fa-network-wired:before{content:""}.fa-neuter:before{content:""}.fa-newspaper:before{content:""}.fa-nimblr:before{content:""}.fa-node:before{content:""}.fa-node-js:before{content:""}.fa-not-equal:before{content:""}.fa-notes-medical:before{content:""}.fa-npm:before{content:""}.fa-ns8:before{content:""}.fa-nutritionix:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-oil-can:before{content:""}.fa-old-republic:before{content:""}.fa-om:before{content:""}.fa-opencart:before{content:""}.fa-openid:before{content:""}.fa-opera:before{content:""}.fa-optin-monster:before{content:""}.fa-orcid:before{content:""}.fa-osi:before{content:""}.fa-otter:before{content:""}.fa-outdent:before{content:""}.fa-page4:before{content:""}.fa-pagelines:before{content:""}.fa-pager:before{content:""}.fa-paint-brush:before{content:""}.fa-paint-roller:before{content:""}.fa-palette:before{content:""}.fa-palfed:before{content:""}.fa-pallet:before{content:""}.fa-paper-plane:before{content:""}.fa-paperclip:before{content:""}.fa-parachute-box:before{content:""}.fa-paragraph:before{content:""}.fa-parking:before{content:""}.fa-passport:before{content:""}.fa-pastafarianism:before{content:""}.fa-paste:before{content:""}.fa-patreon:before{content:""}.fa-pause:before{content:""}.fa-pause-circle:before{content:""}.fa-paw:before{content:""}.fa-paypal:before{content:""}.fa-peace:before{content:""}.fa-pen:before{content:""}.fa-pen-alt:before{content:""}.fa-pen-fancy:before{content:""}.fa-pen-nib:before{content:""}.fa-pen-square:before{content:""}.fa-pencil-alt:before{content:""}.fa-pencil-ruler:before{content:""}.fa-penny-arcade:before{content:""}.fa-people-arrows:before{content:""}.fa-people-carry:before{content:""}.fa-pepper-hot:before{content:""}.fa-percent:before{content:""}.fa-percentage:before{content:""}.fa-periscope:before{content:""}.fa-person-booth:before{content:""}.fa-phabricator:before{content:""}.fa-phoenix-framework:before{content:""}.fa-phoenix-squadron:before{content:""}.fa-phone:before{content:""}.fa-phone-alt:before{content:""}.fa-phone-slash:before{content:""}.fa-phone-square:before{content:""}.fa-phone-square-alt:before{content:""}.fa-phone-volume:before{content:""}.fa-photo-video:before{content:""}.fa-php:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-pied-piper-hat:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-square:before{content:""}.fa-piggy-bank:before{content:""}.fa-pills:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-p:before{content:""}.fa-pinterest-square:before{content:""}.fa-pizza-slice:before{content:""}.fa-place-of-worship:before{content:""}.fa-plane:before{content:""}.fa-plane-arrival:before{content:""}.fa-plane-departure:before{content:""}.fa-plane-slash:before{content:""}.fa-play:before{content:""}.fa-play-circle:before{content:""}.fa-playstation:before{content:""}.fa-plug:before{content:""}.fa-plus:before{content:""}.fa-plus-circle:before{content:""}.fa-plus-square:before{content:""}.fa-podcast:before{content:""}.fa-poll:before{content:""}.fa-poll-h:before{content:""}.fa-poo:before{content:""}.fa-poo-storm:before{content:""}.fa-poop:before{content:""}.fa-portrait:before{content:""}.fa-pound-sign:before{content:""}.fa-power-off:before{content:""}.fa-pray:before{content:""}.fa-praying-hands:before{content:""}.fa-prescription:before{content:""}.fa-prescription-bottle:before{content:""}.fa-prescription-bottle-alt:before{content:""}.fa-print:before{content:""}.fa-procedures:before{content:""}.fa-product-hunt:before{content:""}.fa-project-diagram:before{content:""}.fa-pump-medical:before{content:""}.fa-pump-soap:before{content:""}.fa-pushed:before{content:""}.fa-puzzle-piece:before{content:""}.fa-python:before{content:""}.fa-qq:before{content:""}.fa-qrcode:before{content:""}.fa-question:before{content:""}.fa-question-circle:before{content:""}.fa-quidditch:before{content:""}.fa-quinscape:before{content:""}.fa-quora:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-quran:before{content:""}.fa-r-project:before{content:""}.fa-radiation:before{content:""}.fa-radiation-alt:before{content:""}.fa-rainbow:before{content:""}.fa-random:before{content:""}.fa-raspberry-pi:before{content:""}.fa-ravelry:before{content:""}.fa-react:before{content:""}.fa-reacteurope:before{content:""}.fa-readme:before{content:""}.fa-rebel:before{content:""}.fa-receipt:before{content:""}.fa-record-vinyl:before{content:""}.fa-recycle:before{content:""}.fa-red-river:before{content:""}.fa-reddit:before{content:""}.fa-reddit-alien:before{content:""}.fa-reddit-square:before{content:""}.fa-redhat:before{content:""}.fa-redo:before{content:""}.fa-redo-alt:before{content:""}.fa-registered:before{content:""}.fa-remove-format:before{content:""}.fa-renren:before{content:""}.fa-reply:before{content:""}.fa-reply-all:before{content:""}.fa-replyd:before{content:""}.fa-republican:before{content:""}.fa-researchgate:before{content:""}.fa-resolving:before{content:""}.fa-restroom:before{content:""}.fa-retweet:before{content:""}.fa-rev:before{content:""}.fa-ribbon:before{content:""}.fa-ring:before{content:""}.fa-road:before{content:""}.fa-robot:before{content:""}.fa-rocket:before{content:""}.fa-rocketchat:before{content:""}.fa-rockrms:before{content:""}.fa-route:before{content:""}.fa-rss:before{content:""}.fa-rss-square:before{content:""}.fa-ruble-sign:before{content:""}.fa-ruler:before{content:""}.fa-ruler-combined:before{content:""}.fa-ruler-horizontal:before{content:""}.fa-ruler-vertical:before{content:""}.fa-running:before{content:""}.fa-rupee-sign:before{content:""}.fa-rust:before{content:""}.fa-sad-cry:before{content:""}.fa-sad-tear:before{content:""}.fa-safari:before{content:""}.fa-salesforce:before{content:""}.fa-sass:before{content:""}.fa-satellite:before{content:""}.fa-satellite-dish:before{content:""}.fa-save:before{content:""}.fa-schlix:before{content:""}.fa-school:before{content:""}.fa-screwdriver:before{content:""}.fa-scribd:before{content:""}.fa-scroll:before{content:""}.fa-sd-card:before{content:""}.fa-search:before{content:""}.fa-search-dollar:before{content:""}.fa-search-location:before{content:""}.fa-search-minus:before{content:""}.fa-search-plus:before{content:""}.fa-searchengin:before{content:""}.fa-seedling:before{content:""}.fa-sellcast:before{content:""}.fa-sellsy:before{content:""}.fa-server:before{content:""}.fa-servicestack:before{content:""}.fa-shapes:before{content:""}.fa-share:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-share-square:before{content:""}.fa-shekel-sign:before{content:""}.fa-shield-alt:before{content:""}.fa-shield-virus:before{content:""}.fa-ship:before{content:""}.fa-shipping-fast:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-shoe-prints:before{content:""}.fa-shopify:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-shopping-cart:before{content:""}.fa-shopware:before{content:""}.fa-shower:before{content:""}.fa-shuttle-van:before{content:""}.fa-sign:before{content:""}.fa-sign-in-alt:before{content:""}.fa-sign-language:before{content:""}.fa-sign-out-alt:before{content:""}.fa-signal:before{content:""}.fa-signature:before{content:""}.fa-sim-card:before{content:""}.fa-simplybuilt:before{content:""}.fa-sink:before{content:""}.fa-sistrix:before{content:""}.fa-sitemap:before{content:""}.fa-sith:before{content:""}.fa-skating:before{content:""}.fa-sketch:before{content:""}.fa-skiing:before{content:""}.fa-skiing-nordic:before{content:""}.fa-skull:before{content:""}.fa-skull-crossbones:before{content:""}.fa-skyatlas:before{content:""}.fa-skype:before{content:""}.fa-slack:before{content:""}.fa-slack-hash:before{content:""}.fa-slash:before{content:""}.fa-sleigh:before{content:""}.fa-sliders-h:before{content:""}.fa-slideshare:before{content:""}.fa-smile:before{content:""}.fa-smile-beam:before{content:""}.fa-smile-wink:before{content:""}.fa-smog:before{content:""}.fa-smoking:before{content:""}.fa-smoking-ban:before{content:""}.fa-sms:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-snowboarding:before{content:""}.fa-snowflake:before{content:""}.fa-snowman:before{content:""}.fa-snowplow:before{content:""}.fa-soap:before{content:""}.fa-socks:before{content:""}.fa-solar-panel:before{content:""}.fa-sort:before{content:""}.fa-sort-alpha-down:before{content:""}.fa-sort-alpha-down-alt:before{content:""}.fa-sort-alpha-up:before{content:""}.fa-sort-alpha-up-alt:before{content:""}.fa-sort-amount-down:before{content:""}.fa-sort-amount-down-alt:before{content:""}.fa-sort-amount-up:before{content:""}.fa-sort-amount-up-alt:before{content:""}.fa-sort-down:before{content:""}.fa-sort-numeric-down:before{content:""}.fa-sort-numeric-down-alt:before{content:""}.fa-sort-numeric-up:before{content:""}.fa-sort-numeric-up-alt:before{content:""}.fa-sort-up:before{content:""}.fa-soundcloud:before{content:""}.fa-sourcetree:before{content:""}.fa-spa:before{content:""}.fa-space-shuttle:before{content:""}.fa-speakap:before{content:""}.fa-speaker-deck:before{content:""}.fa-spell-check:before{content:""}.fa-spider:before{content:""}.fa-spinner:before{content:""}.fa-splotch:before{content:""}.fa-spotify:before{content:""}.fa-spray-can:before{content:""}.fa-square:before{content:""}.fa-square-full:before{content:""}.fa-square-root-alt:before{content:""}.fa-squarespace:before{content:""}.fa-stack-exchange:before{content:""}.fa-stack-overflow:before{content:""}.fa-stackpath:before{content:""}.fa-stamp:before{content:""}.fa-star:before{content:""}.fa-star-and-crescent:before{content:""}.fa-star-half:before{content:""}.fa-star-half-alt:before{content:""}.fa-star-of-david:before{content:""}.fa-star-of-life:before{content:""}.fa-staylinked:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-steam-symbol:before{content:""}.fa-step-backward:before{content:""}.fa-step-forward:before{content:""}.fa-stethoscope:before{content:""}.fa-sticker-mule:before{content:""}.fa-sticky-note:before{content:""}.fa-stop:before{content:""}.fa-stop-circle:before{content:""}.fa-stopwatch:before{content:""}.fa-stopwatch-20:before{content:""}.fa-store:before{content:""}.fa-store-alt:before{content:""}.fa-store-alt-slash:before{content:""}.fa-store-slash:before{content:""}.fa-strava:before{content:""}.fa-stream:before{content:""}.fa-street-view:before{content:""}.fa-strikethrough:before{content:""}.fa-stripe:before{content:""}.fa-stripe-s:before{content:""}.fa-stroopwafel:before{content:""}.fa-studiovinari:before{content:""}.fa-stumbleupon:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-subscript:before{content:""}.fa-subway:before{content:""}.fa-suitcase:before{content:""}.fa-suitcase-rolling:before{content:""}.fa-sun:before{content:""}.fa-superpowers:before{content:""}.fa-superscript:before{content:""}.fa-supple:before{content:""}.fa-surprise:before{content:""}.fa-suse:before{content:""}.fa-swatchbook:before{content:""}.fa-swift:before{content:""}.fa-swimmer:before{content:""}.fa-swimming-pool:before{content:""}.fa-symfony:before{content:""}.fa-synagogue:before{content:""}.fa-sync:before{content:""}.fa-sync-alt:before{content:""}.fa-syringe:before{content:""}.fa-table:before{content:""}.fa-table-tennis:before{content:""}.fa-tablet:before{content:""}.fa-tablet-alt:before{content:""}.fa-tablets:before{content:""}.fa-tachometer-alt:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-tape:before{content:""}.fa-tasks:before{content:""}.fa-taxi:before{content:""}.fa-teamspeak:before{content:""}.fa-teeth:before{content:""}.fa-teeth-open:before{content:""}.fa-telegram:before{content:""}.fa-telegram-plane:before{content:""}.fa-temperature-high:before{content:""}.fa-temperature-low:before{content:""}.fa-tencent-weibo:before{content:""}.fa-tenge:before{content:""}.fa-terminal:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-th:before{content:""}.fa-th-large:before{content:""}.fa-th-list:before{content:""}.fa-the-red-yeti:before{content:""}.fa-theater-masks:before{content:""}.fa-themeco:before{content:""}.fa-themeisle:before{content:""}.fa-thermometer:before{content:""}.fa-thermometer-empty:before{content:""}.fa-thermometer-full:before{content:""}.fa-thermometer-half:before{content:""}.fa-thermometer-quarter:before{content:""}.fa-thermometer-three-quarters:before{content:""}.fa-think-peaks:before{content:""}.fa-thumbs-down:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbtack:before{content:""}.fa-ticket-alt:before{content:""}.fa-tiktok:before{content:""}.fa-times:before{content:""}.fa-times-circle:before{content:""}.fa-tint:before{content:""}.fa-tint-slash:before{content:""}.fa-tired:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-toilet:before{content:""}.fa-toilet-paper:before{content:""}.fa-toilet-paper-slash:before{content:""}.fa-toolbox:before{content:""}.fa-tools:before{content:""}.fa-tooth:before{content:""}.fa-torah:before{content:""}.fa-torii-gate:before{content:""}.fa-tractor:before{content:""}.fa-trade-federation:before{content:""}.fa-trademark:before{content:""}.fa-traffic-light:before{content:""}.fa-trailer:before{content:""}.fa-train:before{content:""}.fa-tram:before{content:""}.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-trash:before{content:""}.fa-trash-alt:before{content:""}.fa-trash-restore:before{content:""}.fa-trash-restore-alt:before{content:""}.fa-tree:before{content:""}.fa-trello:before{content:""}.fa-tripadvisor:before{content:""}.fa-trophy:before{content:""}.fa-truck:before{content:""}.fa-truck-loading:before{content:""}.fa-truck-monster:before{content:""}.fa-truck-moving:before{content:""}.fa-truck-pickup:before{content:""}.fa-tshirt:before{content:""}.fa-tty:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-tv:before{content:""}.fa-twitch:before{content:""}.fa-twitter:before{content:""}.fa-twitter-square:before{content:""}.fa-typo3:before{content:""}.fa-uber:before{content:""}.fa-ubuntu:before{content:""}.fa-uikit:before{content:""}.fa-umbraco:before{content:""}.fa-umbrella:before{content:""}.fa-umbrella-beach:before{content:""}.fa-underline:before{content:""}.fa-undo:before{content:""}.fa-undo-alt:before{content:""}.fa-uniregistry:before{content:""}.fa-unity:before{content:""}.fa-universal-access:before{content:""}.fa-university:before{content:""}.fa-unlink:before{content:""}.fa-unlock:before{content:""}.fa-unlock-alt:before{content:""}.fa-unsplash:before{content:""}.fa-untappd:before{content:""}.fa-upload:before{content:""}.fa-ups:before{content:""}.fa-usb:before{content:""}.fa-user:before{content:""}.fa-user-alt:before{content:""}.fa-user-alt-slash:before{content:""}.fa-user-astronaut:before{content:""}.fa-user-check:before{content:""}.fa-user-circle:before{content:""}.fa-user-clock:before{content:""}.fa-user-cog:before{content:""}.fa-user-edit:before{content:""}.fa-user-friends:before{content:""}.fa-user-graduate:before{content:""}.fa-user-injured:before{content:""}.fa-user-lock:before{content:""}.fa-user-md:before{content:""}.fa-user-minus:before{content:""}.fa-user-ninja:before{content:""}.fa-user-nurse:before{content:""}.fa-user-plus:before{content:""}.fa-user-secret:before{content:""}.fa-user-shield:before{content:""}.fa-user-slash:before{content:""}.fa-user-tag:before{content:""}.fa-user-tie:before{content:""}.fa-user-times:before{content:""}.fa-users:before{content:""}.fa-users-cog:before{content:""}.fa-users-slash:before{content:""}.fa-usps:before{content:""}.fa-ussunnah:before{content:""}.fa-utensil-spoon:before{content:""}.fa-utensils:before{content:""}.fa-vaadin:before{content:""}.fa-vector-square:before{content:""}.fa-venus:before{content:""}.fa-venus-double:before{content:""}.fa-venus-mars:before{content:""}.fa-viacoin:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-vial:before{content:""}.fa-vials:before{content:""}.fa-viber:before{content:""}.fa-video:before{content:""}.fa-video-slash:before{content:""}.fa-vihara:before{content:""}.fa-vimeo:before{content:""}.fa-vimeo-square:before{content:""}.fa-vimeo-v:before{content:""}.fa-vine:before{content:""}.fa-virus:before{content:""}.fa-virus-slash:before{content:""}.fa-viruses:before{content:""}.fa-vk:before{content:""}.fa-vnv:before{content:""}.fa-voicemail:before{content:""}.fa-volleyball-ball:before{content:""}.fa-volume-down:before{content:""}.fa-volume-mute:before{content:""}.fa-volume-off:before{content:""}.fa-volume-up:before{content:""}.fa-vote-yea:before{content:""}.fa-vr-cardboard:before{content:""}.fa-vuejs:before{content:""}.fa-walking:before{content:""}.fa-wallet:before{content:""}.fa-warehouse:before{content:""}.fa-water:before{content:""}.fa-wave-square:before{content:""}.fa-waze:before{content:""}.fa-weebly:before{content:""}.fa-weibo:before{content:""}.fa-weight:before{content:""}.fa-weight-hanging:before{content:""}.fa-weixin:before{content:""}.fa-whatsapp:before{content:""}.fa-whatsapp-square:before{content:""}.fa-wheelchair:before{content:""}.fa-whmcs:before{content:""}.fa-wifi:before{content:""}.fa-wikipedia-w:before{content:""}.fa-wind:before{content:""}.fa-window-close:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-windows:before{content:""}.fa-wine-bottle:before{content:""}.fa-wine-glass:before{content:""}.fa-wine-glass-alt:before{content:""}.fa-wix:before{content:""}.fa-wizards-of-the-coast:before{content:""}.fa-wolf-pack-battalion:before{content:""}.fa-won-sign:before{content:""}.fa-wordpress:before{content:""}.fa-wordpress-simple:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpexplorer:before{content:""}.fa-wpforms:before{content:""}.fa-wpressr:before{content:""}.fa-wrench:before{content:""}.fa-x-ray:before{content:""}.fa-xbox:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-y-combinator:before{content:""}.fa-yahoo:before{content:""}.fa-yammer:before{content:""}.fa-yandex:before{content:""}.fa-yandex-international:before{content:""}.fa-yarn:before{content:""}.fa-yelp:before{content:""}.fa-yen-sign:before{content:""}.fa-yin-yang:before{content:""}.fa-yoast:before{content:""}.fa-youtube:before{content:""}.fa-youtube-square:before{content:""}.fa-zhihu:before{content:""}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.converse-website converse-icon:before,.conversejs converse-icon:before{content:none!important}.converse-website .far:not(converse-icon),.conversejs .far:not(converse-icon){font-family:ConverseFontAwesomeRegular!important;font-weight:400}.converse-website .fa:not(converse-icon),.converse-website .fas:not(converse-icon),.conversejs .fa:not(converse-icon),.conversejs .fas:not(converse-icon){font-family:ConverseFontAwesomeSolid!important;font-weight:900}.converse-website .fab:not(converse-icon),.conversejs .fab:not(converse-icon){font-family:ConverseFontAwesomeBrands}.converse-website .fa:not(converse-icon),.converse-website .fab:not(converse-icon),.converse-website .far:not(converse-icon),.converse-website .fas:not(converse-icon),.conversejs .fa:not(converse-icon),.conversejs .fab:not(converse-icon),.conversejs .far:not(converse-icon),.conversejs .fas:not(converse-icon){display:inline-block;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.converse-website .fa-info-circle,.conversejs .fa-info-circle{height:1em}.conversejs :root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.conversejs *,.conversejs ::after,.conversejs ::before{box-sizing:border-box}.conversejs html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}.conversejs article,.conversejs aside,.conversejs figcaption,.conversejs figure,.conversejs footer,.conversejs header,.conversejs hgroup,.conversejs main,.conversejs nav,.conversejs section{display:block}.conversejs body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}.conversejs [tabindex="-1"]:focus:not(:focus-visible){outline:0!important}.conversejs hr{box-sizing:content-box;height:0;overflow:visible}.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6{margin-top:0;margin-bottom:.5rem}.conversejs p{margin-top:0;margin-bottom:1rem}.conversejs abbr[data-original-title],.conversejs abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}.conversejs address{margin-bottom:1rem;font-style:normal;line-height:inherit}.conversejs dl,.conversejs ol,.conversejs ul{margin-top:0;margin-bottom:1rem}.conversejs ol ol,.conversejs ol ul,.conversejs ul ol,.conversejs ul ul{margin-bottom:0}.conversejs dt{font-weight:700}.conversejs dd{margin-bottom:.5rem;margin-left:0}.conversejs blockquote{margin:0 0 1rem}.conversejs b,.conversejs strong{font-weight:bolder}.conversejs small{font-size:80%}.conversejs sub,.conversejs sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.conversejs sub{bottom:-.25em}.conversejs sup{top:-.5em}.conversejs a{color:#007bff;text-decoration:none;background-color:transparent}.conversejs a:hover{color:#0056b3;text-decoration:underline}.conversejs a:not([href]):not([class]){color:inherit;text-decoration:none}.conversejs a:not([href]):not([class]):hover{color:inherit;text-decoration:none}.conversejs code,.conversejs kbd,.conversejs pre,.conversejs samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}.conversejs pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}.conversejs figure{margin:0 0 1rem}.conversejs img{vertical-align:middle;border-style:none}.conversejs svg{overflow:hidden;vertical-align:middle}.conversejs table{border-collapse:collapse}.conversejs caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}.conversejs th{text-align:inherit;text-align:-webkit-match-parent}.conversejs label{display:inline-block;margin-bottom:.5rem}.conversejs button{border-radius:0}.conversejs button:focus:not(:focus-visible){outline:0}.conversejs button,.conversejs input,.conversejs optgroup,.conversejs select,.conversejs textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}.conversejs button,.conversejs input{overflow:visible}.conversejs button,.conversejs select{text-transform:none}.conversejs [role=button]{cursor:pointer}.conversejs select{word-wrap:normal}.conversejs [type=button],.conversejs [type=reset],.conversejs [type=submit],.conversejs button{-webkit-appearance:button}.conversejs [type=button]:not(:disabled),.conversejs [type=reset]:not(:disabled),.conversejs [type=submit]:not(:disabled),.conversejs button:not(:disabled){cursor:pointer}.conversejs [type=button]::-moz-focus-inner,.conversejs [type=reset]::-moz-focus-inner,.conversejs [type=submit]::-moz-focus-inner,.conversejs button::-moz-focus-inner{padding:0;border-style:none}.conversejs input[type=checkbox],.conversejs input[type=radio]{box-sizing:border-box;padding:0}.conversejs textarea{overflow:auto;resize:vertical}.conversejs fieldset{min-width:0;padding:0;margin:0;border:0}.conversejs legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}.conversejs progress{vertical-align:baseline}.conversejs [type=number]::-webkit-inner-spin-button,.conversejs [type=number]::-webkit-outer-spin-button{height:auto}.conversejs [type=search]{outline-offset:-2px;-webkit-appearance:none}.conversejs [type=search]::-webkit-search-decoration{-webkit-appearance:none}.conversejs ::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}.conversejs output{display:inline-block}.conversejs summary{display:list-item;cursor:pointer}.conversejs template{display:none}.conversejs [hidden]{display:none!important}.conversejs .h1,.conversejs .h2,.conversejs .h3,.conversejs .h4,.conversejs .h5,.conversejs .h6,.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.conversejs .h1,.conversejs h1{font-size:2.5rem}.conversejs .h2,.conversejs h2{font-size:2rem}.conversejs .h3,.conversejs h3{font-size:1.75rem}.conversejs .h4,.conversejs h4{font-size:1.5rem}.conversejs .h5,.conversejs h5{font-size:1.25rem}.conversejs .h6,.conversejs h6{font-size:1rem}.conversejs .lead{font-size:1.25rem;font-weight:300}.conversejs .display-1{font-size:6rem;font-weight:300;line-height:1.2}.conversejs .display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.conversejs .display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.conversejs .display-4{font-size:3.5rem;font-weight:300;line-height:1.2}.conversejs hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.conversejs .small,.conversejs small{font-size:80%;font-weight:400}.conversejs .mark,.conversejs mark{padding:.2em;background-color:#fcf8e3}.conversejs .list-unstyled{padding-left:0;list-style:none}.conversejs .list-inline{padding-left:0;list-style:none}.conversejs .list-inline-item{display:inline-block}.conversejs .list-inline-item:not(:last-child){margin-right:.5rem}.conversejs .initialism{font-size:90%;text-transform:uppercase}.conversejs .blockquote{margin-bottom:1rem;font-size:1.25rem}.conversejs .blockquote-footer{display:block;font-size:80%;color:#6c757d}.conversejs .blockquote-footer::before{content:"— "}.conversejs .img-fluid{max-width:100%;height:auto}.conversejs .img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.conversejs .figure{display:inline-block}.conversejs .figure-img{margin-bottom:.5rem;line-height:1}.conversejs .figure-caption{font-size:90%;color:#6c757d}.conversejs .container,.conversejs .container-fluid,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm,.conversejs .container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media(min-width:576px){.conversejs .container,.conversejs .container-sm{max-width:540px}}@media(min-width:768px){.conversejs .container,.conversejs .container-md,.conversejs .container-sm{max-width:720px}}@media(min-width:992px){.conversejs .container,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm{max-width:960px}}@media(min-width:1200px){.conversejs .container,.conversejs .container-lg,.conversejs .container-md,.conversejs .container-sm,.conversejs .container-xl{max-width:1140px}}.conversejs .row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.conversejs .no-gutters{margin-right:0;margin-left:0}.conversejs .no-gutters>.col,.conversejs .no-gutters>[class*=col-]{padding-right:0;padding-left:0}.conversejs .col,.conversejs .col-1,.conversejs .col-10,.conversejs .col-11,.conversejs .col-12,.conversejs .col-2,.conversejs .col-3,.conversejs .col-4,.conversejs .col-5,.conversejs .col-6,.conversejs .col-7,.conversejs .col-8,.conversejs .col-9,.conversejs .col-auto,.conversejs .col-lg,.conversejs .col-lg-1,.conversejs .col-lg-10,.conversejs .col-lg-11,.conversejs .col-lg-12,.conversejs .col-lg-2,.conversejs .col-lg-3,.conversejs .col-lg-4,.conversejs .col-lg-5,.conversejs .col-lg-6,.conversejs .col-lg-7,.conversejs .col-lg-8,.conversejs .col-lg-9,.conversejs .col-lg-auto,.conversejs .col-md,.conversejs .col-md-1,.conversejs .col-md-10,.conversejs .col-md-11,.conversejs .col-md-12,.conversejs .col-md-2,.conversejs .col-md-3,.conversejs .col-md-4,.conversejs .col-md-5,.conversejs .col-md-6,.conversejs .col-md-7,.conversejs .col-md-8,.conversejs .col-md-9,.conversejs .col-md-auto,.conversejs .col-sm,.conversejs .col-sm-1,.conversejs .col-sm-10,.conversejs .col-sm-11,.conversejs .col-sm-12,.conversejs .col-sm-2,.conversejs .col-sm-3,.conversejs .col-sm-4,.conversejs .col-sm-5,.conversejs .col-sm-6,.conversejs .col-sm-7,.conversejs .col-sm-8,.conversejs .col-sm-9,.conversejs .col-sm-auto,.conversejs .col-xl,.conversejs .col-xl-1,.conversejs .col-xl-10,.conversejs .col-xl-11,.conversejs .col-xl-12,.conversejs .col-xl-2,.conversejs .col-xl-3,.conversejs .col-xl-4,.conversejs .col-xl-5,.conversejs .col-xl-6,.conversejs .col-xl-7,.conversejs .col-xl-8,.conversejs .col-xl-9,.conversejs .col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.conversejs .col{flex-basis:0;flex-grow:1;max-width:100%}.conversejs .row-cols-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-md-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-md-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-md-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-md-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.conversejs .row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.conversejs .row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.conversejs .row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.conversejs .row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.conversejs .row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.conversejs .col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.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 .fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.conversejs .fade{transition:none}}.conversejs .fade:not(.show){opacity:0}.conversejs .collapse:not(.show){display:none}.conversejs .collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.conversejs .collapsing{transition:none}}.conversejs .nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.conversejs .nav-link{display:block;padding:.5rem 1rem}.conversejs .nav-link:focus,.conversejs .nav-link:hover{text-decoration:none}.conversejs .nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.conversejs .nav-tabs{border-bottom:1px solid #dee2e6}.conversejs .nav-tabs .nav-link{margin-bottom:-1px;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.conversejs .nav-tabs .nav-link:focus,.conversejs .nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.conversejs .nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.conversejs .nav-tabs .nav-item.show .nav-link,.conversejs .nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.conversejs .nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.conversejs .nav-pills .nav-link{border-radius:.25rem}.conversejs .nav-pills .nav-link.active,.conversejs .nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.conversejs .nav-fill .nav-item,.conversejs .nav-fill>.nav-link{flex:1 1 auto;text-align:center}.conversejs .nav-justified .nav-item,.conversejs .nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.conversejs .tab-content>.tab-pane{display:none}.conversejs .tab-content>.active{display:block}.conversejs .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.conversejs .alert-heading{color:inherit}.conversejs .alert-link{font-weight:700}.conversejs .alert-dismissible{padding-right:4rem}.conversejs .alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.conversejs .alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.conversejs .alert-primary hr{border-top-color:#9fcdff}.conversejs .alert-primary .alert-link{color:#002752}.conversejs .alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.conversejs .alert-secondary hr{border-top-color:#c8cbcf}.conversejs .alert-secondary .alert-link{color:#202326}.conversejs .alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.conversejs .alert-success hr{border-top-color:#b1dfbb}.conversejs .alert-success .alert-link{color:#0b2e13}.conversejs .alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.conversejs .alert-info hr{border-top-color:#abdde5}.conversejs .alert-info .alert-link{color:#062c33}.conversejs .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.conversejs .alert-warning hr{border-top-color:#ffe8a1}.conversejs .alert-warning .alert-link{color:#533f03}.conversejs .alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.conversejs .alert-danger hr{border-top-color:#f1b0b7}.conversejs .alert-danger .alert-link{color:#491217}.conversejs .alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.conversejs .alert-light hr{border-top-color:#ececf6}.conversejs .alert-light .alert-link{color:#686868}.conversejs .alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.conversejs .alert-dark hr{border-top-color:#b9bbbe}.conversejs .alert-dark .alert-link{color:#040505}.conversejs .media{display:flex;align-items:flex-start}.conversejs .media-body{flex:1}.conversejs .close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.conversejs .close:hover{color:#000;text-decoration:none}.conversejs .close:not(:disabled):not(.disabled):focus,.conversejs .close:not(:disabled):not(.disabled):hover{opacity:.75}.conversejs button.close{padding:0;background-color:transparent;border:0}.conversejs a.close.disabled{pointer-events:none}.conversejs .popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.conversejs .popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.conversejs .popover .arrow::after,.conversejs .popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.conversejs .bs-popover-auto[x-placement^=top],.conversejs .bs-popover-top{margin-bottom:.5rem}.conversejs .bs-popover-auto[x-placement^=top]>.arrow,.conversejs .bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.conversejs .bs-popover-auto[x-placement^=top]>.arrow::before,.conversejs .bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=top]>.arrow::after,.conversejs .bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.conversejs .bs-popover-auto[x-placement^=right],.conversejs .bs-popover-right{margin-left:.5rem}.conversejs .bs-popover-auto[x-placement^=right]>.arrow,.conversejs .bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.conversejs .bs-popover-auto[x-placement^=right]>.arrow::before,.conversejs .bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=right]>.arrow::after,.conversejs .bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.conversejs .bs-popover-auto[x-placement^=bottom],.conversejs .bs-popover-bottom{margin-top:.5rem}.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow,.conversejs .bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::before,.conversejs .bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=bottom]>.arrow::after,.conversejs .bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.conversejs .bs-popover-auto[x-placement^=bottom] .popover-header::before,.conversejs .bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.conversejs .bs-popover-auto[x-placement^=left],.conversejs .bs-popover-left{margin-right:.5rem}.conversejs .bs-popover-auto[x-placement^=left]>.arrow,.conversejs .bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.conversejs .bs-popover-auto[x-placement^=left]>.arrow::before,.conversejs .bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.conversejs .bs-popover-auto[x-placement^=left]>.arrow::after,.conversejs .bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.conversejs .popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.conversejs .popover-header:empty{display:none}.conversejs .popover-body{padding:.5rem .75rem;color:#212529}.conversejs .align-baseline{vertical-align:baseline!important}.conversejs .align-top{vertical-align:top!important}.conversejs .align-middle{vertical-align:middle!important}.conversejs .align-bottom{vertical-align:bottom!important}.conversejs .align-text-bottom{vertical-align:text-bottom!important}.conversejs .align-text-top{vertical-align:text-top!important}.conversejs .bg-primary{background-color:#007bff!important}.conversejs a.bg-primary:focus,.conversejs a.bg-primary:hover,.conversejs button.bg-primary:focus,.conversejs button.bg-primary:hover{background-color:#0062cc!important}.conversejs .bg-secondary{background-color:#6c757d!important}.conversejs a.bg-secondary:focus,.conversejs a.bg-secondary:hover,.conversejs button.bg-secondary:focus,.conversejs button.bg-secondary:hover{background-color:#545b62!important}.conversejs .bg-success{background-color:#28a745!important}.conversejs a.bg-success:focus,.conversejs a.bg-success:hover,.conversejs button.bg-success:focus,.conversejs button.bg-success:hover{background-color:#1e7e34!important}.conversejs .bg-info{background-color:#17a2b8!important}.conversejs a.bg-info:focus,.conversejs a.bg-info:hover,.conversejs button.bg-info:focus,.conversejs button.bg-info:hover{background-color:#117a8b!important}.conversejs .bg-warning{background-color:#ffc107!important}.conversejs a.bg-warning:focus,.conversejs a.bg-warning:hover,.conversejs button.bg-warning:focus,.conversejs button.bg-warning:hover{background-color:#d39e00!important}.conversejs .bg-danger{background-color:#dc3545!important}.conversejs a.bg-danger:focus,.conversejs a.bg-danger:hover,.conversejs button.bg-danger:focus,.conversejs button.bg-danger:hover{background-color:#bd2130!important}.conversejs .bg-light{background-color:#f8f9fa!important}.conversejs a.bg-light:focus,.conversejs a.bg-light:hover,.conversejs button.bg-light:focus,.conversejs button.bg-light:hover{background-color:#dae0e5!important}.conversejs .bg-dark{background-color:#343a40!important}.conversejs a.bg-dark:focus,.conversejs a.bg-dark:hover,.conversejs button.bg-dark:focus,.conversejs button.bg-dark:hover{background-color:#1d2124!important}.conversejs .bg-white{background-color:#fff!important}.conversejs .bg-transparent{background-color:transparent!important}.conversejs .border{border:1px solid #dee2e6!important}.conversejs .border-top{border-top:1px solid #dee2e6!important}.conversejs .border-right{border-right:1px solid #dee2e6!important}.conversejs .border-bottom{border-bottom:1px solid #dee2e6!important}.conversejs .border-left{border-left:1px solid #dee2e6!important}.conversejs .border-0{border:0!important}.conversejs .border-top-0{border-top:0!important}.conversejs .border-right-0{border-right:0!important}.conversejs .border-bottom-0{border-bottom:0!important}.conversejs .border-left-0{border-left:0!important}.conversejs .border-primary{border-color:#007bff!important}.conversejs .border-secondary{border-color:#6c757d!important}.conversejs .border-success{border-color:#28a745!important}.conversejs .border-info{border-color:#17a2b8!important}.conversejs .border-warning{border-color:#ffc107!important}.conversejs .border-danger{border-color:#dc3545!important}.conversejs .border-light{border-color:#f8f9fa!important}.conversejs .border-dark{border-color:#343a40!important}.conversejs .border-white{border-color:#fff!important}.conversejs .rounded-sm{border-radius:.2rem!important}.conversejs .rounded{border-radius:.25rem!important}.conversejs .rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.conversejs .rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.conversejs .rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.conversejs .rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.conversejs .rounded-lg{border-radius:.3rem!important}.conversejs .rounded-circle{border-radius:50%!important}.conversejs .rounded-pill{border-radius:50rem!important}.conversejs .rounded-0{border-radius:0!important}.conversejs .clearfix::after{display:block;clear:both;content:""}.conversejs .d-none{display:none!important}.conversejs .d-inline{display:inline!important}.conversejs .d-inline-block{display:inline-block!important}.conversejs .d-block{display:block!important}.conversejs .d-table{display:table!important}.conversejs .d-table-row{display:table-row!important}.conversejs .d-table-cell{display:table-cell!important}.conversejs .d-flex{display:flex!important}.conversejs .d-inline-flex{display:inline-flex!important}@media(min-width:576px){.conversejs .d-sm-none{display:none!important}.conversejs .d-sm-inline{display:inline!important}.conversejs .d-sm-inline-block{display:inline-block!important}.conversejs .d-sm-block{display:block!important}.conversejs .d-sm-table{display:table!important}.conversejs .d-sm-table-row{display:table-row!important}.conversejs .d-sm-table-cell{display:table-cell!important}.conversejs .d-sm-flex{display:flex!important}.conversejs .d-sm-inline-flex{display:inline-flex!important}}@media(min-width:768px){.conversejs .d-md-none{display:none!important}.conversejs .d-md-inline{display:inline!important}.conversejs .d-md-inline-block{display:inline-block!important}.conversejs .d-md-block{display:block!important}.conversejs .d-md-table{display:table!important}.conversejs .d-md-table-row{display:table-row!important}.conversejs .d-md-table-cell{display:table-cell!important}.conversejs .d-md-flex{display:flex!important}.conversejs .d-md-inline-flex{display:inline-flex!important}}@media(min-width:992px){.conversejs .d-lg-none{display:none!important}.conversejs .d-lg-inline{display:inline!important}.conversejs .d-lg-inline-block{display:inline-block!important}.conversejs .d-lg-block{display:block!important}.conversejs .d-lg-table{display:table!important}.conversejs .d-lg-table-row{display:table-row!important}.conversejs .d-lg-table-cell{display:table-cell!important}.conversejs .d-lg-flex{display:flex!important}.conversejs .d-lg-inline-flex{display:inline-flex!important}}@media(min-width:1200px){.conversejs .d-xl-none{display:none!important}.conversejs .d-xl-inline{display:inline!important}.conversejs .d-xl-inline-block{display:inline-block!important}.conversejs .d-xl-block{display:block!important}.conversejs .d-xl-table{display:table!important}.conversejs .d-xl-table-row{display:table-row!important}.conversejs .d-xl-table-cell{display:table-cell!important}.conversejs .d-xl-flex{display:flex!important}.conversejs .d-xl-inline-flex{display:inline-flex!important}}@media print{.conversejs .d-print-none{display:none!important}.conversejs .d-print-inline{display:inline!important}.conversejs .d-print-inline-block{display:inline-block!important}.conversejs .d-print-block{display:block!important}.conversejs .d-print-table{display:table!important}.conversejs .d-print-table-row{display:table-row!important}.conversejs .d-print-table-cell{display:table-cell!important}.conversejs .d-print-flex{display:flex!important}.conversejs .d-print-inline-flex{display:inline-flex!important}}.conversejs .embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.conversejs .embed-responsive::before{display:block;content:""}.conversejs .embed-responsive .embed-responsive-item,.conversejs .embed-responsive embed,.conversejs .embed-responsive iframe,.conversejs .embed-responsive object,.conversejs .embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.conversejs .embed-responsive-21by9::before{padding-top:42.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 .flex-fill{flex:1 1 auto!important}.conversejs .flex-grow-0{flex-grow:0!important}.conversejs .flex-grow-1{flex-grow:1!important}.conversejs .flex-shrink-0{flex-shrink:0!important}.conversejs .flex-shrink-1{flex-shrink:1!important}.conversejs .justify-content-start{justify-content:flex-start!important}.conversejs .justify-content-end{justify-content:flex-end!important}.conversejs .justify-content-center{justify-content:center!important}.conversejs .justify-content-between{justify-content:space-between!important}.conversejs .justify-content-around{justify-content:space-around!important}.conversejs .align-items-start{align-items:flex-start!important}.conversejs .align-items-end{align-items:flex-end!important}.conversejs .align-items-center{align-items:center!important}.conversejs .align-items-baseline{align-items:baseline!important}.conversejs .align-items-stretch{align-items:stretch!important}.conversejs .align-content-start{align-content:flex-start!important}.conversejs .align-content-end{align-content:flex-end!important}.conversejs .align-content-center{align-content:center!important}.conversejs .align-content-between{align-content:space-between!important}.conversejs .align-content-around{align-content:space-around!important}.conversejs .align-content-stretch{align-content:stretch!important}.conversejs .align-self-auto{align-self:auto!important}.conversejs .align-self-start{align-self:flex-start!important}.conversejs .align-self-end{align-self:flex-end!important}.conversejs .align-self-center{align-self:center!important}.conversejs .align-self-baseline{align-self:baseline!important}.conversejs .align-self-stretch{align-self:stretch!important}@media(min-width:576px){.conversejs .flex-sm-row{flex-direction:row!important}.conversejs .flex-sm-column{flex-direction:column!important}.conversejs .flex-sm-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-sm-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-sm-wrap{flex-wrap:wrap!important}.conversejs .flex-sm-nowrap{flex-wrap:nowrap!important}.conversejs .flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-sm-fill{flex:1 1 auto!important}.conversejs .flex-sm-grow-0{flex-grow:0!important}.conversejs .flex-sm-grow-1{flex-grow:1!important}.conversejs .flex-sm-shrink-0{flex-shrink:0!important}.conversejs .flex-sm-shrink-1{flex-shrink:1!important}.conversejs .justify-content-sm-start{justify-content:flex-start!important}.conversejs .justify-content-sm-end{justify-content:flex-end!important}.conversejs .justify-content-sm-center{justify-content:center!important}.conversejs .justify-content-sm-between{justify-content:space-between!important}.conversejs .justify-content-sm-around{justify-content:space-around!important}.conversejs .align-items-sm-start{align-items:flex-start!important}.conversejs .align-items-sm-end{align-items:flex-end!important}.conversejs .align-items-sm-center{align-items:center!important}.conversejs .align-items-sm-baseline{align-items:baseline!important}.conversejs .align-items-sm-stretch{align-items:stretch!important}.conversejs .align-content-sm-start{align-content:flex-start!important}.conversejs .align-content-sm-end{align-content:flex-end!important}.conversejs .align-content-sm-center{align-content:center!important}.conversejs .align-content-sm-between{align-content:space-between!important}.conversejs .align-content-sm-around{align-content:space-around!important}.conversejs .align-content-sm-stretch{align-content:stretch!important}.conversejs .align-self-sm-auto{align-self:auto!important}.conversejs .align-self-sm-start{align-self:flex-start!important}.conversejs .align-self-sm-end{align-self:flex-end!important}.conversejs .align-self-sm-center{align-self:center!important}.conversejs .align-self-sm-baseline{align-self:baseline!important}.conversejs .align-self-sm-stretch{align-self:stretch!important}}@media(min-width:768px){.conversejs .flex-md-row{flex-direction:row!important}.conversejs .flex-md-column{flex-direction:column!important}.conversejs .flex-md-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-md-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-md-wrap{flex-wrap:wrap!important}.conversejs .flex-md-nowrap{flex-wrap:nowrap!important}.conversejs .flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-md-fill{flex:1 1 auto!important}.conversejs .flex-md-grow-0{flex-grow:0!important}.conversejs .flex-md-grow-1{flex-grow:1!important}.conversejs .flex-md-shrink-0{flex-shrink:0!important}.conversejs .flex-md-shrink-1{flex-shrink:1!important}.conversejs .justify-content-md-start{justify-content:flex-start!important}.conversejs .justify-content-md-end{justify-content:flex-end!important}.conversejs .justify-content-md-center{justify-content:center!important}.conversejs .justify-content-md-between{justify-content:space-between!important}.conversejs .justify-content-md-around{justify-content:space-around!important}.conversejs .align-items-md-start{align-items:flex-start!important}.conversejs .align-items-md-end{align-items:flex-end!important}.conversejs .align-items-md-center{align-items:center!important}.conversejs .align-items-md-baseline{align-items:baseline!important}.conversejs .align-items-md-stretch{align-items:stretch!important}.conversejs .align-content-md-start{align-content:flex-start!important}.conversejs .align-content-md-end{align-content:flex-end!important}.conversejs .align-content-md-center{align-content:center!important}.conversejs .align-content-md-between{align-content:space-between!important}.conversejs .align-content-md-around{align-content:space-around!important}.conversejs .align-content-md-stretch{align-content:stretch!important}.conversejs .align-self-md-auto{align-self:auto!important}.conversejs .align-self-md-start{align-self:flex-start!important}.conversejs .align-self-md-end{align-self:flex-end!important}.conversejs .align-self-md-center{align-self:center!important}.conversejs .align-self-md-baseline{align-self:baseline!important}.conversejs .align-self-md-stretch{align-self:stretch!important}}@media(min-width:992px){.conversejs .flex-lg-row{flex-direction:row!important}.conversejs .flex-lg-column{flex-direction:column!important}.conversejs .flex-lg-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-lg-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-lg-wrap{flex-wrap:wrap!important}.conversejs .flex-lg-nowrap{flex-wrap:nowrap!important}.conversejs .flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-lg-fill{flex:1 1 auto!important}.conversejs .flex-lg-grow-0{flex-grow:0!important}.conversejs .flex-lg-grow-1{flex-grow:1!important}.conversejs .flex-lg-shrink-0{flex-shrink:0!important}.conversejs .flex-lg-shrink-1{flex-shrink:1!important}.conversejs .justify-content-lg-start{justify-content:flex-start!important}.conversejs .justify-content-lg-end{justify-content:flex-end!important}.conversejs .justify-content-lg-center{justify-content:center!important}.conversejs .justify-content-lg-between{justify-content:space-between!important}.conversejs .justify-content-lg-around{justify-content:space-around!important}.conversejs .align-items-lg-start{align-items:flex-start!important}.conversejs .align-items-lg-end{align-items:flex-end!important}.conversejs .align-items-lg-center{align-items:center!important}.conversejs .align-items-lg-baseline{align-items:baseline!important}.conversejs .align-items-lg-stretch{align-items:stretch!important}.conversejs .align-content-lg-start{align-content:flex-start!important}.conversejs .align-content-lg-end{align-content:flex-end!important}.conversejs .align-content-lg-center{align-content:center!important}.conversejs .align-content-lg-between{align-content:space-between!important}.conversejs .align-content-lg-around{align-content:space-around!important}.conversejs .align-content-lg-stretch{align-content:stretch!important}.conversejs .align-self-lg-auto{align-self:auto!important}.conversejs .align-self-lg-start{align-self:flex-start!important}.conversejs .align-self-lg-end{align-self:flex-end!important}.conversejs .align-self-lg-center{align-self:center!important}.conversejs .align-self-lg-baseline{align-self:baseline!important}.conversejs .align-self-lg-stretch{align-self:stretch!important}}@media(min-width:1200px){.conversejs .flex-xl-row{flex-direction:row!important}.conversejs .flex-xl-column{flex-direction:column!important}.conversejs .flex-xl-row-reverse{flex-direction:row-reverse!important}.conversejs .flex-xl-column-reverse{flex-direction:column-reverse!important}.conversejs .flex-xl-wrap{flex-wrap:wrap!important}.conversejs .flex-xl-nowrap{flex-wrap:nowrap!important}.conversejs .flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.conversejs .flex-xl-fill{flex:1 1 auto!important}.conversejs .flex-xl-grow-0{flex-grow:0!important}.conversejs .flex-xl-grow-1{flex-grow:1!important}.conversejs .flex-xl-shrink-0{flex-shrink:0!important}.conversejs .flex-xl-shrink-1{flex-shrink:1!important}.conversejs .justify-content-xl-start{justify-content:flex-start!important}.conversejs .justify-content-xl-end{justify-content:flex-end!important}.conversejs .justify-content-xl-center{justify-content:center!important}.conversejs .justify-content-xl-between{justify-content:space-between!important}.conversejs .justify-content-xl-around{justify-content:space-around!important}.conversejs .align-items-xl-start{align-items:flex-start!important}.conversejs .align-items-xl-end{align-items:flex-end!important}.conversejs .align-items-xl-center{align-items:center!important}.conversejs .align-items-xl-baseline{align-items:baseline!important}.conversejs .align-items-xl-stretch{align-items:stretch!important}.conversejs .align-content-xl-start{align-content:flex-start!important}.conversejs .align-content-xl-end{align-content:flex-end!important}.conversejs .align-content-xl-center{align-content:center!important}.conversejs .align-content-xl-between{align-content:space-between!important}.conversejs .align-content-xl-around{align-content:space-around!important}.conversejs .align-content-xl-stretch{align-content:stretch!important}.conversejs .align-self-xl-auto{align-self:auto!important}.conversejs .align-self-xl-start{align-self:flex-start!important}.conversejs .align-self-xl-end{align-self:flex-end!important}.conversejs .align-self-xl-center{align-self:center!important}.conversejs .align-self-xl-baseline{align-self:baseline!important}.conversejs .align-self-xl-stretch{align-self:stretch!important}}.conversejs .float-left{float:left!important}.conversejs .float-right{float:right!important}.conversejs .float-none{float:none!important}@media(min-width:576px){.conversejs .float-sm-left{float:left!important}.conversejs .float-sm-right{float:right!important}.conversejs .float-sm-none{float:none!important}}@media(min-width:768px){.conversejs .float-md-left{float:left!important}.conversejs .float-md-right{float:right!important}.conversejs .float-md-none{float:none!important}}@media(min-width:992px){.conversejs .float-lg-left{float:left!important}.conversejs .float-lg-right{float:right!important}.conversejs .float-lg-none{float:none!important}}@media(min-width:1200px){.conversejs .float-xl-left{float:left!important}.conversejs .float-xl-right{float:right!important}.conversejs .float-xl-none{float:none!important}}.conversejs .user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.conversejs .user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.conversejs .user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.conversejs .overflow-auto{overflow:auto!important}.conversejs .overflow-hidden{overflow:hidden!important}.conversejs .position-static{position:static!important}.conversejs .position-relative{position:relative!important}.conversejs .position-absolute{position:absolute!important}.conversejs .position-fixed{position:fixed!important}.conversejs .position-sticky{position: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;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.conversejs .sr-only-focusable:active,.conversejs .sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.conversejs .shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.conversejs .shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.conversejs .shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.conversejs .shadow-none{box-shadow:none!important}.conversejs .w-25{width:25%!important}.conversejs .w-50{width:50%!important}.conversejs .w-75{width:75%!important}.conversejs .w-100{width:100%!important}.conversejs .w-auto{width:auto!important}.conversejs .h-25{height:25%!important}.conversejs .h-50{height:50%!important}.conversejs .h-75{height:75%!important}.conversejs .h-100{height:100%!important}.conversejs .h-auto{height:auto!important}.conversejs .mw-100{max-width:100%!important}.conversejs .mh-100{max-height:100%!important}.conversejs .min-vw-100{min-width:100vw!important}.conversejs .min-vh-100{min-height:100vh!important}.conversejs .vw-100{width:100vw!important}.conversejs .vh-100{height:100vh!important}.conversejs .m-0{margin:0!important}.conversejs .mt-0,.conversejs .my-0{margin-top:0!important}.conversejs .mr-0,.conversejs .mx-0{margin-right:0!important}.conversejs .mb-0,.conversejs .my-0{margin-bottom:0!important}.conversejs .ml-0,.conversejs .mx-0{margin-left:0!important}.conversejs .m-1{margin:.25rem!important}.conversejs .mt-1,.conversejs .my-1{margin-top:.25rem!important}.conversejs .mr-1,.conversejs .mx-1{margin-right:.25rem!important}.conversejs .mb-1,.conversejs .my-1{margin-bottom:.25rem!important}.conversejs .ml-1,.conversejs .mx-1{margin-left:.25rem!important}.conversejs .m-2{margin:.5rem!important}.conversejs .mt-2,.conversejs .my-2{margin-top:.5rem!important}.conversejs .mr-2,.conversejs .mx-2{margin-right:.5rem!important}.conversejs .mb-2,.conversejs .my-2{margin-bottom:.5rem!important}.conversejs .ml-2,.conversejs .mx-2{margin-left:.5rem!important}.conversejs .m-3{margin:1rem!important}.conversejs .mt-3,.conversejs .my-3{margin-top:1rem!important}.conversejs .mr-3,.conversejs .mx-3{margin-right:1rem!important}.conversejs .mb-3,.conversejs .my-3{margin-bottom:1rem!important}.conversejs .ml-3,.conversejs .mx-3{margin-left:1rem!important}.conversejs .m-4{margin:1.5rem!important}.conversejs .mt-4,.conversejs .my-4{margin-top:1.5rem!important}.conversejs .mr-4,.conversejs .mx-4{margin-right:1.5rem!important}.conversejs .mb-4,.conversejs .my-4{margin-bottom:1.5rem!important}.conversejs .ml-4,.conversejs .mx-4{margin-left:1.5rem!important}.conversejs .m-5{margin:3rem!important}.conversejs .mt-5,.conversejs .my-5{margin-top:3rem!important}.conversejs .mr-5,.conversejs .mx-5{margin-right:3rem!important}.conversejs .mb-5,.conversejs .my-5{margin-bottom:3rem!important}.conversejs .ml-5,.conversejs .mx-5{margin-left:3rem!important}.conversejs .p-0{padding:0!important}.conversejs .pt-0,.conversejs .py-0{padding-top:0!important}.conversejs .pr-0,.conversejs .px-0{padding-right:0!important}.conversejs .pb-0,.conversejs .py-0{padding-bottom:0!important}.conversejs .pl-0,.conversejs .px-0{padding-left:0!important}.conversejs .p-1{padding:.25rem!important}.conversejs .pt-1,.conversejs .py-1{padding-top:.25rem!important}.conversejs .pr-1,.conversejs .px-1{padding-right:.25rem!important}.conversejs .pb-1,.conversejs .py-1{padding-bottom:.25rem!important}.conversejs .pl-1,.conversejs .px-1{padding-left:.25rem!important}.conversejs .p-2{padding:.5rem!important}.conversejs .pt-2,.conversejs .py-2{padding-top:.5rem!important}.conversejs .pr-2,.conversejs .px-2{padding-right:.5rem!important}.conversejs .pb-2,.conversejs .py-2{padding-bottom:.5rem!important}.conversejs .pl-2,.conversejs .px-2{padding-left:.5rem!important}.conversejs .p-3{padding:1rem!important}.conversejs .pt-3,.conversejs .py-3{padding-top:1rem!important}.conversejs .pr-3,.conversejs .px-3{padding-right:1rem!important}.conversejs .pb-3,.conversejs .py-3{padding-bottom:1rem!important}.conversejs .pl-3,.conversejs .px-3{padding-left:1rem!important}.conversejs .p-4{padding:1.5rem!important}.conversejs .pt-4,.conversejs .py-4{padding-top:1.5rem!important}.conversejs .pr-4,.conversejs .px-4{padding-right:1.5rem!important}.conversejs .pb-4,.conversejs .py-4{padding-bottom:1.5rem!important}.conversejs .pl-4,.conversejs .px-4{padding-left:1.5rem!important}.conversejs .p-5{padding:3rem!important}.conversejs .pt-5,.conversejs .py-5{padding-top:3rem!important}.conversejs .pr-5,.conversejs .px-5{padding-right:3rem!important}.conversejs .pb-5,.conversejs .py-5{padding-bottom:3rem!important}.conversejs .pl-5,.conversejs .px-5{padding-left:3rem!important}.conversejs .m-n1{margin:-.25rem!important}.conversejs .mt-n1,.conversejs .my-n1{margin-top:-.25rem!important}.conversejs .mr-n1,.conversejs .mx-n1{margin-right:-.25rem!important}.conversejs .mb-n1,.conversejs .my-n1{margin-bottom:-.25rem!important}.conversejs .ml-n1,.conversejs .mx-n1{margin-left:-.25rem!important}.conversejs .m-n2{margin:-.5rem!important}.conversejs .mt-n2,.conversejs .my-n2{margin-top:-.5rem!important}.conversejs .mr-n2,.conversejs .mx-n2{margin-right:-.5rem!important}.conversejs .mb-n2,.conversejs .my-n2{margin-bottom:-.5rem!important}.conversejs .ml-n2,.conversejs .mx-n2{margin-left:-.5rem!important}.conversejs .m-n3{margin:-1rem!important}.conversejs .mt-n3,.conversejs .my-n3{margin-top:-1rem!important}.conversejs .mr-n3,.conversejs .mx-n3{margin-right:-1rem!important}.conversejs .mb-n3,.conversejs .my-n3{margin-bottom:-1rem!important}.conversejs .ml-n3,.conversejs .mx-n3{margin-left:-1rem!important}.conversejs .m-n4{margin:-1.5rem!important}.conversejs .mt-n4,.conversejs .my-n4{margin-top:-1.5rem!important}.conversejs .mr-n4,.conversejs .mx-n4{margin-right:-1.5rem!important}.conversejs .mb-n4,.conversejs .my-n4{margin-bottom:-1.5rem!important}.conversejs .ml-n4,.conversejs .mx-n4{margin-left:-1.5rem!important}.conversejs .m-n5{margin:-3rem!important}.conversejs .mt-n5,.conversejs .my-n5{margin-top:-3rem!important}.conversejs .mr-n5,.conversejs .mx-n5{margin-right:-3rem!important}.conversejs .mb-n5,.conversejs .my-n5{margin-bottom:-3rem!important}.conversejs .ml-n5,.conversejs .mx-n5{margin-left:-3rem!important}.conversejs .m-auto{margin:auto!important}.conversejs .mt-auto,.conversejs .my-auto{margin-top:auto!important}.conversejs .mr-auto,.conversejs .mx-auto{margin-right:auto!important}.conversejs .mb-auto,.conversejs .my-auto{margin-bottom:auto!important}.conversejs .ml-auto,.conversejs .mx-auto{margin-left:auto!important}@media(min-width:576px){.conversejs .m-sm-0{margin:0!important}.conversejs .mt-sm-0,.conversejs .my-sm-0{margin-top:0!important}.conversejs .mr-sm-0,.conversejs .mx-sm-0{margin-right:0!important}.conversejs .mb-sm-0,.conversejs .my-sm-0{margin-bottom:0!important}.conversejs .ml-sm-0,.conversejs .mx-sm-0{margin-left:0!important}.conversejs .m-sm-1{margin:.25rem!important}.conversejs .mt-sm-1,.conversejs .my-sm-1{margin-top:.25rem!important}.conversejs .mr-sm-1,.conversejs .mx-sm-1{margin-right:.25rem!important}.conversejs .mb-sm-1,.conversejs .my-sm-1{margin-bottom:.25rem!important}.conversejs .ml-sm-1,.conversejs .mx-sm-1{margin-left:.25rem!important}.conversejs .m-sm-2{margin:.5rem!important}.conversejs .mt-sm-2,.conversejs .my-sm-2{margin-top:.5rem!important}.conversejs .mr-sm-2,.conversejs .mx-sm-2{margin-right:.5rem!important}.conversejs .mb-sm-2,.conversejs .my-sm-2{margin-bottom:.5rem!important}.conversejs .ml-sm-2,.conversejs .mx-sm-2{margin-left:.5rem!important}.conversejs .m-sm-3{margin:1rem!important}.conversejs .mt-sm-3,.conversejs .my-sm-3{margin-top:1rem!important}.conversejs .mr-sm-3,.conversejs .mx-sm-3{margin-right:1rem!important}.conversejs .mb-sm-3,.conversejs .my-sm-3{margin-bottom:1rem!important}.conversejs .ml-sm-3,.conversejs .mx-sm-3{margin-left:1rem!important}.conversejs .m-sm-4{margin:1.5rem!important}.conversejs .mt-sm-4,.conversejs .my-sm-4{margin-top:1.5rem!important}.conversejs .mr-sm-4,.conversejs .mx-sm-4{margin-right:1.5rem!important}.conversejs .mb-sm-4,.conversejs .my-sm-4{margin-bottom:1.5rem!important}.conversejs .ml-sm-4,.conversejs .mx-sm-4{margin-left:1.5rem!important}.conversejs .m-sm-5{margin:3rem!important}.conversejs .mt-sm-5,.conversejs .my-sm-5{margin-top:3rem!important}.conversejs .mr-sm-5,.conversejs .mx-sm-5{margin-right:3rem!important}.conversejs .mb-sm-5,.conversejs .my-sm-5{margin-bottom:3rem!important}.conversejs .ml-sm-5,.conversejs .mx-sm-5{margin-left:3rem!important}.conversejs .p-sm-0{padding:0!important}.conversejs .pt-sm-0,.conversejs .py-sm-0{padding-top:0!important}.conversejs .pr-sm-0,.conversejs .px-sm-0{padding-right:0!important}.conversejs .pb-sm-0,.conversejs .py-sm-0{padding-bottom:0!important}.conversejs .pl-sm-0,.conversejs .px-sm-0{padding-left:0!important}.conversejs .p-sm-1{padding:.25rem!important}.conversejs .pt-sm-1,.conversejs .py-sm-1{padding-top:.25rem!important}.conversejs .pr-sm-1,.conversejs .px-sm-1{padding-right:.25rem!important}.conversejs .pb-sm-1,.conversejs .py-sm-1{padding-bottom:.25rem!important}.conversejs .pl-sm-1,.conversejs .px-sm-1{padding-left:.25rem!important}.conversejs .p-sm-2{padding:.5rem!important}.conversejs .pt-sm-2,.conversejs .py-sm-2{padding-top:.5rem!important}.conversejs .pr-sm-2,.conversejs .px-sm-2{padding-right:.5rem!important}.conversejs .pb-sm-2,.conversejs .py-sm-2{padding-bottom:.5rem!important}.conversejs .pl-sm-2,.conversejs .px-sm-2{padding-left:.5rem!important}.conversejs .p-sm-3{padding:1rem!important}.conversejs .pt-sm-3,.conversejs .py-sm-3{padding-top:1rem!important}.conversejs .pr-sm-3,.conversejs .px-sm-3{padding-right:1rem!important}.conversejs .pb-sm-3,.conversejs .py-sm-3{padding-bottom:1rem!important}.conversejs .pl-sm-3,.conversejs .px-sm-3{padding-left:1rem!important}.conversejs .p-sm-4{padding:1.5rem!important}.conversejs .pt-sm-4,.conversejs .py-sm-4{padding-top:1.5rem!important}.conversejs .pr-sm-4,.conversejs .px-sm-4{padding-right:1.5rem!important}.conversejs .pb-sm-4,.conversejs .py-sm-4{padding-bottom:1.5rem!important}.conversejs .pl-sm-4,.conversejs .px-sm-4{padding-left:1.5rem!important}.conversejs .p-sm-5{padding:3rem!important}.conversejs .pt-sm-5,.conversejs .py-sm-5{padding-top:3rem!important}.conversejs .pr-sm-5,.conversejs .px-sm-5{padding-right:3rem!important}.conversejs .pb-sm-5,.conversejs .py-sm-5{padding-bottom:3rem!important}.conversejs .pl-sm-5,.conversejs .px-sm-5{padding-left:3rem!important}.conversejs .m-sm-n1{margin:-.25rem!important}.conversejs .mt-sm-n1,.conversejs .my-sm-n1{margin-top:-.25rem!important}.conversejs .mr-sm-n1,.conversejs .mx-sm-n1{margin-right:-.25rem!important}.conversejs .mb-sm-n1,.conversejs .my-sm-n1{margin-bottom:-.25rem!important}.conversejs .ml-sm-n1,.conversejs .mx-sm-n1{margin-left:-.25rem!important}.conversejs .m-sm-n2{margin:-.5rem!important}.conversejs .mt-sm-n2,.conversejs .my-sm-n2{margin-top:-.5rem!important}.conversejs .mr-sm-n2,.conversejs .mx-sm-n2{margin-right:-.5rem!important}.conversejs .mb-sm-n2,.conversejs .my-sm-n2{margin-bottom:-.5rem!important}.conversejs .ml-sm-n2,.conversejs .mx-sm-n2{margin-left:-.5rem!important}.conversejs .m-sm-n3{margin:-1rem!important}.conversejs .mt-sm-n3,.conversejs .my-sm-n3{margin-top:-1rem!important}.conversejs .mr-sm-n3,.conversejs .mx-sm-n3{margin-right:-1rem!important}.conversejs .mb-sm-n3,.conversejs .my-sm-n3{margin-bottom:-1rem!important}.conversejs .ml-sm-n3,.conversejs .mx-sm-n3{margin-left:-1rem!important}.conversejs .m-sm-n4{margin:-1.5rem!important}.conversejs .mt-sm-n4,.conversejs .my-sm-n4{margin-top:-1.5rem!important}.conversejs .mr-sm-n4,.conversejs .mx-sm-n4{margin-right:-1.5rem!important}.conversejs .mb-sm-n4,.conversejs .my-sm-n4{margin-bottom:-1.5rem!important}.conversejs .ml-sm-n4,.conversejs .mx-sm-n4{margin-left:-1.5rem!important}.conversejs .m-sm-n5{margin:-3rem!important}.conversejs .mt-sm-n5,.conversejs .my-sm-n5{margin-top:-3rem!important}.conversejs .mr-sm-n5,.conversejs .mx-sm-n5{margin-right:-3rem!important}.conversejs .mb-sm-n5,.conversejs .my-sm-n5{margin-bottom:-3rem!important}.conversejs .ml-sm-n5,.conversejs .mx-sm-n5{margin-left:-3rem!important}.conversejs .m-sm-auto{margin:auto!important}.conversejs .mt-sm-auto,.conversejs .my-sm-auto{margin-top:auto!important}.conversejs .mr-sm-auto,.conversejs .mx-sm-auto{margin-right:auto!important}.conversejs .mb-sm-auto,.conversejs .my-sm-auto{margin-bottom:auto!important}.conversejs .ml-sm-auto,.conversejs .mx-sm-auto{margin-left:auto!important}}@media(min-width:768px){.conversejs .m-md-0{margin:0!important}.conversejs .mt-md-0,.conversejs .my-md-0{margin-top:0!important}.conversejs .mr-md-0,.conversejs .mx-md-0{margin-right:0!important}.conversejs .mb-md-0,.conversejs .my-md-0{margin-bottom:0!important}.conversejs .ml-md-0,.conversejs .mx-md-0{margin-left:0!important}.conversejs .m-md-1{margin:.25rem!important}.conversejs .mt-md-1,.conversejs .my-md-1{margin-top:.25rem!important}.conversejs .mr-md-1,.conversejs .mx-md-1{margin-right:.25rem!important}.conversejs .mb-md-1,.conversejs .my-md-1{margin-bottom:.25rem!important}.conversejs .ml-md-1,.conversejs .mx-md-1{margin-left:.25rem!important}.conversejs .m-md-2{margin:.5rem!important}.conversejs .mt-md-2,.conversejs .my-md-2{margin-top:.5rem!important}.conversejs .mr-md-2,.conversejs .mx-md-2{margin-right:.5rem!important}.conversejs .mb-md-2,.conversejs .my-md-2{margin-bottom:.5rem!important}.conversejs .ml-md-2,.conversejs .mx-md-2{margin-left:.5rem!important}.conversejs .m-md-3{margin:1rem!important}.conversejs .mt-md-3,.conversejs .my-md-3{margin-top:1rem!important}.conversejs .mr-md-3,.conversejs .mx-md-3{margin-right:1rem!important}.conversejs .mb-md-3,.conversejs .my-md-3{margin-bottom:1rem!important}.conversejs .ml-md-3,.conversejs .mx-md-3{margin-left:1rem!important}.conversejs .m-md-4{margin:1.5rem!important}.conversejs .mt-md-4,.conversejs .my-md-4{margin-top:1.5rem!important}.conversejs .mr-md-4,.conversejs .mx-md-4{margin-right:1.5rem!important}.conversejs .mb-md-4,.conversejs .my-md-4{margin-bottom:1.5rem!important}.conversejs .ml-md-4,.conversejs .mx-md-4{margin-left:1.5rem!important}.conversejs .m-md-5{margin:3rem!important}.conversejs .mt-md-5,.conversejs .my-md-5{margin-top:3rem!important}.conversejs .mr-md-5,.conversejs .mx-md-5{margin-right:3rem!important}.conversejs .mb-md-5,.conversejs .my-md-5{margin-bottom:3rem!important}.conversejs .ml-md-5,.conversejs .mx-md-5{margin-left:3rem!important}.conversejs .p-md-0{padding:0!important}.conversejs .pt-md-0,.conversejs .py-md-0{padding-top:0!important}.conversejs .pr-md-0,.conversejs .px-md-0{padding-right:0!important}.conversejs .pb-md-0,.conversejs .py-md-0{padding-bottom:0!important}.conversejs .pl-md-0,.conversejs .px-md-0{padding-left:0!important}.conversejs .p-md-1{padding:.25rem!important}.conversejs .pt-md-1,.conversejs .py-md-1{padding-top:.25rem!important}.conversejs .pr-md-1,.conversejs .px-md-1{padding-right:.25rem!important}.conversejs .pb-md-1,.conversejs .py-md-1{padding-bottom:.25rem!important}.conversejs .pl-md-1,.conversejs .px-md-1{padding-left:.25rem!important}.conversejs .p-md-2{padding:.5rem!important}.conversejs .pt-md-2,.conversejs .py-md-2{padding-top:.5rem!important}.conversejs .pr-md-2,.conversejs .px-md-2{padding-right:.5rem!important}.conversejs .pb-md-2,.conversejs .py-md-2{padding-bottom:.5rem!important}.conversejs .pl-md-2,.conversejs .px-md-2{padding-left:.5rem!important}.conversejs .p-md-3{padding:1rem!important}.conversejs .pt-md-3,.conversejs .py-md-3{padding-top:1rem!important}.conversejs .pr-md-3,.conversejs .px-md-3{padding-right:1rem!important}.conversejs .pb-md-3,.conversejs .py-md-3{padding-bottom:1rem!important}.conversejs .pl-md-3,.conversejs .px-md-3{padding-left:1rem!important}.conversejs .p-md-4{padding:1.5rem!important}.conversejs .pt-md-4,.conversejs .py-md-4{padding-top:1.5rem!important}.conversejs .pr-md-4,.conversejs .px-md-4{padding-right:1.5rem!important}.conversejs .pb-md-4,.conversejs .py-md-4{padding-bottom:1.5rem!important}.conversejs .pl-md-4,.conversejs .px-md-4{padding-left:1.5rem!important}.conversejs .p-md-5{padding:3rem!important}.conversejs .pt-md-5,.conversejs .py-md-5{padding-top:3rem!important}.conversejs .pr-md-5,.conversejs .px-md-5{padding-right:3rem!important}.conversejs .pb-md-5,.conversejs .py-md-5{padding-bottom:3rem!important}.conversejs .pl-md-5,.conversejs .px-md-5{padding-left:3rem!important}.conversejs .m-md-n1{margin:-.25rem!important}.conversejs .mt-md-n1,.conversejs .my-md-n1{margin-top:-.25rem!important}.conversejs .mr-md-n1,.conversejs .mx-md-n1{margin-right:-.25rem!important}.conversejs .mb-md-n1,.conversejs .my-md-n1{margin-bottom:-.25rem!important}.conversejs .ml-md-n1,.conversejs .mx-md-n1{margin-left:-.25rem!important}.conversejs .m-md-n2{margin:-.5rem!important}.conversejs .mt-md-n2,.conversejs .my-md-n2{margin-top:-.5rem!important}.conversejs .mr-md-n2,.conversejs .mx-md-n2{margin-right:-.5rem!important}.conversejs .mb-md-n2,.conversejs .my-md-n2{margin-bottom:-.5rem!important}.conversejs .ml-md-n2,.conversejs .mx-md-n2{margin-left:-.5rem!important}.conversejs .m-md-n3{margin:-1rem!important}.conversejs .mt-md-n3,.conversejs .my-md-n3{margin-top:-1rem!important}.conversejs .mr-md-n3,.conversejs .mx-md-n3{margin-right:-1rem!important}.conversejs .mb-md-n3,.conversejs .my-md-n3{margin-bottom:-1rem!important}.conversejs .ml-md-n3,.conversejs .mx-md-n3{margin-left:-1rem!important}.conversejs .m-md-n4{margin:-1.5rem!important}.conversejs .mt-md-n4,.conversejs .my-md-n4{margin-top:-1.5rem!important}.conversejs .mr-md-n4,.conversejs .mx-md-n4{margin-right:-1.5rem!important}.conversejs .mb-md-n4,.conversejs .my-md-n4{margin-bottom:-1.5rem!important}.conversejs .ml-md-n4,.conversejs .mx-md-n4{margin-left:-1.5rem!important}.conversejs .m-md-n5{margin:-3rem!important}.conversejs .mt-md-n5,.conversejs .my-md-n5{margin-top:-3rem!important}.conversejs .mr-md-n5,.conversejs .mx-md-n5{margin-right:-3rem!important}.conversejs .mb-md-n5,.conversejs .my-md-n5{margin-bottom:-3rem!important}.conversejs .ml-md-n5,.conversejs .mx-md-n5{margin-left:-3rem!important}.conversejs .m-md-auto{margin:auto!important}.conversejs .mt-md-auto,.conversejs .my-md-auto{margin-top:auto!important}.conversejs .mr-md-auto,.conversejs .mx-md-auto{margin-right:auto!important}.conversejs .mb-md-auto,.conversejs .my-md-auto{margin-bottom:auto!important}.conversejs .ml-md-auto,.conversejs .mx-md-auto{margin-left:auto!important}}@media(min-width:992px){.conversejs .m-lg-0{margin:0!important}.conversejs .mt-lg-0,.conversejs .my-lg-0{margin-top:0!important}.conversejs .mr-lg-0,.conversejs .mx-lg-0{margin-right:0!important}.conversejs .mb-lg-0,.conversejs .my-lg-0{margin-bottom:0!important}.conversejs .ml-lg-0,.conversejs .mx-lg-0{margin-left:0!important}.conversejs .m-lg-1{margin:.25rem!important}.conversejs .mt-lg-1,.conversejs .my-lg-1{margin-top:.25rem!important}.conversejs .mr-lg-1,.conversejs .mx-lg-1{margin-right:.25rem!important}.conversejs .mb-lg-1,.conversejs .my-lg-1{margin-bottom:.25rem!important}.conversejs .ml-lg-1,.conversejs .mx-lg-1{margin-left:.25rem!important}.conversejs .m-lg-2{margin:.5rem!important}.conversejs .mt-lg-2,.conversejs .my-lg-2{margin-top:.5rem!important}.conversejs .mr-lg-2,.conversejs .mx-lg-2{margin-right:.5rem!important}.conversejs .mb-lg-2,.conversejs .my-lg-2{margin-bottom:.5rem!important}.conversejs .ml-lg-2,.conversejs .mx-lg-2{margin-left:.5rem!important}.conversejs .m-lg-3{margin:1rem!important}.conversejs .mt-lg-3,.conversejs .my-lg-3{margin-top:1rem!important}.conversejs .mr-lg-3,.conversejs .mx-lg-3{margin-right:1rem!important}.conversejs .mb-lg-3,.conversejs .my-lg-3{margin-bottom:1rem!important}.conversejs .ml-lg-3,.conversejs .mx-lg-3{margin-left:1rem!important}.conversejs .m-lg-4{margin:1.5rem!important}.conversejs .mt-lg-4,.conversejs .my-lg-4{margin-top:1.5rem!important}.conversejs .mr-lg-4,.conversejs .mx-lg-4{margin-right:1.5rem!important}.conversejs .mb-lg-4,.conversejs .my-lg-4{margin-bottom:1.5rem!important}.conversejs .ml-lg-4,.conversejs .mx-lg-4{margin-left:1.5rem!important}.conversejs .m-lg-5{margin:3rem!important}.conversejs .mt-lg-5,.conversejs .my-lg-5{margin-top:3rem!important}.conversejs .mr-lg-5,.conversejs .mx-lg-5{margin-right:3rem!important}.conversejs .mb-lg-5,.conversejs .my-lg-5{margin-bottom:3rem!important}.conversejs .ml-lg-5,.conversejs .mx-lg-5{margin-left:3rem!important}.conversejs .p-lg-0{padding:0!important}.conversejs .pt-lg-0,.conversejs .py-lg-0{padding-top:0!important}.conversejs .pr-lg-0,.conversejs .px-lg-0{padding-right:0!important}.conversejs .pb-lg-0,.conversejs .py-lg-0{padding-bottom:0!important}.conversejs .pl-lg-0,.conversejs .px-lg-0{padding-left:0!important}.conversejs .p-lg-1{padding:.25rem!important}.conversejs .pt-lg-1,.conversejs .py-lg-1{padding-top:.25rem!important}.conversejs .pr-lg-1,.conversejs .px-lg-1{padding-right:.25rem!important}.conversejs .pb-lg-1,.conversejs .py-lg-1{padding-bottom:.25rem!important}.conversejs .pl-lg-1,.conversejs .px-lg-1{padding-left:.25rem!important}.conversejs .p-lg-2{padding:.5rem!important}.conversejs .pt-lg-2,.conversejs .py-lg-2{padding-top:.5rem!important}.conversejs .pr-lg-2,.conversejs .px-lg-2{padding-right:.5rem!important}.conversejs .pb-lg-2,.conversejs .py-lg-2{padding-bottom:.5rem!important}.conversejs .pl-lg-2,.conversejs .px-lg-2{padding-left:.5rem!important}.conversejs .p-lg-3{padding:1rem!important}.conversejs .pt-lg-3,.conversejs .py-lg-3{padding-top:1rem!important}.conversejs .pr-lg-3,.conversejs .px-lg-3{padding-right:1rem!important}.conversejs .pb-lg-3,.conversejs .py-lg-3{padding-bottom:1rem!important}.conversejs .pl-lg-3,.conversejs .px-lg-3{padding-left:1rem!important}.conversejs .p-lg-4{padding:1.5rem!important}.conversejs .pt-lg-4,.conversejs .py-lg-4{padding-top:1.5rem!important}.conversejs .pr-lg-4,.conversejs .px-lg-4{padding-right:1.5rem!important}.conversejs .pb-lg-4,.conversejs .py-lg-4{padding-bottom:1.5rem!important}.conversejs .pl-lg-4,.conversejs .px-lg-4{padding-left:1.5rem!important}.conversejs .p-lg-5{padding:3rem!important}.conversejs .pt-lg-5,.conversejs .py-lg-5{padding-top:3rem!important}.conversejs .pr-lg-5,.conversejs .px-lg-5{padding-right:3rem!important}.conversejs .pb-lg-5,.conversejs .py-lg-5{padding-bottom:3rem!important}.conversejs .pl-lg-5,.conversejs .px-lg-5{padding-left:3rem!important}.conversejs .m-lg-n1{margin:-.25rem!important}.conversejs .mt-lg-n1,.conversejs .my-lg-n1{margin-top:-.25rem!important}.conversejs .mr-lg-n1,.conversejs .mx-lg-n1{margin-right:-.25rem!important}.conversejs .mb-lg-n1,.conversejs .my-lg-n1{margin-bottom:-.25rem!important}.conversejs .ml-lg-n1,.conversejs .mx-lg-n1{margin-left:-.25rem!important}.conversejs .m-lg-n2{margin:-.5rem!important}.conversejs .mt-lg-n2,.conversejs .my-lg-n2{margin-top:-.5rem!important}.conversejs .mr-lg-n2,.conversejs .mx-lg-n2{margin-right:-.5rem!important}.conversejs .mb-lg-n2,.conversejs .my-lg-n2{margin-bottom:-.5rem!important}.conversejs .ml-lg-n2,.conversejs .mx-lg-n2{margin-left:-.5rem!important}.conversejs .m-lg-n3{margin:-1rem!important}.conversejs .mt-lg-n3,.conversejs .my-lg-n3{margin-top:-1rem!important}.conversejs .mr-lg-n3,.conversejs .mx-lg-n3{margin-right:-1rem!important}.conversejs .mb-lg-n3,.conversejs .my-lg-n3{margin-bottom:-1rem!important}.conversejs .ml-lg-n3,.conversejs .mx-lg-n3{margin-left:-1rem!important}.conversejs .m-lg-n4{margin:-1.5rem!important}.conversejs .mt-lg-n4,.conversejs .my-lg-n4{margin-top:-1.5rem!important}.conversejs .mr-lg-n4,.conversejs .mx-lg-n4{margin-right:-1.5rem!important}.conversejs .mb-lg-n4,.conversejs .my-lg-n4{margin-bottom:-1.5rem!important}.conversejs .ml-lg-n4,.conversejs .mx-lg-n4{margin-left:-1.5rem!important}.conversejs .m-lg-n5{margin:-3rem!important}.conversejs .mt-lg-n5,.conversejs .my-lg-n5{margin-top:-3rem!important}.conversejs .mr-lg-n5,.conversejs .mx-lg-n5{margin-right:-3rem!important}.conversejs .mb-lg-n5,.conversejs .my-lg-n5{margin-bottom:-3rem!important}.conversejs .ml-lg-n5,.conversejs .mx-lg-n5{margin-left:-3rem!important}.conversejs .m-lg-auto{margin:auto!important}.conversejs .mt-lg-auto,.conversejs .my-lg-auto{margin-top:auto!important}.conversejs .mr-lg-auto,.conversejs .mx-lg-auto{margin-right:auto!important}.conversejs .mb-lg-auto,.conversejs .my-lg-auto{margin-bottom:auto!important}.conversejs .ml-lg-auto,.conversejs .mx-lg-auto{margin-left:auto!important}}@media(min-width:1200px){.conversejs .m-xl-0{margin:0!important}.conversejs .mt-xl-0,.conversejs .my-xl-0{margin-top:0!important}.conversejs .mr-xl-0,.conversejs .mx-xl-0{margin-right:0!important}.conversejs .mb-xl-0,.conversejs .my-xl-0{margin-bottom:0!important}.conversejs .ml-xl-0,.conversejs .mx-xl-0{margin-left:0!important}.conversejs .m-xl-1{margin:.25rem!important}.conversejs .mt-xl-1,.conversejs .my-xl-1{margin-top:.25rem!important}.conversejs .mr-xl-1,.conversejs .mx-xl-1{margin-right:.25rem!important}.conversejs .mb-xl-1,.conversejs .my-xl-1{margin-bottom:.25rem!important}.conversejs .ml-xl-1,.conversejs .mx-xl-1{margin-left:.25rem!important}.conversejs .m-xl-2{margin:.5rem!important}.conversejs .mt-xl-2,.conversejs .my-xl-2{margin-top:.5rem!important}.conversejs .mr-xl-2,.conversejs .mx-xl-2{margin-right:.5rem!important}.conversejs .mb-xl-2,.conversejs .my-xl-2{margin-bottom:.5rem!important}.conversejs .ml-xl-2,.conversejs .mx-xl-2{margin-left:.5rem!important}.conversejs .m-xl-3{margin:1rem!important}.conversejs .mt-xl-3,.conversejs .my-xl-3{margin-top:1rem!important}.conversejs .mr-xl-3,.conversejs .mx-xl-3{margin-right:1rem!important}.conversejs .mb-xl-3,.conversejs .my-xl-3{margin-bottom:1rem!important}.conversejs .ml-xl-3,.conversejs .mx-xl-3{margin-left:1rem!important}.conversejs .m-xl-4{margin:1.5rem!important}.conversejs .mt-xl-4,.conversejs .my-xl-4{margin-top:1.5rem!important}.conversejs .mr-xl-4,.conversejs .mx-xl-4{margin-right:1.5rem!important}.conversejs .mb-xl-4,.conversejs .my-xl-4{margin-bottom:1.5rem!important}.conversejs .ml-xl-4,.conversejs .mx-xl-4{margin-left:1.5rem!important}.conversejs .m-xl-5{margin:3rem!important}.conversejs .mt-xl-5,.conversejs .my-xl-5{margin-top:3rem!important}.conversejs .mr-xl-5,.conversejs .mx-xl-5{margin-right:3rem!important}.conversejs .mb-xl-5,.conversejs .my-xl-5{margin-bottom:3rem!important}.conversejs .ml-xl-5,.conversejs .mx-xl-5{margin-left:3rem!important}.conversejs .p-xl-0{padding:0!important}.conversejs .pt-xl-0,.conversejs .py-xl-0{padding-top:0!important}.conversejs .pr-xl-0,.conversejs .px-xl-0{padding-right:0!important}.conversejs .pb-xl-0,.conversejs .py-xl-0{padding-bottom:0!important}.conversejs .pl-xl-0,.conversejs .px-xl-0{padding-left:0!important}.conversejs .p-xl-1{padding:.25rem!important}.conversejs .pt-xl-1,.conversejs .py-xl-1{padding-top:.25rem!important}.conversejs .pr-xl-1,.conversejs .px-xl-1{padding-right:.25rem!important}.conversejs .pb-xl-1,.conversejs .py-xl-1{padding-bottom:.25rem!important}.conversejs .pl-xl-1,.conversejs .px-xl-1{padding-left:.25rem!important}.conversejs .p-xl-2{padding:.5rem!important}.conversejs .pt-xl-2,.conversejs .py-xl-2{padding-top:.5rem!important}.conversejs .pr-xl-2,.conversejs .px-xl-2{padding-right:.5rem!important}.conversejs .pb-xl-2,.conversejs .py-xl-2{padding-bottom:.5rem!important}.conversejs .pl-xl-2,.conversejs .px-xl-2{padding-left:.5rem!important}.conversejs .p-xl-3{padding:1rem!important}.conversejs .pt-xl-3,.conversejs .py-xl-3{padding-top:1rem!important}.conversejs .pr-xl-3,.conversejs .px-xl-3{padding-right:1rem!important}.conversejs .pb-xl-3,.conversejs .py-xl-3{padding-bottom:1rem!important}.conversejs .pl-xl-3,.conversejs .px-xl-3{padding-left:1rem!important}.conversejs .p-xl-4{padding:1.5rem!important}.conversejs .pt-xl-4,.conversejs .py-xl-4{padding-top:1.5rem!important}.conversejs .pr-xl-4,.conversejs .px-xl-4{padding-right:1.5rem!important}.conversejs .pb-xl-4,.conversejs .py-xl-4{padding-bottom:1.5rem!important}.conversejs .pl-xl-4,.conversejs .px-xl-4{padding-left:1.5rem!important}.conversejs .p-xl-5{padding:3rem!important}.conversejs .pt-xl-5,.conversejs .py-xl-5{padding-top:3rem!important}.conversejs .pr-xl-5,.conversejs .px-xl-5{padding-right:3rem!important}.conversejs .pb-xl-5,.conversejs .py-xl-5{padding-bottom:3rem!important}.conversejs .pl-xl-5,.conversejs .px-xl-5{padding-left:3rem!important}.conversejs .m-xl-n1{margin:-.25rem!important}.conversejs .mt-xl-n1,.conversejs .my-xl-n1{margin-top:-.25rem!important}.conversejs .mr-xl-n1,.conversejs .mx-xl-n1{margin-right:-.25rem!important}.conversejs .mb-xl-n1,.conversejs .my-xl-n1{margin-bottom:-.25rem!important}.conversejs .ml-xl-n1,.conversejs .mx-xl-n1{margin-left:-.25rem!important}.conversejs .m-xl-n2{margin:-.5rem!important}.conversejs .mt-xl-n2,.conversejs .my-xl-n2{margin-top:-.5rem!important}.conversejs .mr-xl-n2,.conversejs .mx-xl-n2{margin-right:-.5rem!important}.conversejs .mb-xl-n2,.conversejs .my-xl-n2{margin-bottom:-.5rem!important}.conversejs .ml-xl-n2,.conversejs .mx-xl-n2{margin-left:-.5rem!important}.conversejs .m-xl-n3{margin:-1rem!important}.conversejs .mt-xl-n3,.conversejs .my-xl-n3{margin-top:-1rem!important}.conversejs .mr-xl-n3,.conversejs .mx-xl-n3{margin-right:-1rem!important}.conversejs .mb-xl-n3,.conversejs .my-xl-n3{margin-bottom:-1rem!important}.conversejs .ml-xl-n3,.conversejs .mx-xl-n3{margin-left:-1rem!important}.conversejs .m-xl-n4{margin:-1.5rem!important}.conversejs .mt-xl-n4,.conversejs .my-xl-n4{margin-top:-1.5rem!important}.conversejs .mr-xl-n4,.conversejs .mx-xl-n4{margin-right:-1.5rem!important}.conversejs .mb-xl-n4,.conversejs .my-xl-n4{margin-bottom:-1.5rem!important}.conversejs .ml-xl-n4,.conversejs .mx-xl-n4{margin-left:-1.5rem!important}.conversejs .m-xl-n5{margin:-3rem!important}.conversejs .mt-xl-n5,.conversejs .my-xl-n5{margin-top:-3rem!important}.conversejs .mr-xl-n5,.conversejs .mx-xl-n5{margin-right:-3rem!important}.conversejs .mb-xl-n5,.conversejs .my-xl-n5{margin-bottom:-3rem!important}.conversejs .ml-xl-n5,.conversejs .mx-xl-n5{margin-left:-3rem!important}.conversejs .m-xl-auto{margin:auto!important}.conversejs .mt-xl-auto,.conversejs .my-xl-auto{margin-top:auto!important}.conversejs .mr-xl-auto,.conversejs .mx-xl-auto{margin-right:auto!important}.conversejs .mb-xl-auto,.conversejs .my-xl-auto{margin-bottom:auto!important}.conversejs .ml-xl-auto,.conversejs .mx-xl-auto{margin-left:auto!important}}.conversejs .stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.conversejs .text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.conversejs .text-justify{text-align:justify!important}.conversejs .text-wrap{white-space:normal!important}.conversejs .text-nowrap{white-space:nowrap!important}.conversejs .text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .text-left{text-align:left!important}.conversejs .text-right{text-align:right!important}.conversejs .text-center{text-align:center!important}@media(min-width:576px){.conversejs .text-sm-left{text-align:left!important}.conversejs .text-sm-right{text-align:right!important}.conversejs .text-sm-center{text-align:center!important}}@media(min-width:768px){.conversejs .text-md-left{text-align:left!important}.conversejs .text-md-right{text-align:right!important}.conversejs .text-md-center{text-align:center!important}}@media(min-width:992px){.conversejs .text-lg-left{text-align:left!important}.conversejs .text-lg-right{text-align:right!important}.conversejs .text-lg-center{text-align:center!important}}@media(min-width:1200px){.conversejs .text-xl-left{text-align:left!important}.conversejs .text-xl-right{text-align:right!important}.conversejs .text-xl-center{text-align:center!important}}.conversejs .text-lowercase{text-transform:lowercase!important}.conversejs .text-uppercase{text-transform:uppercase!important}.conversejs .text-capitalize{text-transform:capitalize!important}.conversejs .font-weight-light{font-weight:300!important}.conversejs .font-weight-lighter{font-weight:lighter!important}.conversejs .font-weight-normal{font-weight:400!important}.conversejs .font-weight-bold{font-weight:700!important}.conversejs .font-weight-bolder{font-weight:bolder!important}.conversejs .font-italic{font-style:italic!important}.conversejs .text-white{color:#fff!important}.conversejs .text-primary{color:#007bff!important}.conversejs a.text-primary:focus,.conversejs a.text-primary:hover{color:#0056b3!important}.conversejs .text-secondary{color:#6c757d!important}.conversejs a.text-secondary:focus,.conversejs a.text-secondary:hover{color:#494f54!important}.conversejs .text-success{color:#28a745!important}.conversejs a.text-success:focus,.conversejs a.text-success:hover{color:#19692c!important}.conversejs .text-info{color:#17a2b8!important}.conversejs a.text-info:focus,.conversejs a.text-info:hover{color:#0f6674!important}.conversejs .text-warning{color:#ffc107!important}.conversejs a.text-warning:focus,.conversejs a.text-warning:hover{color:#ba8b00!important}.conversejs .text-danger{color:#dc3545!important}.conversejs a.text-danger:focus,.conversejs a.text-danger:hover{color:#a71d2a!important}.conversejs .text-light{color:#f8f9fa!important}.conversejs a.text-light:focus,.conversejs a.text-light:hover{color:#cbd3da!important}.conversejs .text-dark{color:#343a40!important}.conversejs a.text-dark:focus,.conversejs a.text-dark:hover{color:#121416!important}.conversejs .text-body{color:#212529!important}.conversejs .text-muted{color:#6c757d!important}.conversejs .text-black-50{color:rgba(0,0,0,.5)!important}.conversejs .text-white-50{color:rgba(255,255,255,.5)!important}.conversejs .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.conversejs .text-decoration-none{text-decoration:none!important}.conversejs .text-break{word-break:break-word!important;word-wrap:break-word!important}.conversejs .text-reset{color:inherit!important}.conversejs .visible{visibility:visible!important}.conversejs .invisible{visibility:hidden!important}#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--toolbar-btn-text-color:white;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs{color:var(--text-color);font-family:var(--normal-font);font-size:var(--font-size);direction:ltr}.conversejs .flyout{position:absolute}.conversejs textarea:disabled{background-color:#eee!important}.conversejs .subdued{opacity:.35}.conversejs .fit-content{width:-webkit-fit-content!important;width:-moz-fit-content!important;width:fit-content!important;max-width:-webkit-fit-content!important;max-width:-moz-fit-content!important;max-width:fit-content!important}.conversejs .nopadding{padding:0!important}.conversejs .no-scrolling{overflow-x:none;overflow-y:none}.conversejs converse-brand-heading{text-align:center}.conversejs .brand-heading{display:inline-flex;flex-direction:row;align-items:flex-start;font-family:var(--branding-font);color:var(--link-color);margin-bottom:.75em}.conversejs .brand-heading .brand-name-wrapper{display:flex;white-space:nowrap;margin:auto}.conversejs .brand-heading .brand-name{color:var(--link-color);display:flex;flex-direction:column;align-items:center;margin-top:-.25em}.conversejs .brand-heading .brand-name .byline{font-family:var(--heading-font);font-size:.3em;margin-bottom:.75em;margin-left:-2.7em;opacity:.55;word-spacing:5px}.conversejs .brand-heading .brand-subtitle{color:var(--text-color)}.conversejs .brand-heading .brand-name__text{font-size:120%;vertical-align:text-bottom}.conversejs .brand-heading .converse-svg-logo{color:var(--link-color);height:1.5em;margin-right:.25em;margin-bottom:-.25em}.conversejs .brand-heading .converse-svg-logo .cls-1{isolation:isolate}.conversejs .brand-heading .converse-svg-logo .cls-2{opacity:.5;mix-blend-mode:multiply}.conversejs .brand-heading .converse-svg-logo .cls-3{fill:var(--link-color)}.conversejs .brand-heading .converse-svg-logo .cls-4{fill:var(--link-color)}.conversejs .brand-heading--inverse .converse-svg-logo{margin-bottom:0;margin-top:-.2em}.conversejs .brand-heading--inverse .byline{margin:0;font-family:var(--heading-font);font-size:.25em;opacity:.55;margin-left:-7em;word-spacing:5px}.conversejs .popover{position:fixed}.conversejs ::-moz-placeholder{color:var(--subdued-color)}.conversejs :-ms-input-placeholder{color:var(--subdued-color)}.conversejs ::placeholder{color:var(--subdued-color)}.conversejs ::-moz-selection{background-color:var(--highlight-color)}.conversejs ::selection{background-color:var(--highlight-color)}.conversejs ::-moz-selection{background-color:var(--highlight-color)}@media screen and (max-width:480px){.conversejs{margin:0;right:10px;left:10px;bottom:5px}}@media screen and (max-height:450px){.conversejs{margin:0;right:10px;left:10px;bottom:5px}}.conversejs ul li{height:auto}.conversejs a,.conversejs article,.conversejs aside,.conversejs audio,.conversejs blockquote,.conversejs caption,.conversejs dd,.conversejs details,.conversejs div,.conversejs dl,.conversejs dt,.conversejs em,.conversejs embed,.conversejs fieldset,.conversejs figcaption,.conversejs figure,.conversejs footer,.conversejs form,.conversejs h1,.conversejs h2,.conversejs h3,.conversejs h4,.conversejs h5,.conversejs h6,.conversejs header,.conversejs hgroup,.conversejs img,.conversejs legend,.conversejs li,.conversejs mark,.conversejs menu,.conversejs nav,.conversejs ol,.conversejs output,.conversejs p,.conversejs pre,.conversejs ruby,.conversejs section,.conversejs span,.conversejs strong,.conversejs summary,.conversejs table,.conversejs tbody,.conversejs td,.conversejs tfoot,.conversejs th,.conversejs thead,.conversejs time,.conversejs tr,.conversejs ul,.conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}.conversejs button,.conversejs input[type=button],.conversejs input[type=password],.conversejs input[type=submit],.conversejs input[type=text],.conversejs textarea{font-size:var(--font-size);min-height:0}.conversejs strong{font-weight:700}.conversejs em{font-style:italic}.conversejs ol,.conversejs ul{list-style:none}.conversejs li{height:10px}.conversejs dl,.conversejs ol,.conversejs ul{font:inherit;margin:0}.conversejs a{cursor:pointer}.conversejs a,.conversejs a:not([href]):not([tabindex]),.conversejs a:visited{text-decoration:none;color:var(--link-color);text-shadow:none;cursor:pointer}.conversejs a:hover,.conversejs a:not([href]):not([tabindex]):hover,.conversejs a:visited:hover{color:var(--link-hover-color);text-decoration:none;text-shadow:none}.conversejs a.fa,.conversejs a.far,.conversejs a.fas,.conversejs a:not([href]):not([tabindex]).fa,.conversejs a:not([href]):not([tabindex]).far,.conversejs a:not([href]):not([tabindex]).fas,.conversejs a:visited.fa,.conversejs a:visited.far,.conversejs a:visited.fas{color:var(--subdued-color)}.conversejs a.fa:hover,.conversejs a.far:hover,.conversejs a.fas:hover,.conversejs a:not([href]):not([tabindex]).fa:hover,.conversejs a:not([href]):not([tabindex]).far:hover,.conversejs a:not([href]):not([tabindex]).fas:hover,.conversejs a:visited.fa:hover,.conversejs a:visited.far:hover,.conversejs a:visited.fas:hover{color:var(--gray-color)}.conversejs svg{border-radius:var(--chatbox-border-radius)}.conversejs .fa,.conversejs .far,.conversejs .fas{color:var(--subdued-color)}.conversejs .fa:hover,.conversejs .far:hover,.conversejs .fas:hover{color:var(--gray-color)}.conversejs q{quotes:"“" "”" "‘" "’"}.conversejs q.reason{display:inline}.conversejs q:before{content:open-quote}.conversejs q:after{content:close-quote}.conversejs .helptext{font-size:var(--font-size-tiny);color:var(--text-color-lighten-15-percent)}.conversejs .selected{color:var(--link-color)!important}.conversejs .circle{border-radius:50%}.conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage{0%{background-color:#8dd8ae}25%{background-color:rgba(141,216,174,.75)}50%{background-color:rgba(141,216,174,.5)}75%{background-color:rgba(141,216,174,.25)}100%{background-color:transparent}}@keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@-webkit-keyframes colorchange-chatmessage-muc{0%{background-color:#ffb5a2}25%{background-color:rgba(255,181,162,.75)}50%{background-color:rgba(255,181,162,.5)}75%{background-color:rgba(255,181,162,.25)}100%{background-color:transparent}}@keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadein{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}@keyframes fadeOut{0%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}.conversejs .fade-in{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}.conversejs .visible{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}.conversejs .hidden{opacity:0!important;display:none!important}.conversejs .fade-out{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}.conversejs .collapsed{height:0!important;overflow:hidden!important;padding:0!important}.conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spin{from{transform:rotate(0)}to{transform:rotate(359deg)}}.conversejs .spinner__container{width:100%}.conversejs .spinner{-webkit-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;width:1em;display:block;text-align:center;padding:.5em 0;font-size:24px}.conversejs .left{float:left}.conversejs .right{float:right}.conversejs .centered{text-align:center;display:block;margin:auto}.conversejs .hor_centered{text-align:center;display:block!important;margin:0 auto;clear:both}.conversejs .error{color:var(--error-color)!important}.conversejs .info{color:var(--info-color)}.conversejs .reg-feedback{font-size:85%;margin-bottom:1em}.conversejs #converse-login .conn-feedback,.conversejs .reg-feedback{display:block;text-align:center;width:100%}.conversejs .avatar-autocomplete{margin-right:.5em;vertical-align:middle}.conversejs .activated{display:block!important}.conversejs .form-help{color:var(--subdued-color);font-size:90%}.conversejs .form-control--labeled{margin-top:.5em}.conversejs .nav-pills .nav-link.active,.conversejs .nav-pills .show>.nav-link{background-color:var(--primary-color)}@media screen and (max-width:575px){body .converse-brand{font-size:3.75em}.conversejs:not(.converse-embedded) .chatbox .chat-body{border-radius:var(--chatbox-border-radius)}.conversejs:not(.converse-embedded) .flyout{border-radius:var(--chatbox-border-radius)}}@media screen and (min-width:576px){.conversejs .offset-sm-2{margin-left:16.666667%}}@media screen and (min-width:768px){.conversejs .offset-md-2{margin-left:16.666667%}.conversejs .offset-md-3{margin-left:25%}}@media screen and (min-width:992px){.conversejs .offset-lg-2{margin-left:16.666667%}.conversejs .offset-lg-3{margin-left:25%}}@media screen and (min-width:1200px){.conversejs .offset-xl-2{margin-left:16.666667%}}@media screen and (max-height:450px){.conversejs{left:0}}.conversejs .btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .btn{transition:none}}.conversejs .btn:hover{color:#212529;text-decoration:none}.conversejs .btn.focus,.conversejs .btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .btn.disabled,.conversejs .btn:disabled{opacity:.65}.conversejs .btn:not(:disabled):not(.disabled){cursor:pointer}.conversejs a.btn.disabled,.conversejs fieldset:disabled a.btn{pointer-events:none}.conversejs .btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.conversejs .btn-primary.focus,.conversejs .btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.conversejs .btn-primary.disabled,.conversejs .btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-primary:not(:disabled):not(.disabled).active,.conversejs .btn-primary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.conversejs .btn-primary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-primary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.conversejs .btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.conversejs .btn-secondary.focus,.conversejs .btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.conversejs .btn-secondary.disabled,.conversejs .btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-secondary:not(:disabled):not(.disabled).active,.conversejs .btn-secondary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.conversejs .btn-secondary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.conversejs .btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.conversejs .btn-success.focus,.conversejs .btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.conversejs .btn-success.disabled,.conversejs .btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-success:not(:disabled):not(.disabled).active,.conversejs .btn-success:not(:disabled):not(.disabled):active,.show>.conversejs .btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.conversejs .btn-success:not(:disabled):not(.disabled).active:focus,.conversejs .btn-success:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.conversejs .btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.conversejs .btn-info.focus,.conversejs .btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.conversejs .btn-info.disabled,.conversejs .btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-info:not(:disabled):not(.disabled).active,.conversejs .btn-info:not(:disabled):not(.disabled):active,.show>.conversejs .btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.conversejs .btn-info:not(:disabled):not(.disabled).active:focus,.conversejs .btn-info:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.conversejs .btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.conversejs .btn-warning.focus,.conversejs .btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.conversejs .btn-warning.disabled,.conversejs .btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-warning:not(:disabled):not(.disabled).active,.conversejs .btn-warning:not(:disabled):not(.disabled):active,.show>.conversejs .btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.conversejs .btn-warning:not(:disabled):not(.disabled).active:focus,.conversejs .btn-warning:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.conversejs .btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.conversejs .btn-danger.focus,.conversejs .btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.conversejs .btn-danger.disabled,.conversejs .btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-danger:not(:disabled):not(.disabled).active,.conversejs .btn-danger:not(:disabled):not(.disabled):active,.show>.conversejs .btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.conversejs .btn-danger:not(:disabled):not(.disabled).active:focus,.conversejs .btn-danger:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.conversejs .btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.conversejs .btn-light.focus,.conversejs .btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.conversejs .btn-light.disabled,.conversejs .btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-light:not(:disabled):not(.disabled).active,.conversejs .btn-light:not(:disabled):not(.disabled):active,.show>.conversejs .btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.conversejs .btn-light:not(:disabled):not(.disabled).active:focus,.conversejs .btn-light:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.conversejs .btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.conversejs .btn-dark.focus,.conversejs .btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.conversejs .btn-dark.disabled,.conversejs .btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-dark:not(:disabled):not(.disabled).active,.conversejs .btn-dark:not(:disabled):not(.disabled):active,.show>.conversejs .btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.conversejs .btn-dark:not(:disabled):not(.disabled).active:focus,.conversejs .btn-dark:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.conversejs .btn-outline-primary{color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary.focus,.conversejs .btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .btn-outline-primary.disabled,.conversejs .btn-outline-primary:disabled{color:#007bff;background-color:transparent}.conversejs .btn-outline-primary:not(:disabled):not(.disabled).active,.conversejs .btn-outline-primary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .btn-outline-primary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .btn-outline-secondary{color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary.focus,.conversejs .btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .btn-outline-secondary.disabled,.conversejs .btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active,.conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .btn-outline-success{color:#28a745;border-color:#28a745}.conversejs .btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-outline-success.focus,.conversejs .btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .btn-outline-success.disabled,.conversejs .btn-outline-success:disabled{color:#28a745;background-color:transparent}.conversejs .btn-outline-success:not(:disabled):not(.disabled).active,.conversejs .btn-outline-success:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.conversejs .btn-outline-success:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .btn-outline-info{color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info.focus,.conversejs .btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .btn-outline-info.disabled,.conversejs .btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.conversejs .btn-outline-info:not(:disabled):not(.disabled).active,.conversejs .btn-outline-info:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.conversejs .btn-outline-info:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .btn-outline-warning{color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning.focus,.conversejs .btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .btn-outline-warning.disabled,.conversejs .btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.conversejs .btn-outline-warning:not(:disabled):not(.disabled).active,.conversejs .btn-outline-warning:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.conversejs .btn-outline-warning:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .btn-outline-danger{color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger.focus,.conversejs .btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .btn-outline-danger.disabled,.conversejs .btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.conversejs .btn-outline-danger:not(:disabled):not(.disabled).active,.conversejs .btn-outline-danger:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.conversejs .btn-outline-danger:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light.focus,.conversejs .btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .btn-outline-light.disabled,.conversejs .btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.conversejs .btn-outline-light:not(:disabled):not(.disabled).active,.conversejs .btn-outline-light:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.conversejs .btn-outline-light:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .btn-outline-dark{color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark.focus,.conversejs .btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .btn-outline-dark.disabled,.conversejs .btn-outline-dark:disabled{color:#343a40;background-color:transparent}.conversejs .btn-outline-dark:not(:disabled):not(.disabled).active,.conversejs .btn-outline-dark:not(:disabled):not(.disabled):active,.show>.conversejs .btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.conversejs .btn-outline-dark:not(:disabled):not(.disabled).active:focus,.conversejs .btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.conversejs .btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .btn-link{font-weight:400;color:#007bff;text-decoration:none}.conversejs .btn-link:hover{color:#0056b3;text-decoration:underline}.conversejs .btn-link.focus,.conversejs .btn-link:focus{text-decoration:underline}.conversejs .btn-link.disabled,.conversejs .btn-link:disabled{color:#6c757d;pointer-events:none}.conversejs .btn-group-lg>.btn,.conversejs .btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs .btn-group-sm>.btn,.conversejs .btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.conversejs .btn-block{display:block;width:100%}.conversejs .btn-block+.btn-block{margin-top:.5rem}.conversejs input[type=button].btn-block,.conversejs input[type=reset].btn-block,.conversejs input[type=submit].btn-block{width:100%}.conversejs .btn-group,.conversejs .btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.conversejs .btn-group-vertical>.btn,.conversejs .btn-group>.btn{position:relative;flex:1 1 auto}.conversejs .btn-group-vertical>.btn:hover,.conversejs .btn-group>.btn:hover{z-index:1}.conversejs .btn-group-vertical>.btn.active,.conversejs .btn-group-vertical>.btn:active,.conversejs .btn-group-vertical>.btn:focus,.conversejs .btn-group>.btn.active,.conversejs .btn-group>.btn:active,.conversejs .btn-group>.btn:focus{z-index:1}.conversejs .btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.conversejs .btn-toolbar .input-group{width:auto}.conversejs .btn-group>.btn-group:not(:first-child),.conversejs .btn-group>.btn:not(:first-child){margin-left:-1px}.conversejs .btn-group>.btn-group:not(:last-child)>.btn,.conversejs .btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .btn-group>.btn-group:not(:first-child)>.btn,.conversejs .btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.conversejs .dropdown-toggle-split::after,.dropright .conversejs .dropdown-toggle-split::after,.dropup .conversejs .dropdown-toggle-split::after{margin-left:0}.dropleft .conversejs .dropdown-toggle-split::before{margin-right:0}.conversejs .btn-group-sm>.btn+.dropdown-toggle-split,.conversejs .btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.conversejs .btn-group-lg>.btn+.dropdown-toggle-split,.conversejs .btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.conversejs .btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.conversejs .btn-group-vertical>.btn,.conversejs .btn-group-vertical>.btn-group{width:100%}.conversejs .btn-group-vertical>.btn-group:not(:first-child),.conversejs .btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.conversejs .btn-group-vertical>.btn-group:not(:last-child)>.btn,.conversejs .btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.conversejs .btn-group-vertical>.btn-group:not(:first-child)>.btn,.conversejs .btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.conversejs .btn-group-toggle>.btn,.conversejs .btn-group-toggle>.btn-group>.btn{margin-bottom:0}.conversejs .btn-group-toggle>.btn input[type=checkbox],.conversejs .btn-group-toggle>.btn input[type=radio],.conversejs .btn-group-toggle>.btn-group>.btn input[type=checkbox],.conversejs .btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.conversejs .btn{font-weight:400;color:var(--button-text-color)}.conversejs .btn.fa{color:var(--button-text-color)!important}.conversejs .btn i.fa,.conversejs .btn i.far,.conversejs .btn i.fas{color:var(--button-text-color);margin-right:.5em}.conversejs .btn i.fa.only-icon,.conversejs .btn i.far.only-icon,.conversejs .btn i.fas.only-icon{margin-right:0}.conversejs .btn converse-icon{display:inline-block;margin-right:0}.conversejs .btn-primary{background-color:var(--primary-color)!important;border-color:transparent!important}.conversejs .btn-primary:active,.conversejs .btn-primary:focus,.conversejs .btn-primary:hover{background-color:var(--primary-color-dark)!important;border-color:transparent!important}.conversejs .btn--transparent{background:0 0;border:none}.conversejs .btn-circle{width:30px;height:30px;text-align:center;padding:.5em 0;font-size:var(--font-size-small);line-height:1.428571429;border-radius:50%}.conversejs .badge-info,.conversejs .btn-info{background-color:var(--primary-color);border-color:var(--primary-color)}.conversejs .badge-info:hover,.conversejs .btn-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}.conversejs .badge-secondary,.conversejs .btn-secondary,.conversejs .button-cancel{color:var(--button-text-color);background-color:var(--secondary-color);border-color:var(--secondary-color)}.conversejs .badge-secondary:hover,.conversejs .btn-secondary:hover,.conversejs .button-cancel:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}.conversejs .btn-warning{color:var(--button-text-color);background-color:var(--warning-color);border-color:var(--warning-color)}.conversejs .btn-warning:hover{color:var(--button-text-color);background-color:var(--warning-color-dark);border-color:var(--warning-color-dark)}.conversejs .btn-danger{color:var(--button-text-color);background-color:var(--danger-color);border-color:var(--danger-color)!important}.conversejs .btn-danger:hover{background-color:var(--danger-color-dark);border-color:var(--danger-color-dark)}.conversejs .badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .badge{transition:none}}a.conversejs .badge:focus,a.conversejs .badge:hover{text-decoration:none}.conversejs .badge:empty{display:none}.conversejs .btn .badge{position:relative;top:-1px}.conversejs .badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.conversejs .badge-primary{color:#fff;background-color:#007bff}a.conversejs .badge-primary:focus,a.conversejs .badge-primary:hover{color:#fff;background-color:#0062cc}a.conversejs .badge-primary.focus,a.conversejs .badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.conversejs .badge-secondary{color:#fff;background-color:#6c757d}a.conversejs .badge-secondary:focus,a.conversejs .badge-secondary:hover{color:#fff;background-color:#545b62}a.conversejs .badge-secondary.focus,a.conversejs .badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.conversejs .badge-success{color:#fff;background-color:#28a745}a.conversejs .badge-success:focus,a.conversejs .badge-success:hover{color:#fff;background-color:#1e7e34}a.conversejs .badge-success.focus,a.conversejs .badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.conversejs .badge-info{color:#fff;background-color:#17a2b8}a.conversejs .badge-info:focus,a.conversejs .badge-info:hover{color:#fff;background-color:#117a8b}a.conversejs .badge-info.focus,a.conversejs .badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.conversejs .badge-warning{color:#212529;background-color:#ffc107}a.conversejs .badge-warning:focus,a.conversejs .badge-warning:hover{color:#212529;background-color:#d39e00}a.conversejs .badge-warning.focus,a.conversejs .badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.conversejs .badge-danger{color:#fff;background-color:#dc3545}a.conversejs .badge-danger:focus,a.conversejs .badge-danger:hover{color:#fff;background-color:#bd2130}a.conversejs .badge-danger.focus,a.conversejs .badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.conversejs .badge-light{color:#212529;background-color:#f8f9fa}a.conversejs .badge-light:focus,a.conversejs .badge-light:hover{color:#212529;background-color:#dae0e5}a.conversejs .badge-light.focus,a.conversejs .badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.conversejs .badge-dark{color:#fff;background-color:#343a40}a.conversejs .badge-dark:focus,a.conversejs .badge-dark:hover{color:#fff;background-color:#1d2124}a.conversejs .badge-dark.focus,a.conversejs .badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.conversejs .badge{color:#fff;font-size:90%;font-weight:400;line-height:1;text-shadow:none}.conversejs .badge-light{color:var(--text-color)}.conversejs .badge-primary{background-color:var(--primary-color);border-color:transparent}.conversejs .badge-primary:active,.conversejs .badge-primary:focus,.conversejs .badge-primary:hover{background-color:var(--primary-color-dark)!important;border-color:transparent!important}.conversejs .badge-info{background-color:var(--primary-color);border-color:var(--primary-color)}.conversejs .badge-info:hover{background-color:var(--primary-color-dark);border-color:var(--primary-color-dark)}.conversejs .badge-secondary{color:#fff;background-color:var(--secondary-color);border-color:var(--secondary-color)}.conversejs .badge-secondary:hover{background-color:var(--secondary-color-dark);border-color:var(--secondary-color-dark)}.conversejs .form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .form-control{transition:none}}.conversejs .form-control::-ms-expand{background-color:transparent;border:0}.conversejs .form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.conversejs .form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .form-control::-moz-placeholder{color:#6c757d;opacity:1}.conversejs .form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.conversejs .form-control::placeholder{color:#6c757d;opacity:1}.conversejs .form-control:disabled,.conversejs .form-control[readonly]{background-color:#e9ecef;opacity:1}.conversejs input[type=date].form-control,.conversejs input[type=datetime-local].form-control,.conversejs input[type=month].form-control,.conversejs input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.conversejs .form-control-file,.conversejs .form-control-range{display:block;width:100%}.conversejs .col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.conversejs .col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.conversejs .col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.conversejs .form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.conversejs .form-control-plaintext.form-control-lg,.conversejs .form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.conversejs .form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.conversejs .form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs select.form-control[multiple],.conversejs select.form-control[size]{height:auto}.conversejs textarea.form-control{height:auto}.conversejs .form-group{margin-bottom:1rem}.conversejs .form-text{display:block;margin-top:.25rem}.conversejs .form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.conversejs .form-row>.col,.conversejs .form-row>[class*=col-]{padding-right:5px;padding-left:5px}.conversejs .form-check{position:relative;display:block;padding-left:1.25rem}.conversejs .form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.conversejs .form-check-input:disabled~.form-check-label,.conversejs .form-check-input[disabled]~.form-check-label{color:#6c757d}.conversejs .form-check-label{margin-bottom:0}.conversejs .form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.conversejs .form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.conversejs .valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.conversejs .valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-row>.col>.conversejs .valid-tooltip,.form-row>[class*=col-]>.conversejs .valid-tooltip{left:5px}.conversejs.is-valid~.valid-feedback,.conversejs.is-valid~.valid-tooltip,.was-validated .conversejs:valid~.valid-feedback,.was-validated .conversejs:valid~.valid-tooltip{display:block}.conversejs .form-control.is-valid,.was-validated .conversejs .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.conversejs .form-control.is-valid:focus,.was-validated .conversejs .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs textarea.form-control.is-valid,.was-validated .conversejs textarea.form-control:valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.conversejs .custom-select.is-valid,.was-validated .conversejs .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.conversejs .custom-select.is-valid:focus,.was-validated .conversejs .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs .form-check-input.is-valid~.form-check-label,.was-validated .conversejs .form-check-input:valid~.form-check-label{color:#28a745}.conversejs .form-check-input.is-valid~.valid-feedback,.conversejs .form-check-input.is-valid~.valid-tooltip,.was-validated .conversejs .form-check-input:valid~.valid-feedback,.was-validated .conversejs .form-check-input:valid~.valid-tooltip{display:block}.conversejs .custom-control-input.is-valid~.custom-control-label,.was-validated .conversejs .custom-control-input:valid~.custom-control-label{color:#28a745}.conversejs .custom-control-input.is-valid~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.conversejs .custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.conversejs .custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs .custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .conversejs .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.conversejs .custom-file-input.is-valid~.custom-file-label,.was-validated .conversejs .custom-file-input:valid~.custom-file-label{border-color:#28a745}.conversejs .custom-file-input.is-valid:focus~.custom-file-label,.was-validated .conversejs .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.conversejs .invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.conversejs .invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-row>.col>.conversejs .invalid-tooltip,.form-row>[class*=col-]>.conversejs .invalid-tooltip{left:5px}.conversejs.is-invalid~.invalid-feedback,.conversejs.is-invalid~.invalid-tooltip,.was-validated .conversejs:invalid~.invalid-feedback,.was-validated .conversejs:invalid~.invalid-tooltip{display:block}.conversejs .form-control.is-invalid,.was-validated .conversejs .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.conversejs .form-control.is-invalid:focus,.was-validated .conversejs .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs textarea.form-control.is-invalid,.was-validated .conversejs textarea.form-control:invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.conversejs .custom-select.is-invalid,.was-validated .conversejs .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat,#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem) no-repeat}.conversejs .custom-select.is-invalid:focus,.was-validated .conversejs .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs .form-check-input.is-invalid~.form-check-label,.was-validated .conversejs .form-check-input:invalid~.form-check-label{color:#dc3545}.conversejs .form-check-input.is-invalid~.invalid-feedback,.conversejs .form-check-input.is-invalid~.invalid-tooltip,.was-validated .conversejs .form-check-input:invalid~.invalid-feedback,.was-validated .conversejs .form-check-input:invalid~.invalid-tooltip{display:block}.conversejs .custom-control-input.is-invalid~.custom-control-label,.was-validated .conversejs .custom-control-input:invalid~.custom-control-label{color:#dc3545}.conversejs .custom-control-input.is-invalid~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.conversejs .custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.conversejs .custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs .custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .conversejs .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.conversejs .custom-file-input.is-invalid~.custom-file-label,.was-validated .conversejs .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.conversejs .custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .conversejs .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.conversejs .form-inline{display:flex;flex-flow:row wrap;align-items:center}.conversejs .form-inline .form-check{width:100%}@media(min-width:576px){.conversejs .form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.conversejs .form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.conversejs .form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.conversejs .form-inline .form-control-plaintext{display:inline-block}.conversejs .form-inline .custom-select,.conversejs .form-inline .input-group{width:auto}.conversejs .form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.conversejs .form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.conversejs .form-inline .custom-control{align-items:center;justify-content:center}.conversejs .form-inline .custom-control-label{margin-bottom:0}}.conversejs .input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.conversejs .input-group>.custom-file,.conversejs .input-group>.custom-select,.conversejs .input-group>.form-control,.conversejs .input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.conversejs .input-group>.custom-file+.custom-file,.conversejs .input-group>.custom-file+.custom-select,.conversejs .input-group>.custom-file+.form-control,.conversejs .input-group>.custom-select+.custom-file,.conversejs .input-group>.custom-select+.custom-select,.conversejs .input-group>.custom-select+.form-control,.conversejs .input-group>.form-control+.custom-file,.conversejs .input-group>.form-control+.custom-select,.conversejs .input-group>.form-control+.form-control,.conversejs .input-group>.form-control-plaintext+.custom-file,.conversejs .input-group>.form-control-plaintext+.custom-select,.conversejs .input-group>.form-control-plaintext+.form-control{margin-left:-1px}.conversejs .input-group>.custom-file .custom-file-input:focus~.custom-file-label,.conversejs .input-group>.custom-select:focus,.conversejs .input-group>.form-control:focus{z-index:3}.conversejs .input-group>.custom-file .custom-file-input:focus{z-index:4}.conversejs .input-group>.custom-select:not(:first-child),.conversejs .input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .input-group>.custom-file{display:flex;align-items:center}.conversejs .input-group>.custom-file:not(:first-child) .custom-file-label,.conversejs .input-group>.custom-file:not(:last-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .input-group:not(.has-validation)>.custom-file:not(:last-child) .custom-file-label::after,.conversejs .input-group:not(.has-validation)>.custom-select:not(:last-child),.conversejs .input-group:not(.has-validation)>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group.has-validation>.custom-file:nth-last-child(n+3) .custom-file-label::after,.conversejs .input-group.has-validation>.custom-select:nth-last-child(n+3),.conversejs .input-group.has-validation>.form-control:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group-append,.conversejs .input-group-prepend{display:flex}.conversejs .input-group-append .btn,.conversejs .input-group-prepend .btn{position:relative;z-index:2}.conversejs .input-group-append .btn:focus,.conversejs .input-group-prepend .btn:focus{z-index:3}.conversejs .input-group-append .btn+.btn,.conversejs .input-group-append .btn+.input-group-text,.conversejs .input-group-append .input-group-text+.btn,.conversejs .input-group-append .input-group-text+.input-group-text,.conversejs .input-group-prepend .btn+.btn,.conversejs .input-group-prepend .btn+.input-group-text,.conversejs .input-group-prepend .input-group-text+.btn,.conversejs .input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.conversejs .input-group-prepend{margin-right:-1px}.conversejs .input-group-append{margin-left:-1px}.conversejs .input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.conversejs .input-group-text input[type=checkbox],.conversejs .input-group-text input[type=radio]{margin-top:0}.conversejs .input-group-lg>.custom-select,.conversejs .input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.conversejs .input-group-lg>.custom-select,.conversejs .input-group-lg>.form-control,.conversejs .input-group-lg>.input-group-append>.btn,.conversejs .input-group-lg>.input-group-append>.input-group-text,.conversejs .input-group-lg>.input-group-prepend>.btn,.conversejs .input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.conversejs .input-group-sm>.custom-select,.conversejs .input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.conversejs .input-group-sm>.custom-select,.conversejs .input-group-sm>.form-control,.conversejs .input-group-sm>.input-group-append>.btn,.conversejs .input-group-sm>.input-group-append>.input-group-text,.conversejs .input-group-sm>.input-group-prepend>.btn,.conversejs .input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.conversejs .input-group-lg>.custom-select,.conversejs .input-group-sm>.custom-select{padding-right:1.75rem}.conversejs .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.btn,.conversejs .input-group.has-validation>.input-group-append:nth-last-child(n+3)>.input-group-text,.conversejs .input-group:not(.has-validation)>.input-group-append:not(:last-child)>.btn,.conversejs .input-group:not(.has-validation)>.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),.conversejs .input-group>.input-group-prepend>.btn,.conversejs .input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .input-group>.input-group-append>.btn,.conversejs .input-group>.input-group-append>.input-group-text,.conversejs .input-group>.input-group-prepend:first-child>.btn:not(:first-child),.conversejs .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.conversejs .input-group>.input-group-prepend:not(:first-child)>.btn,.conversejs .input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem;-webkit-print-color-adjust:exact;color-adjust:exact}.conversejs .custom-control-inline{display:inline-flex;margin-right:1rem}.conversejs .custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.conversejs .custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.conversejs .custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.conversejs .custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.conversejs .custom-control-input:disabled~.custom-control-label,.conversejs .custom-control-input[disabled]~.custom-control-label{color:#6c757d}.conversejs .custom-control-input:disabled~.custom-control-label::before,.conversejs .custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.conversejs .custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.conversejs .custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.conversejs .custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:50%/50% 50% no-repeat}.conversejs .custom-checkbox .custom-control-label::before{border-radius:.25rem}.conversejs .custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.conversejs .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.conversejs .custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-radio .custom-control-label::before{border-radius:50%}.conversejs .custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.conversejs .custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-switch{padding-left:2.25rem}.conversejs .custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.conversejs .custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .custom-switch .custom-control-label::after{transition:none}}.conversejs .custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}.conversejs .custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.conversejs .custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right .75rem center/8px 10px no-repeat;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs .custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-select:focus::-ms-value{color:#495057;background-color:#fff}.conversejs .custom-select[multiple],.conversejs .custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.conversejs .custom-select:disabled{color:#6c757d;background-color:#e9ecef}.conversejs .custom-select::-ms-expand{display:none}.conversejs .custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.conversejs .custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.conversejs .custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.conversejs .custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.conversejs .custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;overflow:hidden;opacity:0}.conversejs .custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-file-input:disabled~.custom-file-label,.conversejs .custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.conversejs .custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.conversejs .custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.conversejs .custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;overflow:hidden;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.conversejs .custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.conversejs .custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.conversejs .custom-range:focus{outline:0}.conversejs .custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.conversejs .custom-range::-moz-focus-outer{border:0}.conversejs .custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media(prefers-reduced-motion:reduce){.conversejs .custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.conversejs .custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.conversejs .custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media(prefers-reduced-motion:reduce){.conversejs .custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.conversejs .custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.conversejs .custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion:reduce){.conversejs .custom-range::-ms-thumb{-ms-transition:none;transition:none}}.conversejs .custom-range::-ms-thumb:active{background-color:#b3d7ff}.conversejs .custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.conversejs .custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.conversejs .custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.conversejs .custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.conversejs .custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.conversejs .custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.conversejs .custom-range:disabled::-moz-range-track{cursor:default}.conversejs .custom-range:disabled::-ms-thumb{background-color:#adb5bd}.conversejs .custom-control-label::before,.conversejs .custom-file-label,.conversejs .custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.conversejs .custom-control-label::before,.conversejs .custom-file-label,.conversejs .custom-select{transition:none}}.conversejs .btn--small{font-size:80%;font-weight:400}.conversejs form .hidden-username{opacity:0!important;height:0!important;padding:0!important}.conversejs form .error-feedback{margin-bottom:.5em}.conversejs form .form-check-label{margin-top:.3rem}.conversejs form .form-control::-moz-placeholder{color:var(--subdued-color)}.conversejs form .form-control:-ms-input-placeholder{color:var(--subdued-color)}.conversejs form .form-control::placeholder{color:var(--subdued-color)}.conversejs form .clear-input{margin-top:.5em;margin-bottom:.5em;position:absolute;right:.2em;cursor:pointer;font-size:var(--font-size)}.conversejs form#converse-login,.conversejs form#converse-register{background:var(--controlbox-pane-background-color)}.conversejs form#converse-login legend,.conversejs form#converse-register legend{width:100%;text-align:center;margin:0 auto .5em auto}.conversejs form#converse-login fieldset.buttons,.conversejs form#converse-register fieldset.buttons{text-align:center}.conversejs form#converse-login .login-anon,.conversejs form#converse-register .login-anon{height:auto;white-space:normal}.conversejs form#converse-login .save-submit,.conversejs form#converse-register .save-submit{color:var(--save-button-color)}.conversejs form#converse-login .form-url,.conversejs form#converse-register .form-url{display:block;font-weight:400;margin:1em 0}.conversejs form.converse-form{padding:1.2rem}.conversejs form.converse-form legend{color:var(--text-color);font-size:125%;margin-bottom:1.5em}.conversejs form.converse-form input[type=number],.conversejs form.converse-form input[type=password],.conversejs form.converse-form input[type=text],.conversejs form.converse-form select{min-width:50%}.conversejs form.converse-form input[type=button],.conversejs form.converse-form input[type=number],.conversejs form.converse-form input[type=password],.conversejs form.converse-form input[type=submit],.conversejs form.converse-form input[type=text]{padding:.5em}.conversejs form.converse-form input[type=button],.conversejs form.converse-form input[type=submit]{padding-left:1em;padding-right:1em;border:none}.conversejs form.converse-form input.error{border:1px solid var(--error-color);color:var(--text-color)}.conversejs form.converse-form .text-muted{color:var(--subdued-color)!important;font-size:85%;padding-top:.5em}.conversejs form.converse-form .text-muted a{color:var(--link-color-lighten-10-percent)}.conversejs form.converse-form .text-muted.error{color:var(--error-color)}.conversejs form.converse-form--modal{padding-bottom:0}.conversejs form.converse-form--spinner{height:100%}.conversejs form.converse-centered-form{min-height:66%;text-align:center}.conversejs form.converse-centered-form input{max-width:30em;margin:auto}.conversejs .list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.conversejs .list-group-item-action{width:100%;color:#495057;text-align:inherit}.conversejs .list-group-item-action:focus,.conversejs .list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.conversejs .list-group-item-action:active{color:#212529;background-color:#e9ecef}.conversejs .list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.conversejs .list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.conversejs .list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.conversejs .list-group-item.disabled,.conversejs .list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.conversejs .list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.conversejs .list-group-item+.conversejs .list-group-item{border-top-width:0}.conversejs .list-group-item+.conversejs .list-group-item.active{margin-top:-1px;border-top-width:1px}.conversejs .list-group-horizontal{flex-direction:row}.conversejs .list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width:576px){.conversejs .list-group-horizontal-sm{flex-direction:row}.conversejs .list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-sm>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:768px){.conversejs .list-group-horizontal-md{flex-direction:row}.conversejs .list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-md>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:992px){.conversejs .list-group-horizontal-lg{flex-direction:row}.conversejs .list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-lg>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:1200px){.conversejs .list-group-horizontal-xl{flex-direction:row}.conversejs .list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.conversejs .list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.conversejs .list-group-horizontal-xl>.list-group-item.active{margin-top:0}.conversejs .list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.conversejs .list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.conversejs .list-group-flush{border-radius:0}.conversejs .list-group-flush>.list-group-item{border-width:0 0 1px}.conversejs .list-group-flush>.list-group-item:last-child{border-bottom-width:0}.conversejs .list-group-item-primary{color:#004085;background-color:#b8daff}.conversejs .list-group-item-primary.list-group-item-action:focus,.conversejs .list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.conversejs .list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.conversejs .list-group-item-secondary{color:#383d41;background-color:#d6d8db}.conversejs .list-group-item-secondary.list-group-item-action:focus,.conversejs .list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.conversejs .list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.conversejs .list-group-item-success{color:#155724;background-color:#c3e6cb}.conversejs .list-group-item-success.list-group-item-action:focus,.conversejs .list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.conversejs .list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.conversejs .list-group-item-info{color:#0c5460;background-color:#bee5eb}.conversejs .list-group-item-info.list-group-item-action:focus,.conversejs .list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.conversejs .list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.conversejs .list-group-item-warning{color:#856404;background-color:#ffeeba}.conversejs .list-group-item-warning.list-group-item-action:focus,.conversejs .list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.conversejs .list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.conversejs .list-group-item-danger{color:#721c24;background-color:#f5c6cb}.conversejs .list-group-item-danger.list-group-item-action:focus,.conversejs .list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.conversejs .list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.conversejs .list-group-item-light{color:#818182;background-color:#fdfdfe}.conversejs .list-group-item-light.list-group-item-action:focus,.conversejs .list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.conversejs .list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.conversejs .list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.conversejs .list-group-item-dark.list-group-item-action:focus,.conversejs .list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.conversejs .list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.conversejs .list-group-item.active{background-color:var(--primary-color);border-color:var(--primary-color-dark)}.conversejs .list-container{text-align:left;padding:.3em 0}.conversejs .list-container .list-toggle{font-family:var(--heading-font);font-weight:var(--list-toggle-font-weight);display:block;color:var(--list-toggle-color);padding:0 0 .5rem 0}.conversejs .list-container .list-toggle:hover{color:var(--list-toggle-hover-color)}.conversejs .items-list{text-align:left}.conversejs .items-list .list-item{border:none;clear:both;color:var(--text-color);overflow:hidden;padding:.5em 0;text-shadow:0 1px 0 var(--text-shadow-color);word-wrap:break-word;height:2.5em}.conversejs .items-list .list-item.unread-msgs{font-weight:700}.conversejs .items-list .list-item .list-item-link{color:var(--list-item-link-color);margin:auto;font-size:var(--font-size);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;vertical-align:baseline}.conversejs .items-list .list-item .list-item-link:hover{color:var(--list-item-link-hover-color)}.conversejs .items-list .list-item .list-item-badge{opacity:1;border-radius:25%;color:#fff;font-size:var(--font-size-small);line-height:var(--font-size-small)}.conversejs .items-list .list-item .list-item-action{opacity:0;font-size:var(--font-size-tiny);padding:.3em 0 0 0;margin:0 0 0 var(--inline-action-margin);width:2em;height:2em;color:var(--subdued-color)}.conversejs .items-list .list-item .list-item-action:before{font-size:var(--font-size)}.conversejs .items-list .list-item .list-item-action.button-on{color:var(--list-item-link-color)}.conversejs .items-list .list-item .list-item-action.button-on:hover{color:var(--list-item-link-hover-color)}.conversejs .items-list .list-item .list-item-action:hover{color:var(--list-toggle-hover-color);opacity:1}.conversejs .items-list .list-item .list-item-action--visible{opacity:1!important}.conversejs .items-list .list-item.open{background-color:var(--list-item-open-color)}.conversejs .items-list .list-item.open:hover{background-color:var(--list-item-open-hover-color)!important}.conversejs .items-list .list-item.open a{color:#fff}.conversejs .items-list .list-item.open .list-item-link:hover{color:#fff}.conversejs .items-list .list-item.open .list-item-action{color:var(--list-item-action-color)}.conversejs .items-list .list-item.open .list-item-action:hover{color:#fff}.conversejs .items-list .list-item:hover{background-color:var(--controlbox-pane-bg-hover-color)}.conversejs .items-list .list-item:hover .fa,.conversejs .items-list .list-item:hover .far,.conversejs .items-list .list-item:hover .fas{opacity:1}.conversejs .styling-directive{color:var(--subdued-color)}.conversejs .older-msg time{font-weight:700}.conversejs .message .show-msg-author-modal{align-self:flex-start;color:var(--text-color)!important}.conversejs .message blockquote{margin-left:.5em;margin-bottom:.25em;padding-right:1em;color:var(--subdued-color);border-left:.3em solid var(--subdued-color);padding-left:.5em;display:inline-block}.conversejs .message code{font-family:monospace}.conversejs .message .mention{font-weight:700}.conversejs .message .mention--self{font-weight:400}.conversejs .message.date-separator,.conversejs .message.separator{height:2em;margin:0;position:relative;text-align:center;z-index:0}.conversejs .message.date-separator .separator,.conversejs .message.separator .separator{border-top:0;border-bottom:var(--chat-separator-border-bottom);margin:0 1em;position:relative;top:1em;z-index:5}.conversejs .message.date-separator .separator-text,.conversejs .message.separator .separator-text{background:#fff;bottom:1px;color:var(--separator-text-color);display:inline-block;line-height:2em;padding:0 1em;position:relative;z-index:5}.conversejs .message.chat-info{color:var(--chat-head-color);font-size:var(--message-font-size);line-height:var(--line-height-small);font-size:90%;padding:.17rem 1rem}.conversejs .message.chat-info.badge{color:var(--chat-head-text-color)}.conversejs .message.chat-info.chat-state-notification{font-style:italic}.conversejs .message.chat-info.chat-event{clear:left;font-style:italic}.conversejs .message.chat-info.chat-error{color:var(--error-color);font-weight:700}.conversejs .message.chat-info .q{font-style:italic}.conversejs .message .chat-image{height:auto;width:auto;max-height:15em;max-width:100%}.conversejs .message.chat-msg--action{font-style:italic}.conversejs .message.chat-msg--action .chat-msg__author{padding-right:.2em}.conversejs .message.chat-msg{display:inline-flex;width:100%;flex-direction:row;padding:.125rem 1rem}.conversejs .message.chat-msg.onload{animation:colorchange-chatmessage 1s;-webkit-animation:colorchange-chatmessage 1s}.conversejs .message.chat-msg:hover{background-color:var(--list-item-hover-color)}.conversejs .message.chat-msg.correcting.groupchat{background-color:var(--chatroom-correcting-color)}.conversejs .message.chat-msg.correcting:not(.groupchat){background-color:var(--chat-correcting-color)}.conversejs .message.chat-msg .spoiler{margin-top:.5em}.conversejs .message.chat-msg .spoiler-hint{margin-bottom:.5em}.conversejs .message.chat-msg .spoiler-toggle{color:#fff}.conversejs .message.chat-msg .spoiler-toggle i{color:#fff;padding-right:.5em}.conversejs .message.chat-msg .spoiler-toggle:before{padding-right:.25em;whitespace:nowrap}.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat .chat-msg__text{color:var(--subdued-color)}.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--delayed .chat-msg__text,.conversejs .message.chat-msg .chat-msg__content--me .chat-msg__body--groupchat.chat-msg__body--received .chat-msg__text{color:var(--message-text-color)}.conversejs .message.chat-msg .chat-msg__content--action{width:100%;margin-left:0}.conversejs .message.chat-msg converse-chat-message-body{display:inline}.conversejs .message.chat-msg .chat-msg__message{line-height:1.5em;display:inline-flex;flex-direction:column;width:100%;overflow-wrap:break-word}.conversejs .message.chat-msg .chat-msg__edit-modal{cursor:pointer;padding-right:.5em}.conversejs .message.chat-msg .chat-msg__subject{font-weight:700;clear:right}.conversejs .message.chat-msg .chat-msg__text{color:var(--message-text-color);padding:0;white-space:pre-wrap;word-wrap:break-word;word-break:break-word}.conversejs .message.chat-msg .chat-msg__text a{word-wrap:break-word;word-break:break-all;display:inline}.conversejs .message.chat-msg .chat-msg__text a.chat-image__link{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:block}.conversejs .message.chat-msg .chat-msg__text img.emoji{height:1.5em;width:1.5em;margin:0 .05em 0 .1em;vertical-align:-.1em}.conversejs .message.chat-msg .chat-msg__text .emojione{margin-bottom:-6px}.conversejs .message.chat-msg .chat-msg__text--larger{font-size:1.6em;padding-top:.25em;padding-bottom:.25em}.conversejs .message.chat-msg .chat-msg__error{color:var(--error-color)}.conversejs .message.chat-msg .chat-msg__media{margin-top:.25rem;word-break:break-all}.conversejs .message.chat-msg .chat-msg__media a{word-wrap:break-word}.conversejs .message.chat-msg .chat-msg__media audio{width:100%}.conversejs .message.chat-msg .chat-msg__author{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--heading-font);font-size:115%;font-weight:700;padding-bottom:1px}.conversejs .message.chat-msg .chat-msg__heading{width:100%;padding-right:.25rem;padding-bottom:.25rem}.conversejs .message.chat-msg .chat-msg__heading .badge{margin-left:.5em;font-family:var(--normal_font)}.conversejs .message.chat-msg .chat-msg__heading .chat-msg__time{padding-left:.25em;padding-right:.25em;color:var(--text-color-lighten-15-percent)}.conversejs .message.chat-msg.chat-msg--action .chat-msg__message{flex-direction:row}.conversejs .message.chat-msg.chat-msg--action .chat-msg__text{width:auto}.conversejs .message.chat-msg.chat-msg--action .chat-msg__heading{margin-top:0;padding-bottom:0;width:auto}.conversejs .message.chat-msg.chat-msg--action .chat-msg__heading .fa{margin-left:.5em}.conversejs .message.chat-msg.chat-msg--action .chat-msg__author{font-size:var(--message-font-size)}.conversejs .message.chat-msg.chat-msg--action .chat-msg__time{margin-left:0}.conversejs .message.chat-msg .chat-msg__content{width:calc(100% - var(--message-avatar-width))}.conversejs .message.chat-msg.chat-msg--followup .chat-msg__heading,.conversejs .message.chat-msg.chat-msg--followup .show-msg-author-modal{display:none}.conversejs .message.chat-msg.chat-msg--followup.chat-msg--with-avatar .chat-msg__content{margin-left:2.75rem;width:100%}.conversejs .message.chat-msg .chat-msg__receipt{margin-left:.5em;margin-right:.5em;color:var(--message-receipt-color)}.conversejs .message .chat-msg__content{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-left:.5rem}.conversejs .message .chat-msg__content:hover .btn--standalone{opacity:1}.conversejs .message .chat-msg__body{display:flex;flex-direction:row;justify-content:space-between}.conversejs .chatroom-body .message.onload{animation:colorchange-chatmessage-muc 1s;-webkit-animation:colorchange-chatmessage-muc 1s}.conversejs .chatroom-body .message .separator{border-top:0;border-bottom:var(--chatroom-separator-border-bottom)}.conversejs converse-chats.converse-overlayed .message.chat-msg.chat-msg--followup .chat-msg__content{margin-left:0}@media screen and (max-width:767px){converse-chats:not(.converse-embedded) .message.chat-msg .chat-msg__author{white-space:normal}}#conversejs-bg .subdued{opacity:.35}#conversejs-bg .converse-brand{display:flex;justify-content:space-between;margin-top:15vh;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:5s;animation-duration:5s;-webkit-animation-timing-function:ease;animation-timing-function:ease}#conversejs-bg .converse-brand__text{color:#fff;font-family:var(--branding-font);font-weight:400;text-align:center;font-size:140%;margin-left:.2em}#conversejs-bg .converse-brand__text .byline{margin:0;font-family:var(--heading-font);font-size:.3em;opacity:.55;margin-bottom:2em;margin-left:-2.7em;word-spacing:5px}.converse-fullscreen #conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media(min-width:768px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 33.3333333333%;max-width:33.3333333333%}}@media(min-width:992px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 25%;max-width:25%}}@media(min-width:1200px){.converse-fullscreen #conversejs-bg .converse-brand__padding{flex:0 0 16.6666666667%;max-width:16.6666666667%}}.converse-fullscreen #conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media(min-width:768px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.6666666667%;max-width:66.6666666667%}}@media(min-width:992px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 75%;max-width:75%}}@media(min-width:1200px){.converse-fullscreen #conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.3333333333%;max-width:83.3333333333%}}.converse-fullscreen #conversejs-bg .converse-brand__heading svg{margin-top:.3em}.converse-overlayed #conversejs-bg .converse-brand__padding{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0}@media(min-width:768px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 16.6666666667%;max-width:16.6666666667%}}@media(min-width:992px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 8.3333333333%;max-width:8.3333333333%}}@media(min-width:1200px){.converse-overlayed #conversejs-bg .converse-brand__padding{flex:0 0 8.3333333333%;max-width:8.3333333333%}}.converse-overlayed #conversejs-bg .converse-brand__heading{position:relative;width:100%;padding-right:15px;padding-left:15px;padding:0;display:flex;justify-content:center;margin:auto}@media(min-width:768px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:4em;flex:0 0 66.6666666667%;max-width:66.6666666667%}}@media(min-width:992px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:5em;flex:0 0 83.3333333333%;max-width:83.3333333333%}}@media(min-width:1200px){.converse-overlayed #conversejs-bg .converse-brand__heading{font-size:6em;flex:0 0 83.3333333333%;max-width:83.3333333333%}}.converse-overlayed #conversejs-bg .converse-brand__heading svg{margin-top:.3em} .conversejs #controlbox .bookmarks-toggle,.conversejs #controlbox .bookmarks-toggle .fa{color:var(--groupchats-header-color)!important}.conversejs #controlbox .bookmarks-toggle .fa:hover,.conversejs #controlbox .bookmarks-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}.conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room{width:80%} -.conversejs converse-chats.converse-chatboxes{z-index:1031;position:fixed;bottom:0;right:0}.conversejs converse-chats.converse-overlayed{height:3em}.conversejs converse-chats.converse-overlayed>.row{flex-direction:row-reverse}.conversejs converse-chats.converse-fullscreen,.conversejs converse-chats.converse-mobile{flex-wrap:nowrap;width:100vw}.conversejs converse-chats.converse-embedded{box-sizing:border-box;bottom:auto;height:100%;position:relative;right:auto;width:100%}.conversejs converse-chats.converse-embedded *,.conversejs converse-chats.converse-embedded :after,.conversejs converse-chats.converse-embedded :before{box-sizing:border-box}.conversejs converse-chats.converse-embedded.converse-chatboxes{z-index:1031;position:inherit;flex-wrap:nowrap;bottom:auto;height:100%;width:100%;margin-left:-15px} +.conversejs converse-chats.converse-chatboxes{z-index:1031;position:fixed;bottom:0;right:0}.conversejs converse-chats.converse-overlayed{height:3em}.conversejs converse-chats.converse-overlayed>.row{flex-direction:row-reverse}.conversejs converse-chats.converse-fullscreen,.conversejs converse-chats.converse-mobile{flex-wrap:nowrap;width:100vw}.conversejs converse-chats.converse-embedded{box-sizing:border-box;bottom:auto;height:100%;position:relative;right:auto;width:100%}.conversejs converse-chats.converse-embedded *,.conversejs converse-chats.converse-embedded :after,.conversejs converse-chats.converse-embedded :before{box-sizing:border-box}.conversejs converse-chats.converse-embedded.converse-chatboxes{z-index:1031;position:inherit;flex-wrap:nowrap;bottom:auto;height:100%;width:100%} .conversejs .modal-open{overflow:hidden}.conversejs .modal-open .modal{overflow-x:hidden;overflow-y:auto}.conversejs .modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.conversejs .modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .conversejs .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media(prefers-reduced-motion:reduce){.modal.fade .conversejs .modal-dialog{transition:none}}.modal.show .conversejs .modal-dialog{transform:none}.modal.modal-static .conversejs .modal-dialog{transform:scale(1.02)}.conversejs .modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.conversejs .modal-dialog-scrollable .modal-footer,.conversejs .modal-dialog-scrollable .modal-header{flex-shrink:0}.conversejs .modal-dialog-scrollable .modal-body{overflow-y:auto}.conversejs .modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.conversejs .modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.conversejs .modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.conversejs .modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.conversejs .modal-dialog-centered.modal-dialog-scrollable::before{content:none}.conversejs .modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.conversejs .modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.conversejs .modal-backdrop.fade{opacity:0}.conversejs .modal-backdrop.show{opacity:.5}.conversejs .modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.conversejs .modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.conversejs .modal-title{margin-bottom:0;line-height:1.5}.conversejs .modal-body{position:relative;flex:1 1 auto;padding:1rem}.conversejs .modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.conversejs .modal-footer>*{margin:.25rem}.conversejs .modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media(min-width:576px){.conversejs .modal-dialog{max-width:500px;margin:1.75rem auto}.conversejs .modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.conversejs .modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.conversejs .modal-dialog-centered{min-height:calc(100% - 3.5rem)}.conversejs .modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.conversejs .modal-sm{max-width:300px}}@media(min-width:992px){.conversejs .modal-lg,.conversejs .modal-xl{max-width:800px}}@media(min-width:1200px){.conversejs .modal-xl{max-width:1140px}}.conversejs #converse-modals .modal .modal-body{overflow-y:auto;max-height:75vh;margin-bottom:2em}.conversejs #converse-modals .modal .modal-body p{padding:.25rem 0}.conversejs #converse-modals .modal .modal-body .confirm .form-group p:first-child{font-size:110%;font-weight:700}.conversejs #converse-modals .modal .modal-body.fit-content{box-sizing:content-box}.conversejs #converse-modals .modal .modal-body.fit-content img{max-width:90vw}.conversejs #converse-modals .modal .modal-body--image .chat-image{max-height:99%;max-width:100%}.conversejs #converse-modals .modal .modal-footer{justify-content:flex-start}.conversejs #converse-modals .modal .roomid-policy-error{color:var(--error-color);font-size:var(--font-size-small);float:right}.conversejs #converse-modals .scrollable-container{max-height:45vh;overflow-y:auto}.conversejs #converse-modals .affiliation-form,.conversejs #converse-modals .role-form{padding:2em 0 1em 0}.conversejs #converse-modals .set-xmpp-status{margin:1em}.conversejs #converse-modals .set-xmpp-status .custom-control-label{padding-top:.25em}.conversejs #converse-modals #omemo-tabpanel{margin-top:1em}.conversejs #converse-modals .btn{font-weight:400}.conversejs #converse-modals #user-profile-modal .profile-form label{font-weight:700}.conversejs #converse-modals #user-profile-modal .fingerprint-removal label{display:flex;padding:.75rem 1.25rem}.conversejs #converse-modals #user-profile-modal .list-group-item{display:flex;justify-content:left;font-size:95%}.conversejs #converse-modals #user-profile-modal .list-group-item input[type=checkbox]{margin-right:1em}.conversejs #converse-modals .fingerprints{width:100%;margin-bottom:1em}.conversejs #converse-modals .fingerprint-trust{display:flex;justify-content:space-between;font-size:95%}.conversejs #converse-modals .fingerprint-trust .fingerprint{margin-left:1em} +converse-message-actions{margin-left:.5em}converse-message-actions .chat-msg__actions .dropdown-menu{min-width:5rem}converse-message-actions .chat-msg__actions i{color:var(--text-color-lighten-15-percent);font-size:70%}converse-message-actions .chat-msg__actions button{border:none;background:0 0;color:var(--text-color-lighten-15-percent);padding:0 .25em}converse-message-actions .chat-msg__actions .btn--standalone{opacity:0;margin-top:-.2em}converse-message-actions .chat-msg__actions .chat-msg__action{width:100%;padding:.5em 1em;text-align:left;white-space:nowrap}converse-message-actions .chat-msg__actions .chat-msg__action converse-icon{margin-right:.25em}converse-message-actions .chat-msg__actions .chat-msg__action:hover{color:var(--text-color);background-color:var(--list-item-hover-color)} converse-gif{display:block}img.gif{visibility:hidden}.gif-canvas{cursor:pointer;max-width:100%;max-height:100%;display:block}.gifcontrol{cursor:pointer;transition:background .25s ease-in-out;z-index:100;display:contents;position:relative}.gifcontrol:after{transition:background .25s ease-in-out;position:absolute;content:"";display:block;left:calc(50% - 25px);top:calc(50% - 25px)}.gifcontrol.loading{background:rgba(255,255,255,.75)}.gifcontrol.loading:after{background:#fff;width:50px;height:50px;border-radius:50px}.gifcontrol.playing:after{opacity:0;transition:opacity .25s ease-in-out;border-left:20px solid #fff;border-right:20px solid #fff;width:50px;height:50px}.gifcontrol.playing:hover:after{opacity:1}.gifcontrol.paused{background:rgba(255,255,255,.5)}.gifcontrol.paused:after{width:0;height:0;border-style:solid;border-width:25px 0 25px 50px;border-color:transparent transparent transparent #fff} converse-chat-message-body audio{display:block}@media(max-width:767.98px){converse-chat-message-body audio{max-width:95%}}@media(min-width:768px){converse-chat-message-body audio{max-width:70%}}@media(min-width:992px){converse-chat-message-body audio{max-width:50%}}@media(min-width:1200px){converse-chat-message-body audio{max-width:40%}}converse-chat-message-body video{display:block;max-height:25em}@media(max-width:767.98px){converse-chat-message-body video{max-width:95%}}@media(min-width:768px){converse-chat-message-body video{max-width:70%}}@media(min-width:992px){converse-chat-message-body video{max-width:50%}}@media(min-width:1200px){converse-chat-message-body video{max-width:40%}}.converse-overlayed converse-chat-message-body audio{display:block;max-width:100%}.converse-overlayed converse-chat-message-body video{display:block;max-width:100%} converse-icon{display:inline-block;padding:0;margin:0;fill:var(--subdued-color)}converse-icon:hover{fill:var(--text-color)} -.conversejs .dropdown,.conversejs .dropleft,.conversejs .dropright,.conversejs .dropup{position:relative}.conversejs .dropdown-toggle{white-space:nowrap}.conversejs .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.conversejs .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.conversejs .dropdown-menu-left{right:auto;left:0}.conversejs .dropdown-menu-right{right:0;left:auto}@media(min-width:576px){.conversejs .dropdown-menu-sm-left{right:auto;left:0}.conversejs .dropdown-menu-sm-right{right:0;left:auto}}@media(min-width:768px){.conversejs .dropdown-menu-md-left{right:auto;left:0}.conversejs .dropdown-menu-md-right{right:0;left:auto}}@media(min-width:992px){.conversejs .dropdown-menu-lg-left{right:auto;left:0}.conversejs .dropdown-menu-lg-right{right:0;left:auto}}@media(min-width:1200px){.conversejs .dropdown-menu-xl-left{right:auto;left:0}.conversejs .dropdown-menu-xl-right{right:0;left:auto}}.conversejs .dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.conversejs .dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.conversejs .dropup .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.conversejs .dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.conversejs .dropright .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropright .dropdown-toggle::after{vertical-align:0}.conversejs .dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.conversejs .dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.conversejs .dropleft .dropdown-toggle::after{display:none}.conversejs .dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.conversejs .dropleft .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropleft .dropdown-toggle::before{vertical-align:0}.conversejs .dropdown-menu[x-placement^=bottom],.conversejs .dropdown-menu[x-placement^=left],.conversejs .dropdown-menu[x-placement^=right],.conversejs .dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.conversejs .dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.conversejs .dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.conversejs .dropdown-item:focus,.conversejs .dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.conversejs .dropdown-item.active,.conversejs .dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.conversejs .dropdown-item.disabled,.conversejs .dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.conversejs .dropdown-menu.show{display:block}.conversejs .dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.conversejs .dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.conversejs converse-dropdown.dropup.dropup--left .dropdown-menu{right:100%;left:auto}.conversejs converse-dropdown .btn--standalone{padding:0 .2em;margin:0}.conversejs converse-dropdown .dropdown-menu{margin-top:-.2em!important}.conversejs converse-dropdown .dropdown-item{padding:.5rem 1rem}.conversejs converse-dropdown .dropdown-item .fa{width:1.25em;margin-right:.75rem}.conversejs converse-dropdown .dropdown-item.selected,.conversejs converse-dropdown .dropdown-item:active{color:#fff!important;background-color:var(--list-item-open-color)}.conversejs converse-dropdown .dropdown-item.selected .fa,.conversejs converse-dropdown .dropdown-item:active .fa{color:#fff!important} +.conversejs .dropdown,.conversejs .dropleft,.conversejs .dropright,.conversejs .dropup{position:relative}.conversejs .dropdown-toggle{white-space:nowrap}.conversejs .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.conversejs .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.conversejs .dropdown-menu-left{right:auto;left:0}.conversejs .dropdown-menu-right{right:0;left:auto}@media(min-width:576px){.conversejs .dropdown-menu-sm-left{right:auto;left:0}.conversejs .dropdown-menu-sm-right{right:0;left:auto}}@media(min-width:768px){.conversejs .dropdown-menu-md-left{right:auto;left:0}.conversejs .dropdown-menu-md-right{right:0;left:auto}}@media(min-width:992px){.conversejs .dropdown-menu-lg-left{right:auto;left:0}.conversejs .dropdown-menu-lg-right{right:0;left:auto}}@media(min-width:1200px){.conversejs .dropdown-menu-xl-left{right:auto;left:0}.conversejs .dropdown-menu-xl-right{right:0;left:auto}}.conversejs .dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.conversejs .dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.conversejs .dropup .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.conversejs .dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.conversejs .dropright .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropright .dropdown-toggle::after{vertical-align:0}.conversejs .dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.conversejs .dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.conversejs .dropleft .dropdown-toggle::after{display:none}.conversejs .dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.conversejs .dropleft .dropdown-toggle:empty::after{margin-left:0}.conversejs .dropleft .dropdown-toggle::before{vertical-align:0}.conversejs .dropdown-menu[x-placement^=bottom],.conversejs .dropdown-menu[x-placement^=left],.conversejs .dropdown-menu[x-placement^=right],.conversejs .dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.conversejs .dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.conversejs .dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.conversejs .dropdown-item:focus,.conversejs .dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#e9ecef}.conversejs .dropdown-item.active,.conversejs .dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.conversejs .dropdown-item.disabled,.conversejs .dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.conversejs .dropdown-menu.show{display:block}.conversejs .dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.conversejs .dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.conversejs converse-dropdown.dropup.dropup--left .dropdown-menu{right:100%;left:auto}.conversejs converse-dropdown .btn--standalone{padding:0 .2em;margin:0}.conversejs converse-dropdown .dropdown-menu{margin-top:-.2em!important}.conversejs converse-dropdown .dropdown-item{line-height:1em;color:var(--text-color);padding:.5rem 1rem}.conversejs converse-dropdown .dropdown-item converse-icon{margin-top:-.1em;width:1.25em;margin-right:0}.conversejs converse-dropdown .dropdown-item.selected,.conversejs converse-dropdown .dropdown-item:active{color:#fff!important;background-color:var(--list-item-open-color)}.conversejs converse-dropdown .dropdown-item.selected .fa,.conversejs converse-dropdown .dropdown-item:active .fa{color:#fff!important}.conversejs converse-dropdown .dropdown-item:hover{color:var(--text-color)} +converse-avatar{border:0;background:0 0}converse-avatar.modal-avatar{display:block;margin-bottom:1em}converse-avatar .avatar{border-radius:var(--avatar-border-radius)} +.conversejs .modal-body .row{margin-left:0;margin-right:0}.conversejs .occupant-details li{margin-bottom:1em} .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,.125);border-radius:.25rem}.conversejs .card>hr{margin-right:0;margin-left:0}.conversejs .card>.list-group{border-top:inherit;border-bottom:inherit}.conversejs .card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.conversejs .card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.conversejs .card>.card-header+.list-group,.conversejs .card>.list-group+.card-footer{border-top:0}.conversejs .card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.conversejs .card-title{margin-bottom:.75rem}.conversejs .card-subtitle{margin-top:-.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:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.conversejs .card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.conversejs .card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.conversejs .card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.conversejs .card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.conversejs .card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.conversejs .card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.conversejs .card-img,.conversejs .card-img-bottom,.conversejs .card-img-top{flex-shrink:0;width:100%}.conversejs .card-img,.conversejs .card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.conversejs .card-img,.conversejs .card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.conversejs .card-deck .card{margin-bottom:15px}@media(min-width:576px){.conversejs .card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.conversejs .card-deck .card{flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.conversejs .card-group>.card{margin-bottom:15px}@media(min-width:576px){.conversejs .card-group{display:flex;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:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.conversejs .card-group>.card:not(:last-child) .card-header,.conversejs .card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.conversejs .card-group>.card:not(:last-child) .card-footer,.conversejs .card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.conversejs .card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.conversejs .card-group>.card:not(:first-child) .card-header,.conversejs .card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.conversejs .card-group>.card:not(:first-child) .card-footer,.conversejs .card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.conversejs .card-columns .card{margin-bottom:.75rem}@media(min-width:576px){.conversejs .card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.conversejs .card-columns .card{display:inline-block;width:100%}}.conversejs .accordion{overflow-anchor:none}.conversejs .accordion>.card{overflow:hidden}.conversejs .accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.conversejs .accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.conversejs .accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{margin:1em 0}@media(max-width:767.98px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:95%}}@media(min-width:768px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:75%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:66%}}@media(min-width:1200px){.conversejs converse-chats.converse-embedded .message .card--unfurl,.conversejs converse-chats.converse-fullscreen .message .card--unfurl{max-width:50%}}.conversejs converse-chats.converse-mobile .message .card--unfurl,.conversejs converse-chats.converse-overlayed .message .card--unfurl{margin:1em 0;max-width:95%} +converse-chat-message .message.chat-msg--retracted .chat-msg__message{color:var(--subdued-color)} converse-chat-content{display:flex;flex-direction:column-reverse;height:100%;justify-content:space-between;overflow:auto} .conversejs .media{display:flex;align-items:flex-start}.conversejs .media-body{flex:1}.conversejs .chatbox img.emoji{height:1.2em;width:1.2em;margin:0 .05em 0 .1em;vertical-align:-.1em}.conversejs .chatbox .sendXMPPMessage .toggle-smiley a.toggle-smiley{padding:0}.conversejs .chatbox converse-emoji-dropdown{display:inline-block}.conversejs .chatbox converse-emoji-dropdown .dropdown-menu{padding:0}.conversejs .chatbox converse-emoji-picker{width:100%;padding-top:0;padding-bottom:0;background-color:var(--chat-head-color);overflow-y:hidden;background:#fff}.conversejs .chatbox converse-emoji-picker .emoji-picker__lists{height:8em;overflow-y:auto;display:flex;flex-direction:column}.conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-category__heading{clear:both;color:var(--subdued-color);cursor:auto;display:block;font-size:var(--font-size);margin:0;padding:.75em 0 0 .5em}.conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-lists__container{overflow-x:hidden}.conversejs .chatbox converse-emoji-picker .emoji-picker__lists .emoji-picker li{float:left}.conversejs .chatbox converse-emoji-picker .emoji-skintone-picker{display:flex;padding:.5em 0;background-color:var(--chat-head-color);width:100%;font-size:var(--font-size)}.conversejs .chatbox converse-emoji-picker .emoji-skintone-picker label{margin:0;padding:0 .5em;white-space:nowrap;font-size:var(--font-size-small);color:var(--heading-color)}.conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul{display:flex;flex-direction:row;flex-wrap:wrap}.conversejs .chatbox converse-emoji-picker .emoji-skintone-picker ul li{padding:0 .25em}.conversejs .chatbox converse-emoji-picker .emoji-picker{background-color:#fff;padding:.5em 0 0 .5em}.conversejs .chatbox converse-emoji-picker .emoji-picker:last-child{padding-bottom:.5em}.conversejs .chatbox converse-emoji-picker .emoji-picker li{display:inline-block;height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden;margin-left:0;list-style:none;position:relative}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji{padding:0 .2em;height:auto;width:auto;margin:0;display:block;text-align:center}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji.selected a{background-color:var(--highlight-color-darker)}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji img{margin:0 auto;height:var(--font-size-huge);width:var(--font-size-huge);display:inline-block;vertical-align:baseline}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a{padding:3px;display:inline-block;font-size:var(--font-size-huge);line-height:calc(var(--font-size-huge) * 1.5);height:calc(var(--font-size-huge) * 1.5);width:calc(var(--font-size-huge) * 1.5);overflow:hidden}.conversejs .chatbox converse-emoji-picker .emoji-picker li.insert-emoji a:hover{background-color:var(--highlight-color-darker)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header{width:100%;display:flex;flex-direction:column;padding:.1em 0;background-color:var(--chat-head-color)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header .emoji-search{width:auto;margin:.25em;height:2em;font-size:var(--font-size-small)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul{display:flex;flex-direction:row;flex-wrap:wrap}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category{padding:.25em 0;font-size:var(--font-size-huge)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{background-color:#fff;border:1px var(--chat-head-color) solid;border-bottom:none}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category.selected a,.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category:hover a{background-color:var(--highlight-color-darker)}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category a{padding:.25em;display:inline-block}.conversejs .chatbox converse-emoji-picker .emoji-picker__header ul .emoji-category img{height:var(--font-size-huge);width:var(--font-size-huge)}.conversejs .chatroom converse-emoji-picker{background-color:var(--chatroom-head-bg-color);background:#fff}.conversejs .chatroom converse-emoji-picker .emoji-skintone-picker{background-color:var(--chatroom-head-bg-color)}.conversejs .chatroom converse-emoji-picker .emoji-picker__header{background-color:var(--chatroom-head-bg-color)}.conversejs .chatroom converse-emoji-picker .emoji-picker__header ul .emoji-category.picked{border:1px var(--chatroom-head-bg-color) solid;border-bottom:none}.conversejs converse-chats.converse-overlayed converse-emoji-dropdown .dropdown-menu{min-width:18em}.conversejs converse-chats.converse-overlayed .chatbox .emoji-picker__header .emoji-category img{height:var(--font-size)!important;width:var(--font-size)!important}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji a{font-size:var(--font-size);line-height:calc(var(--font-size) * 1.5);padding:0;height:calc(var(--font-size) * 1.5);width:calc(var(--font-size) * 1.5)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker .insert-emoji img{height:var(--font-size);width:var(--font-size)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-skintone-picker{font-size:var(--font-size-small)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__header .emoji-category{font-size:var(--font-size-small)}.conversejs converse-chats.converse-overlayed .chatbox converse-emoji-picker .emoji-picker__lists{height:7em}.conversejs converse-chats.converse-embedded converse-emoji-dropdown .dropdown-menu{min-width:20em}.conversejs converse-chats.converse-fullscreen converse-emoji-dropdown .dropdown-menu{min-width:22em}.conversejs converse-chats.converse-fullscreen .chatbox converse-emoji-picker .emoji-picker__lists{height:12em}.conversejs .chatbox converse-emoji-picker{max-width:40em} .conversejs .send-button{border-radius:0;bottom:var(--send-button-bottom);color:var(--inverse-link-color)}.conversejs .chatbox .send-button{background-color:var(--chat-head-color)}.conversejs .chatroom .send-button{background-color:var(--muc-toolbar-btn-color)}.conversejs .chat-toolbar .toolbar-buttons{width:100%}.conversejs .chat-toolbar .toolbar-buttons .message-limit{padding:.5em;font-weight:700}.conversejs .chat-toolbar .toolbar-buttons *{float:left}.conversejs .chat-toolbar .toolbar-buttons .right{float:right}.conversejs .chat-toolbar .unverified,.conversejs .chat-toolbar .unverified a{color:#cf5300}.conversejs .chat-toolbar .private,.conversejs .chat-toolbar .private a{color:#4b7003}.conversejs .chat-toolbar li{cursor:pointer;display:inline-block;list-style:none;padding:0 .5em}.conversejs .chat-toolbar li:hover{cursor:pointer}.conversejs .chat-toolbar li .toolbar-menu{background-color:#fff;bottom:1.7rem;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);height:auto;margin-bottom:0;min-width:21rem;position:absolute;right:0;top:auto;z-index:1000}.conversejs .chat-toolbar li .toolbar-menu.otr-menu{left:-6em;min-width:15rem}.conversejs .chat-toolbar li .toolbar-menu.otr-menu.show{display:flex;flex-direction:column}.conversejs .chat-toolbar li .toolbar-menu a{color:var(--link-color)}.conversejs .chat-toolbar li.toggle-otr ul{z-index:99}.conversejs .chat-toolbar li.toggle-otr ul li{display:block;padding:7px}.conversejs .chat-toolbar li.toggle-otr ul li:hover{background-color:var(--highlight-color)}.conversejs .chat-toolbar li.toggle-otr ul li a{display:block}.conversejs converse-chat-toolbar{background-color:#fff;box-sizing:border-box;display:flex;justify-content:space-between;margin:0;width:100%}.conversejs converse-chat-toolbar .fa,.conversejs converse-chat-toolbar .fa:hover,.conversejs converse-chat-toolbar .far,.conversejs converse-chat-toolbar .far:hover,.conversejs converse-chat-toolbar .fas,.conversejs converse-chat-toolbar .fas:hover{color:var(--chat-head-color);font-size:var(--font-size-large)}.conversejs converse-chat-toolbar .fa svg,.conversejs converse-chat-toolbar .fa:hover svg,.conversejs converse-chat-toolbar .far svg,.conversejs converse-chat-toolbar .far:hover svg,.conversejs converse-chat-toolbar .fas svg,.conversejs converse-chat-toolbar .fas:hover svg{fill:var(--chat-head-color)}.conversejs converse-chat-toolbar .unencrypted,.conversejs converse-chat-toolbar .unencrypted a{color:var(--text-color)}.conversejs converse-chat-toolbar .unencrypted .toolbar-menu a,.conversejs converse-chat-toolbar .unencrypted a .toolbar-menu a{color:var(--link-color)}.conversejs converse-chat-toolbar button{margin-top:.4em;border:1px transparent solid;background-color:transparent}.conversejs converse-chat-toolbar button.send-button{padding-top:.2em;padding-bottom:.2em;margin:0;margin-top:-1px}.conversejs .chatbox converse-chat-toolbar{border-top:var(--chatbox-message-input-border-top);color:var(--chat-toolbar-btn-color);background-color:#fff}.conversejs .chatbox converse-chat-toolbar .fa,.conversejs .chatbox converse-chat-toolbar .fa:hover,.conversejs .chatbox converse-chat-toolbar .far,.conversejs .chatbox converse-chat-toolbar .far:hover,.conversejs .chatbox converse-chat-toolbar .fas,.conversejs .chatbox converse-chat-toolbar .fas:hover{color:var(--chat-toolbar-btn-color)}.conversejs .chatbox converse-chat-toolbar button:focus{outline-color:var(--chat-toolbar-btn-color)!important}.conversejs .chatbox converse-chat-toolbar button:disabled .fa{color:var(--chat-toolbar-btn-disabled-color)}.conversejs .chatbox converse-chat-toolbar button:disabled .fa:hover{color:var(--chat-toolbar-btn-disabled-color)}.conversejs .chatbox converse-chat-toolbar button:disabled .fa svg,.conversejs .chatbox converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--chat-toolbar-btn-disabled-color)}.conversejs .chatroom converse-chat-toolbar{border-top:var(--chatroom-message-input-border-top);color:var(--muc-toolbar-btn-color)}.conversejs .chatroom converse-chat-toolbar .fa,.conversejs .chatroom converse-chat-toolbar .fa:hover,.conversejs .chatroom converse-chat-toolbar .far,.conversejs .chatroom converse-chat-toolbar .far:hover,.conversejs .chatroom converse-chat-toolbar .fas,.conversejs .chatroom converse-chat-toolbar .fas:hover{color:var(--muc-toolbar-btn-color);font-size:var(--font-size-large)}.conversejs .chatroom converse-chat-toolbar .fa svg,.conversejs .chatroom converse-chat-toolbar .fa:hover svg,.conversejs .chatroom converse-chat-toolbar .far svg,.conversejs .chatroom converse-chat-toolbar .far:hover svg,.conversejs .chatroom converse-chat-toolbar .fas svg,.conversejs .chatroom converse-chat-toolbar .fas:hover svg{fill:var(--muc-toolbar-btn-color)}.conversejs .chatroom converse-chat-toolbar button:focus{outline-color:var(--muc-toolbar-btn-color)!important}.conversejs .chatroom converse-chat-toolbar button:disabled .fa{color:var(--muc-toolbar-btn-disabled-color)}.conversejs .chatroom converse-chat-toolbar button:disabled .fa:hover{color:var(--muc-toolbar-btn-disabled-color)}.conversejs .chatroom converse-chat-toolbar button:disabled .fa svg,.conversejs .chatroom converse-chat-toolbar button:disabled .fa svg:hover{fill:var(--muc-toolbar-btn-disabled-color)}.conversejs converse-chats.converse-overlayed .chat-toolbar li .toolbar-menu{min-width:235px}.conversejs converse-chats.converse-overlayed .chatroom .chat-toolbar li .toolbar-menu{min-width:280px} .conversejs .chatbox .chat-head{display:flex;flex-direction:row;color:#fff;font-size:100%;margin:0;padding:0;position:relative}.conversejs .chatbox .chat-head.chat-head-chatbox{background-color:var(--chat-head-color)}.conversejs .chatbox .chat-head .avatar{margin-right:.5em}.conversejs .chatbox .chat-head .show-msg-author-modal{color:#fff!important}.conversejs .chatbox .chat-head .chat-head__desc{color:var(--chat-head-color-lighten-50-percent);font-size:var(--font-size-small);margin:0;overflow:hidden;padding:.5rem 1rem .5rem 1rem;text-overflow:ellipsis;width:100%;max-height:5em}.conversejs .chatbox .chat-head .chatbox-title{padding:.75rem 1rem 0 1rem;display:flex;flex-direction:row;justify-content:space-between;width:100%}.conversejs .chatbox .chat-head .chatbox-title--no-desc{padding:.75rem 1rem}.conversejs .chatbox .chat-head .chatbox-title--row{display:flex;flex-direction:row;overflow:hidden}.conversejs .chatbox .chat-head .chatbox-title__text{overflow:hidden;text-overflow:ellipsis}.conversejs .chatbox .chat-head .chatbox-title__buttons{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;padding:0}.conversejs .chatbox .chat-head a.chatbox-btn.fa,.conversejs .chatbox .chat-head a.chatbox-btn.far,.conversejs .chatbox .chat-head a.chatbox-btn.fas,.conversejs .chatbox .chat-head a:hover.chatbox-btn.fa,.conversejs .chatbox .chat-head a:hover.chatbox-btn.far,.conversejs .chatbox .chat-head a:hover.chatbox-btn.fas,.conversejs .chatbox .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa,.conversejs .chatbox .chat-head a:not([href]):not([tabindex]).chatbox-btn.far,.conversejs .chatbox .chat-head a:not([href]):not([tabindex]).chatbox-btn.fas,.conversejs .chatbox .chat-head a:visited.chatbox-btn.fa,.conversejs .chatbox .chat-head a:visited.chatbox-btn.far,.conversejs .chatbox .chat-head a:visited.chatbox-btn.fas{color:#fff}.conversejs .chatbox .chat-head a.chatbox-btn.fa.button-on:before,.conversejs .chatbox .chat-head a.chatbox-btn.far.button-on:before,.conversejs .chatbox .chat-head a.chatbox-btn.fas.button-on:before,.conversejs .chatbox .chat-head a:hover.chatbox-btn.fa.button-on:before,.conversejs .chatbox .chat-head a:hover.chatbox-btn.far.button-on:before,.conversejs .chatbox .chat-head a:hover.chatbox-btn.fas.button-on:before,.conversejs .chatbox .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,.conversejs .chatbox .chat-head a:not([href]):not([tabindex]).chatbox-btn.far.button-on:before,.conversejs .chatbox .chat-head a:not([href]):not([tabindex]).chatbox-btn.fas.button-on:before,.conversejs .chatbox .chat-head a:visited.chatbox-btn.fa.button-on:before,.conversejs .chatbox .chat-head a:visited.chatbox-btn.far.button-on:before,.conversejs .chatbox .chat-head a:visited.chatbox-btn.fas.button-on:before{padding:.2em;background-color:var(--chat-head-text-color);color:var(--chat-head-color)}.conversejs .chatbox .chat-head .chatbox-btn{color:#fff}.conversejs .chatbox .chat-head .chatbox-btn.fa,.conversejs .chatbox .chat-head .chatbox-btn.far,.conversejs .chatbox .chat-head .chatbox-btn.fas{color:#fff}.conversejs .chatbox .chat-head .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .chat-head .chatbox-btn.button-on:before{border-radius:5%;background-color:var(--chat-head-text-color);color:var(--chat-head-color)} -#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs .chatbox .bottom-panel .chat-content-sendbutton{height:calc(100% - (var(--chat-textarea-height) + var(--send-button-height) + 2 * var(--send-button-margin)))}.conversejs .chatbox .bottom-panel .sendXMPPMessage{-moz-background-clip:padding;-webkit-background-clip:padding-box;border-bottom-radius:var(--chatbox-border-radius);background-clip:padding-box;background-color:#fff;border:0;margin:0;padding:0}@media screen and (max-height:450px){.conversejs .chatbox .bottom-panel .sendXMPPMessage{width:100%}}@media screen and (max-width:480px){.conversejs .chatbox .bottom-panel .sendXMPPMessage{width:100%}}.conversejs .chatbox .bottom-panel .sendXMPPMessage .suggestion-box__results:after{display:none}.conversejs .chatbox .bottom-panel .sendXMPPMessage .spoiler-hint{width:100%}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea:active,.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea:focus,.conversejs .chatbox .bottom-panel .sendXMPPMessage input:active,.conversejs .chatbox .bottom-panel .sendXMPPMessage input:focus{outline-color:var(--chat-head-color)}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea.correcting,.conversejs .chatbox .bottom-panel .sendXMPPMessage input.correcting{background-color:var(--chat-correcting-color)}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);border-top-left-radius:0;border-top-right-radius:0;border-bottom-radius:var(--chatbox-border-radius);padding-left:.5em;padding-right:4.5em;padding-top:.5em;padding-bottom:.5em;width:100%;border:none;min-height:var(--chat-textarea-height);margin-bottom:-4px;resize:none}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea.spoiler{height:42px} -#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.media{display:flex;align-items:flex-start}.media-body{flex:1}.conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height:450px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width:480px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}.conversejs .chatbox converse-controlbox-navback{display:none}.conversejs .chatbox .flyout{position:absolute}@media screen and (max-height:450px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-height:450px){.conversejs .chatbox .flyout{bottom:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{bottom:0}}.conversejs .chatbox .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}.conversejs .chatbox .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height:450px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}.conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}.conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-textarea-background-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0}@media screen and (max-height:450px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}.conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}.conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}.conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}.conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}.conversejs .chatbox .chat-content .chat-content__help{max-height:100%}.conversejs .chatbox .chat-content .chat-content__help converse-chat-help{border-top:1px solid var(--chat-head-color);display:block;height:100%;overflow-y:auto;padding:.5em 0}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}.conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}.conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}.conversejs .chatbox .chat-content .chat-content__notifications:before{content:" "}.conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}.conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}.conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}.conversejs .chatbox .dragresize-left,.conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}.conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}.conversejs converse-chats.converse-embedded .controlbox-head,.conversejs converse-chats.converse-overlayed .controlbox-head{padding:.5em}.conversejs converse-chats.converse-embedded .chat-head,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-overlayed .chatbox{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-embedded .chatbox .box-flyout,.conversejs converse-chats.converse-overlayed .chatbox .box-flyout{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-overlayed .box-flyout,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius)}@media screen and (max-height:450px){.conversejs converse-chats.converse-overlayed .box-flyout,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}@media screen and (max-width:480px){.conversejs converse-chats.converse-overlayed .box-flyout,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}.conversejs converse-chats.converse-overlayed .flyout{bottom:var(--overlayed-chatbox-hover-height)}.conversejs converse-chats.converse-overlayed .box-flyout{height:var(--overlayed-chat-height);min-height:calc(var(--overlayed-chat-height)/ 2)}.conversejs converse-chats.converse-overlayed .chat-head{min-height:var(--overlayed-chat-head-height)}.conversejs converse-chats.converse-overlayed .minimized-chats-flyout .chat-head{cursor:default}.conversejs converse-chats.converse-overlayed .chat-textarea{max-height:var(--overlayed-max-chat-textarea-height)}.conversejs converse-chats.converse-overlayed .chatbox .chat-body{height:calc(100% - var(--overlayed-chat-head-height))}.conversejs converse-chats.converse-overlayed .chatbox .chatbox-title{padding:.5rem .75rem 0 .75rem}.conversejs converse-chats.converse-overlayed .chatbox .chatbox-title--no-desc{padding:.5rem .75rem}@media(max-width:767.98px){.conversejs.converse-overlayed>.row{flex-direction:column}.conversejs.converse-overlayed>.row.no-gutters{margin:-1em}}.conversejs converse-chats.converse-embedded .flyout,.conversejs converse-chats.converse-fullscreen .flyout{border-radius:0;border:none;bottom:0}.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-fullscreen .chatbox{margin:0;margin-left:15px}.conversejs converse-chats.converse-embedded .chatbox .box-flyout,.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout{box-shadow:none;overflow:hidden}@media(min-width:768px){.conversejs converse-chats.converse-embedded .chatbox:not(#controlbox) .box-flyout,.conversejs converse-chats.converse-fullscreen .chatbox:not(#controlbox) .box-flyout{max-width:66.666667%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded .chatbox:not(#controlbox) .box-flyout,.conversejs converse-chats.converse-fullscreen .chatbox:not(#controlbox) .box-flyout{max-width:75%}}@media(min-width:1200px){.conversejs converse-chats.converse-embedded .chatbox:not(#controlbox) .box-flyout,.conversejs converse-chats.converse-fullscreen .chatbox:not(#controlbox) .box-flyout{max-width:83.333333%}}@media(min-width:768px){.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-fullscreen .chatbox{flex:0 0 66.6666666667%;max-width:66.6666666667%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-fullscreen .chatbox{flex:0 0 75%;max-width:75%}}@media(min-width:1200px){.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-fullscreen .chatbox{flex:0 0 83.3333333333%;max-width:83.3333333333%}}.conversejs converse-chats.converse-embedded.converse-singleton .flyout,.conversejs converse-chats.converse-fullscreen.converse-singleton .flyout{border:none!important}.conversejs converse-chats.converse-embedded.converse-singleton .chat-head,.conversejs converse-chats.converse-fullscreen.converse-singleton .chat-head{padding:.5em}.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{margin:0;position:relative;width:100%;padding-right:15px;padding-left:15px}@media(min-width:768px){.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media(min-width:1200px){.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}.conversejs converse-chats.converse-embedded .chat-head{font-size:var(--font-size-huge)}.conversejs converse-chats.converse-embedded .chatbox .box-flyout{bottom:0;height:100%;min-width:auto;width:100%}.conversejs converse-chats.converse-embedded .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}.conversejs converse-chats.converse-fullscreen .chatbox-btn{font-size:var(--fullpage-chatbox-button-size);margin:0 .3em}.conversejs converse-chats.converse-fullscreen .chat-head{font-size:var(--font-size-huge)}.conversejs converse-chats.converse-fullscreen .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout{box-shadow:none;height:var(--fullpage-chat-height);min-height:calc(var(--fullpage-chat-height)/ 2);width:var(--fullpage-chat-width);overflow:hidden}.conversejs converse-chats.converse-fullscreen .chatbox .chat-body{height:inherit;overflow:hidden;background-color:var(--chat-background-color)}.conversejs converse-chats.converse-fullscreen .chatbox .chat-title{font-size:var(--font-size-huge);line-height:var(--line-height-huge)}.conversejs converse-chats.converse-fullscreen .chatbox .sendXMPPMessage ul{width:100%}@media(max-width:767.98px){.conversejs converse-chats:not(.converse-embedded)>.row{flex-direction:row-reverse}.conversejs converse-chats:not(.converse-embedded) #converse-login-panel .converse-form{padding:3em 2em 3em}.conversejs converse-chats:not(.converse-embedded) .chatbox{width:calc(100% - 50px)}.conversejs converse-chats:not(.converse-embedded) .chatbox .row .box-flyout{left:50px;bottom:0;height:var(--fullpage-chat-height);box-shadow:none}.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout converse-controlbox-navback,.conversejs converse-chats.converse-mobile .chatbox .box-flyout converse-controlbox-navback,.conversejs converse-chats.converse-overlayed .chatbox .box-flyout converse-controlbox-navback{margin:auto 0;margin-right:1em;display:flex}.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout converse-controlbox-navback .fa-arrow-left:before,.conversejs converse-chats.converse-mobile .chatbox .box-flyout converse-controlbox-navback .fa-arrow-left:before,.conversejs converse-chats.converse-overlayed .chatbox .box-flyout converse-controlbox-navback .fa-arrow-left:before{color:var(--chat-head-text-color)}} -#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs .oauth-providers{text-align:center}.conversejs .oauth-providers .oauth-provider{margin:1em 0}.conversejs .oauth-providers .oauth-provider .oauth-login{margin-left:0;color:var(--link-color);font-size:var(--font-size-large)}.conversejs .oauth-providers .oauth-provider .oauth-login:hover{color:var(--link-hover-color)}.conversejs .oauth-providers .oauth-provider .oauth-login i{color:var(--link-color);font-size:var(--font-size-huge);margin-right:.5em}.conversejs .set-xmpp-status .chat-status--online,.conversejs .xmpp-status .chat-status--online{color:var(--chat-status-online)}.conversejs .set-xmpp-status .chat-status--busy,.conversejs .xmpp-status .chat-status--busy{color:var(--chat-status-busy)}.conversejs .set-xmpp-status .chat-status--away,.conversejs .xmpp-status .chat-status--away{color:var(--chat-status-away)}.conversejs .set-xmpp-status .fa-times-circle,.conversejs .set-xmpp-status .far.fa-circle,.conversejs .xmpp-status .fa-times-circle,.conversejs .xmpp-status .far.fa-circle{color:var(--subdued-color)}.conversejs .set-xmpp-status .chat-status{padding-right:.5em}.conversejs .room-info{font-size:var(--font-size-small);font-style:normal;font-weight:400}.conversejs .room-info li.room-info{display:block;margin-left:5px}.conversejs .room-info p.room-info{line-height:var(--line-height);margin:0;display:block;white-space:normal}.conversejs div.room-info{padding:.3em 0;clear:left;width:100%}.conversejs #controlbox{order:-1;color:var(--controlbox-text-color);margin-right:calc(3 * var(--chat-gutter))}.conversejs #controlbox converse-brand-logo{width:100%;display:block}.conversejs #controlbox converse-brand-heading{width:100%;display:block}.conversejs #controlbox .brand-name-wrapper{font-size:200%}.conversejs #controlbox .brand-name-wrapper--fullscreen{font-size:100%}.conversejs #controlbox .open-rooms-toggle,.conversejs #controlbox .open-rooms-toggle .fa{color:var(--groupchats-header-color)!important}.conversejs #controlbox .open-rooms-toggle .fa:hover,.conversejs #controlbox .open-rooms-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}.conversejs #controlbox .box-flyout{background-color:var(--controlbox-pane-background-color)}.conversejs #controlbox.logged-out .box-flyout .controlbox-pane{overflow-y:auto}.conversejs #controlbox form.search-xmpp-contact{margin:0;padding-left:5px;padding:0 0 5px 5px}.conversejs #controlbox form.search-xmpp-contact input{width:8em}.conversejs #controlbox .msgs-indicator{margin-right:.5em}.conversejs #controlbox a.subscribe-to-user{padding-left:2em;font-weight:700}.conversejs #controlbox #converse-register{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease;background-color:var(--controlbox-pane-background-color)}.conversejs #controlbox #converse-register .title{font-weight:700}.conversejs #controlbox #converse-register .info{color:green;font-size:90%;margin:1.5em 0}.conversejs #controlbox #converse-register .form-errors{color:var(--error-color);margin:1em 0}.conversejs #controlbox #converse-register .provider-title{font-size:var(--font-size-huge);margin:0}.conversejs #controlbox #converse-register .provider-score{width:178px;margin-bottom:8px}.conversejs #controlbox #converse-register .form-help .url{font-weight:700;color:var(--link-color)}.conversejs #controlbox #converse-register .input-group{display:table;margin:auto;width:100%}.conversejs #controlbox #converse-register .input-group span{overflow-x:hidden;text-overflow:ellipsis;max-width:110px}.conversejs #controlbox #converse-register .input-group input[name=username],.conversejs #controlbox #converse-register .input-group span{display:table-cell;text-align:left}.conversejs #controlbox #converse-register .instructions{color:gray;font-size:85%}.conversejs #controlbox #converse-register .instructions:hover{color:var(--controlbox-text-color)}.conversejs #controlbox .conn-feedback{color:var(--controlbox-head-color)}.conversejs #controlbox .conn-feedback.error{color:var(--error-color)}.conversejs #controlbox .conn-feedback p{padding-bottom:1em}.conversejs #controlbox .conn-feedback p.feedback-subject.error{font-weight:700}.conversejs #controlbox #converse-login-panel,.conversejs #controlbox #converse-register-panel{padding-top:0;padding-bottom:0}.conversejs #controlbox #converse-login-panel{flex-direction:row}.conversejs #controlbox .toggle-register-login{font-weight:700}.conversejs #controlbox .controlbox-pane .userinfo{padding-bottom:1em}.conversejs #controlbox .controlbox-pane .userinfo .username{margin-left:.5em;overflow:hidden;text-overflow:ellipsis}.conversejs #controlbox .controlbox-pane .userinfo .profile{margin-bottom:.75em}.conversejs #controlbox #chatrooms{padding:0}.conversejs #controlbox #chatrooms .add-chatroom{margin:0;padding:0}.conversejs #controlbox #chatrooms .add-chatroom input[type=button],.conversejs #controlbox #chatrooms .add-chatroom input[type=submit],.conversejs #controlbox #chatrooms .add-chatroom input[type=text]{width:100%}.conversejs #controlbox .controlbox-section .controlbox-heading{font-family:var(--heading-font);color:var(--controlbox-heading-color);font-weight:var(--controlbox-heading-font-weight);padding:0;font-size:1.1em;line-height:1.1em;text-transform:uppercase}.conversejs #controlbox .controlbox-section .controlbox-heading--groupchats{color:var(--groupchats-header-color)}.conversejs #controlbox .controlbox-section .controlbox-heading--contacts{color:var(--chat-head-color-dark)}.conversejs #controlbox .controlbox-section .controlbox-heading--headline{color:var(--headline-head-color)}.conversejs #controlbox .controlbox-section .controlbox-heading__btn{cursor:pointer;font-size:1em;padding:0;margin:var(--controlbox-heading-top-margin) 0 var(--inline-action-margin) 0;min-width:25px;text-align:center}.conversejs #controlbox .controlbox-section .controlbox-heading__btn.fa-vcard{margin-top:1em}.conversejs #controlbox .dropdown a{width:143px;display:inline-block}.conversejs #controlbox .dropdown li{list-style:none;padding-left:0}.conversejs #controlbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;width:100%;z-index:21;background-color:var(--light-background-color)}.conversejs #controlbox .dropdown dd ul li:hover{background-color:var(--highlight-color)}.conversejs #controlbox .dropdown dd.search-xmpp{height:0}.conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container{position:absolute;z-index:22}.conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container form{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4);background-color:#fff}.conversejs #controlbox .dropdown dd.search-xmpp li:hover{background-color:var(--light-background-color)}.conversejs #controlbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}.conversejs #controlbox .controlbox-panes{background-color:var(--controlbox-pane-background-color);border-right:.2143rem solid var(--panel-divider-color);height:100%;overflow-y:auto}.conversejs #controlbox .controlbox-subtitle{font-size:90%;padding:.5em;text-align:right}.conversejs #controlbox .controlbox-pane{background-color:var(--controlbox-pane-background-color);border:0;font-size:var(--font-size);left:0;text-align:left;overflow-x:hidden;padding:0 0 1em 0}.conversejs #controlbox .controlbox-pane .controlbox-padded{padding-left:1em;padding-right:1em;align-items:center;line-height:normal}.conversejs #controlbox .controlbox-pane .controlbox-padded .change-status{min-width:25px;text-align:center}.conversejs #controlbox .controlbox-pane .add-converse-contact{margin:0 0 .75em 0}.conversejs #controlbox .controlbox-pane .chatbox-btn{margin:0}.conversejs #controlbox .controlbox-pane .switch-form{text-align:center;padding:2em 0}.conversejs #controlbox .controlbox-pane dd{margin-left:0;margin-bottom:0}.conversejs #controlbox .controlbox-pane dd.odd{background-color:#dceac5}.conversejs #controlbox .add-xmpp-contact{padding:1em .5em}.conversejs #controlbox .add-xmpp-contact input{margin:0 0 1rem;width:100%}.conversejs #controlbox .add-xmpp-contact button{width:100%}.conversejs converse-chats.converse-overlayed{display:flex;flex-direction:row-reverse}.conversejs converse-chats.converse-overlayed .toggle-controlbox{order:-2;text-align:center;background-color:var(--link-color);border-top-left-radius:var(--button-border-radius);border-top-right-radius:var(--button-border-radius);color:#0a0a0a;float:right;height:100%;margin:0 var(--chat-gutter);padding:1em}.conversejs converse-chats.converse-overlayed .toggle-controlbox span{color:var(--inverse-link-color)}.conversejs converse-chats.converse-overlayed #controlbox{order:-1;min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}.conversejs converse-chats.converse-overlayed #controlbox .box-flyout{min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}.conversejs converse-chats.converse-overlayed #controlbox .login-trusted{white-space:nowrap;font-size:90%}.conversejs converse-chats.converse-overlayed #controlbox #converse-login-trusted{margin-top:.5em}.conversejs converse-chats.converse-overlayed #controlbox:not(.logged-out) .controlbox-head{height:15px}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-head{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;justify-content:space-between;min-height:0}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-head .brand-heading{color:var(--controlbox-text-color);font-size:2em}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-head .chatbox-btn{color:var(--controlbox-head-color);margin:0}.conversejs converse-chats.converse-overlayed #controlbox #converse-login,.conversejs converse-chats.converse-overlayed #controlbox #converse-register{flex:0 0 100%;max-width:100%;padding-bottom:0}.conversejs converse-chats.converse-overlayed #controlbox #converse-register .button-cancel{font-size:90%}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-panes{border-radius:var(--chatbox-border-radius)}.conversejs converse-chats.converse-embedded .toggle-controlbox,.conversejs converse-chats.converse-fullscreen .toggle-controlbox{display:none}.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{position:relative;width:100%;padding-right:15px;padding-left:15px;margin:0}@media(min-width:768px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 33.3333333333%;max-width:33.3333333333%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 25%;max-width:25%}}@media(min-width:1200px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 16.6666666667%;max-width:16.6666666667%}}.conversejs converse-chats.converse-embedded #controlbox.logged-out,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out,.conversejs converse-chats.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%}.conversejs converse-chats.converse-embedded #controlbox .flyout,.conversejs converse-chats.converse-fullscreen #controlbox .flyout,.conversejs converse-chats.converse-mobile #controlbox .flyout{border-radius:0}.conversejs converse-chats.converse-embedded #controlbox #converse-login-panel,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login-panel,.conversejs converse-chats.converse-mobile #controlbox #converse-login-panel{border-radius:0}.conversejs converse-chats.converse-embedded #controlbox #converse-login-panel .converse-form,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login-panel .converse-form,.conversejs converse-chats.converse-mobile #controlbox #converse-login-panel .converse-form{padding:3em 2em 3em}.conversejs converse-chats.converse-embedded #controlbox .toggle-register-login,.conversejs converse-chats.converse-fullscreen #controlbox .toggle-register-login,.conversejs converse-chats.converse-mobile #controlbox .toggle-register-login{line-height:var(--line-height-huge)}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo{flex:0 0 100%;max-width:100%;margin-top:5em;margin-bottom:1em}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-heading{width:100%;font-size:500%;padding:.7em 0 0 0;opacity:.8;color:var(--brand-heading-color)}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-subtitle,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-subtitle,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-subtitle{font-size:90%;padding:.5em}@media screen and (max-width:480px){.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-heading{font-size:300%}}.conversejs converse-chats.converse-embedded #controlbox.logged-out,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out,.conversejs converse-chats.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%;opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease;width:100%}.conversejs converse-chats.converse-embedded #controlbox.logged-out .box-flyout,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out .box-flyout,.conversejs converse-chats.converse-mobile #controlbox.logged-out .box-flyout{width:100%}.conversejs converse-chats.converse-embedded #controlbox .box-flyout,.conversejs converse-chats.converse-fullscreen #controlbox .box-flyout,.conversejs converse-chats.converse-mobile #controlbox .box-flyout{border:0;width:100%;z-index:1;background-color:var(--controlbox-head-color)}.conversejs converse-chats.converse-embedded #controlbox .box-flyout .controlbox-head,.conversejs converse-chats.converse-fullscreen #controlbox .box-flyout .controlbox-head,.conversejs converse-chats.converse-mobile #controlbox .box-flyout .controlbox-head{display:none}.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{position:relative;width:100%;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-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{flex:0 0 66.6666666667%;max-width:66.6666666667%;margin-left:16.6666666667%}}@media(min-width:768px){.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{flex:0 0 66.6666666667%;max-width:66.6666666667%;margin-left:16.6666666667%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{flex:0 0 50%;max-width:50%;margin-left:25%}}.conversejs converse-chats.converse-embedded #controlbox #converse-login .instructions,.conversejs converse-chats.converse-embedded #controlbox #converse-login .title,.conversejs converse-chats.converse-embedded #controlbox #converse-register .instructions,.conversejs converse-chats.converse-embedded #controlbox #converse-register .title,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login .instructions,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login .title,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register .instructions,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register .title,.conversejs converse-chats.converse-mobile #controlbox #converse-login .instructions,.conversejs converse-chats.converse-mobile #controlbox #converse-login .title,.conversejs converse-chats.converse-mobile #controlbox #converse-register .instructions,.conversejs converse-chats.converse-mobile #controlbox #converse-register .title{margin:1em 0}.conversejs converse-chats.converse-embedded #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-embedded #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-embedded #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-embedded #controlbox #converse-register input[type=submit],.conversejs converse-chats.converse-fullscreen #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-fullscreen #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-fullscreen #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-fullscreen #controlbox #converse-register input[type=submit],.conversejs converse-chats.converse-mobile #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-mobile #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-mobile #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-mobile #controlbox #converse-register input[type=submit]{width:auto}.conversejs converse-chats.converse-fullscreen #controlbox{margin-left:-15px}.conversejs converse-chats.converse-fullscreen .controlbox-panes{padding-top:2em}.conversejs converse-chats.converse-overlayed .brand-heading{padding-top:.8rem;padding-left:.8rem;width:100%}.conversejs converse-chats.converse-overlayed .converse-svg-logo{height:1em}.conversejs converse-chats.converse-overlayed #controlbox #converse-login-panel{height:100%}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-panes{margin-top:.5em}@media(max-width:767.98px){.conversejs{left:0;right:0;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}.conversejs .converse-chatboxes{margin:0!important;flex-direction:row!important;justify-content:space-between}.conversejs .converse-chatboxes .converse-chatroom{font-size:14px}.conversejs .converse-chatboxes .chatbox .box-flyout{margin-left:15px;left:0;bottom:0;border-radius:0;width:100vw!important;height:var(--fullpage-chat-height)}.conversejs .converse-chatboxes #controlbox{width:100vw!important}.conversejs .converse-chatboxes #controlbox .box-flyout{width:100vw!important;height:var(--fullpage-chat-height);margin-right:-15px}.conversejs .converse-chatboxes #controlbox .sidebar{display:block}.conversejs .converse-chatboxes.sidebar-open .chatbox:not(#controlbox){display:none}.conversejs .converse-chatboxes.sidebar-open #controlbox .controlbox-pane{display:block}} -body.converse-fullscreen{margin:0;background-color:var(--global-background-color)} +#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--toolbar-btn-text-color:white;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs .chatbox .bottom-panel .chat-content-sendbutton{height:calc(100% - (var(--chat-textarea-height) + var(--send-button-height) + 2 * var(--send-button-margin)))}.conversejs .chatbox .bottom-panel .sendXMPPMessage{-moz-background-clip:padding;-webkit-background-clip:padding-box;border-bottom-radius:var(--chatbox-border-radius);background-clip:padding-box;background-color:#fff;border:0;margin:0;padding:0}@media screen and (max-height:450px){.conversejs .chatbox .bottom-panel .sendXMPPMessage{width:100%}}@media screen and (max-width:480px){.conversejs .chatbox .bottom-panel .sendXMPPMessage{width:100%}}.conversejs .chatbox .bottom-panel .sendXMPPMessage .suggestion-box__results:after{display:none}.conversejs .chatbox .bottom-panel .sendXMPPMessage .spoiler-hint{width:100%}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea:active,.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea:focus,.conversejs .chatbox .bottom-panel .sendXMPPMessage input:active,.conversejs .chatbox .bottom-panel .sendXMPPMessage input:focus{outline-color:var(--chat-head-color)}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea.correcting,.conversejs .chatbox .bottom-panel .sendXMPPMessage input.correcting{background-color:var(--chat-correcting-color)}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea{color:var(--chat-textarea-color);background-color:var(--chat-textarea-background-color);border-top-left-radius:0;border-top-right-radius:0;border-bottom-radius:var(--chatbox-border-radius);padding-left:.5em;padding-right:4.5em;padding-top:.5em;padding-bottom:.5em;width:100%;border:none;min-height:var(--chat-textarea-height);margin-bottom:-4px;resize:none}.conversejs .chatbox .bottom-panel .sendXMPPMessage .chat-textarea.spoiler{height:42px} +#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--toolbar-btn-text-color:white;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.media{display:flex;align-items:flex-start}.media-body{flex:1}.conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height:450px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width:480px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}.conversejs .chatbox converse-controlbox-navback{display:none}.conversejs .chatbox .flyout{position:absolute}@media screen and (max-height:450px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-height:450px){.conversejs .chatbox .flyout{bottom:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{bottom:0}}.conversejs .chatbox .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}.conversejs .chatbox .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height:450px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}.conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}.conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-textarea-background-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0}@media screen and (max-height:450px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}.conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}.conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}.conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}.conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}.conversejs .chatbox .chat-content .chat-content__help{max-height:100%}.conversejs .chatbox .chat-content .chat-content__help converse-chat-help{border-top:1px solid var(--chat-head-color);display:block;height:100%;overflow-y:auto;padding:.5em 0}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}.conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}.conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}.conversejs .chatbox .chat-content .chat-content__notifications:before{content:" "}.conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}.conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}.conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}.conversejs .chatbox .dragresize-left,.conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}.conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}.conversejs converse-chats.converse-embedded .controlbox-head,.conversejs converse-chats.converse-overlayed .controlbox-head{padding:.5em}.conversejs converse-chats.converse-embedded .chat-head,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-overlayed .chatbox{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-embedded .chatbox .box-flyout,.conversejs converse-chats.converse-overlayed .chatbox .box-flyout{min-width:var(--overlayed-chat-width)!important;width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-overlayed .box-flyout,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius)}@media screen and (max-height:450px){.conversejs converse-chats.converse-overlayed .box-flyout,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}@media screen and (max-width:480px){.conversejs converse-chats.converse-overlayed .box-flyout,.conversejs converse-chats.converse-overlayed .chat-head{border-top-left-radius:0;border-top-right-radius:0}}.conversejs converse-chats.converse-overlayed .flyout{bottom:var(--overlayed-chatbox-hover-height)}.conversejs converse-chats.converse-overlayed .box-flyout{height:var(--overlayed-chat-height);min-height:calc(var(--overlayed-chat-height)/ 2)}.conversejs converse-chats.converse-overlayed .chat-head{min-height:var(--overlayed-chat-head-height)}.conversejs converse-chats.converse-overlayed .minimized-chats-flyout .chat-head{cursor:default}.conversejs converse-chats.converse-overlayed .chat-textarea{max-height:var(--overlayed-max-chat-textarea-height)}.conversejs converse-chats.converse-overlayed .chatbox .chat-body{height:calc(100% - var(--overlayed-chat-head-height))}.conversejs converse-chats.converse-overlayed .chatbox .chatbox-title{padding:.5rem .75rem 0 .75rem}.conversejs converse-chats.converse-overlayed .chatbox .chatbox-title--no-desc{padding:.5rem .75rem}@media(max-width:767.98px){.conversejs.converse-overlayed>.row{flex-direction:column}.conversejs.converse-overlayed>.row.no-gutters{margin:-1em}}.conversejs converse-chats.converse-embedded .flyout,.conversejs converse-chats.converse-fullscreen .flyout{border-radius:0;border:none;bottom:0}.conversejs converse-chats.converse-embedded .chatbox,.conversejs converse-chats.converse-fullscreen .chatbox{margin:0;margin-left:15px}.conversejs converse-chats.converse-embedded .chatbox .box-flyout,.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout{box-shadow:none;overflow:hidden;margin-left:0}@media(min-width:768px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox{flex:0 0 66.6666666667%;max-width:66.6666666667%}}@media(min-width:992px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox{flex:0 0 75%;max-width:75%}}@media(min-width:1200px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox{flex:0 0 83.3333333333%;max-width:83.3333333333%}}@media(min-width:768px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox:not(#controlbox) .box-flyout{max-width:66.666667%}}@media(min-width:992px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox:not(#controlbox) .box-flyout{max-width:75%}}@media(min-width:1200px){.conversejs converse-chats.converse-fullscreen:not(.converse-singleton) .chatbox:not(#controlbox) .box-flyout{max-width:83.333333%}}.conversejs converse-chats.converse-embedded .chat-head{font-size:var(--font-size-huge)}.conversejs converse-chats.converse-embedded .chatbox .box-flyout{bottom:0;height:100%;min-width:auto;width:100%}.conversejs converse-chats.converse-embedded .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}.conversejs converse-chats.converse-fullscreen .chatbox-btn{font-size:var(--fullpage-chatbox-button-size);margin:0 .3em}.conversejs converse-chats.converse-fullscreen .chat-head{font-size:var(--font-size-huge)}.conversejs converse-chats.converse-fullscreen .chat-textarea{max-height:var(--fullpage-max-chat-textarea-height)}.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout{box-shadow:none;height:var(--fullpage-chat-height);min-height:calc(var(--fullpage-chat-height)/ 2);width:var(--fullpage-chat-width);overflow:hidden}.conversejs converse-chats.converse-fullscreen .chatbox .chat-body{height:inherit;overflow:hidden;background-color:var(--chat-background-color)}.conversejs converse-chats.converse-fullscreen .chatbox .chat-title{font-size:var(--font-size-huge);line-height:var(--line-height-huge)}.conversejs converse-chats.converse-fullscreen .chatbox .sendXMPPMessage ul{width:100%}@media(max-width:767.98px){.conversejs converse-chats:not(.converse-embedded)>.row{flex-direction:row-reverse}.conversejs converse-chats:not(.converse-embedded) #converse-login-panel .converse-form{padding:3em 2em 3em}.conversejs converse-chats:not(.converse-embedded) .chatbox{width:calc(100% - 50px)}.conversejs converse-chats:not(.converse-embedded) .chatbox .row .box-flyout{left:50px;bottom:0;height:var(--fullpage-chat-height);box-shadow:none}.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout converse-controlbox-navback,.conversejs converse-chats.converse-mobile .chatbox .box-flyout converse-controlbox-navback,.conversejs converse-chats.converse-overlayed .chatbox .box-flyout converse-controlbox-navback{margin:auto 0;margin-right:1em;display:flex}.conversejs converse-chats.converse-fullscreen .chatbox .box-flyout converse-controlbox-navback .fa-arrow-left:before,.conversejs converse-chats.converse-mobile .chatbox .box-flyout converse-controlbox-navback .fa-arrow-left:before,.conversejs converse-chats.converse-overlayed .chatbox .box-flyout converse-controlbox-navback .fa-arrow-left:before{color:var(--chat-head-text-color)}} +#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--toolbar-btn-text-color:white;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs .oauth-providers{text-align:center}.conversejs .oauth-providers .oauth-provider{margin:1em 0}.conversejs .oauth-providers .oauth-provider .oauth-login{margin-left:0;color:var(--link-color);font-size:var(--font-size-large)}.conversejs .oauth-providers .oauth-provider .oauth-login:hover{color:var(--link-hover-color)}.conversejs .oauth-providers .oauth-provider .oauth-login i{color:var(--link-color);font-size:var(--font-size-huge);margin-right:.5em}.conversejs .set-xmpp-status .chat-status--online,.conversejs .xmpp-status .chat-status--online{color:var(--chat-status-online)}.conversejs .set-xmpp-status .chat-status--busy,.conversejs .xmpp-status .chat-status--busy{color:var(--chat-status-busy)}.conversejs .set-xmpp-status .chat-status--away,.conversejs .xmpp-status .chat-status--away{color:var(--chat-status-away)}.conversejs .set-xmpp-status .fa-times-circle,.conversejs .set-xmpp-status .far.fa-circle,.conversejs .xmpp-status .fa-times-circle,.conversejs .xmpp-status .far.fa-circle{color:var(--subdued-color)}.conversejs .set-xmpp-status .chat-status{padding-right:.5em}.conversejs .room-info{font-size:var(--font-size-small);font-style:normal;font-weight:400}.conversejs .room-info li.room-info{display:block;margin-left:5px}.conversejs .room-info p.room-info{line-height:var(--line-height);margin:0;display:block;white-space:normal}.conversejs div.room-info{padding:.3em 0;clear:left;width:100%}.conversejs #controlbox{order:-1;color:var(--controlbox-text-color);margin-right:calc(3 * var(--chat-gutter))}.conversejs #controlbox .chat-status--avatar{border:1px solid var(--controlbox-pane-background-color);background:var(--controlbox-pane-background-color)}.conversejs #controlbox converse-brand-logo{width:100%;display:block}.conversejs #controlbox converse-brand-heading{width:100%;display:block}.conversejs #controlbox .brand-name-wrapper{font-size:200%}.conversejs #controlbox .brand-name-wrapper--fullscreen{font-size:100%}.conversejs #controlbox .open-rooms-toggle,.conversejs #controlbox .open-rooms-toggle .fa{color:var(--groupchats-header-color)!important}.conversejs #controlbox .open-rooms-toggle .fa:hover,.conversejs #controlbox .open-rooms-toggle:hover{color:var(--chatroom-head-bg-color-dark)!important}.conversejs #controlbox .box-flyout{background-color:var(--controlbox-pane-background-color)}.conversejs #controlbox.logged-out .box-flyout .controlbox-pane{overflow-y:auto}.conversejs #controlbox form.search-xmpp-contact{margin:0;padding-left:5px;padding:0 0 5px 5px}.conversejs #controlbox form.search-xmpp-contact input{width:8em}.conversejs #controlbox .msgs-indicator{margin-right:.5em}.conversejs #controlbox a.subscribe-to-user{padding-left:2em;font-weight:700}.conversejs #controlbox #converse-register{opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease;background-color:var(--controlbox-pane-background-color)}.conversejs #controlbox #converse-register .title{font-weight:700}.conversejs #controlbox #converse-register .info{color:green;font-size:90%;margin:1.5em 0}.conversejs #controlbox #converse-register .form-errors{color:var(--error-color);margin:1em 0}.conversejs #controlbox #converse-register .provider-title{font-size:var(--font-size-huge);margin:0}.conversejs #controlbox #converse-register .provider-score{width:178px;margin-bottom:8px}.conversejs #controlbox #converse-register .form-help .url{font-weight:700;color:var(--link-color)}.conversejs #controlbox #converse-register .input-group{display:table;margin:auto;width:100%}.conversejs #controlbox #converse-register .input-group span{overflow-x:hidden;text-overflow:ellipsis;max-width:110px}.conversejs #controlbox #converse-register .input-group input[name=username],.conversejs #controlbox #converse-register .input-group span{display:table-cell;text-align:left}.conversejs #controlbox #converse-register .instructions{color:gray;font-size:85%}.conversejs #controlbox #converse-register .instructions:hover{color:var(--controlbox-text-color)}.conversejs #controlbox .conn-feedback{color:var(--controlbox-head-color)}.conversejs #controlbox .conn-feedback.error{color:var(--error-color)}.conversejs #controlbox .conn-feedback p{padding-bottom:1em}.conversejs #controlbox .conn-feedback p.feedback-subject.error{font-weight:700}.conversejs #controlbox #converse-login-panel,.conversejs #controlbox #converse-register-panel{padding-top:0;padding-bottom:0}.conversejs #controlbox #converse-login-panel{flex-direction:row}.conversejs #controlbox .toggle-register-login{font-weight:700}.conversejs #controlbox .controlbox-pane .userinfo{padding-bottom:1em}.conversejs #controlbox .controlbox-pane .userinfo .username{margin-left:.5em;overflow:hidden;text-overflow:ellipsis}.conversejs #controlbox .controlbox-pane .userinfo .profile{margin-bottom:.75em}.conversejs #controlbox #chatrooms{padding:0}.conversejs #controlbox #chatrooms .add-chatroom{margin:0;padding:0}.conversejs #controlbox #chatrooms .add-chatroom input[type=button],.conversejs #controlbox #chatrooms .add-chatroom input[type=submit],.conversejs #controlbox #chatrooms .add-chatroom input[type=text]{width:100%}.conversejs #controlbox .controlbox-section .controlbox-heading{font-family:var(--heading-font);color:var(--controlbox-heading-color);font-weight:var(--controlbox-heading-font-weight);padding:0;font-size:1.1em;line-height:1.1em;text-transform:uppercase}.conversejs #controlbox .controlbox-section .controlbox-heading--groupchats{color:var(--groupchats-header-color)}.conversejs #controlbox .controlbox-section .controlbox-heading--contacts{color:var(--chat-head-color-dark)}.conversejs #controlbox .controlbox-section .controlbox-heading--headline{color:var(--headline-head-color)}.conversejs #controlbox .controlbox-section .controlbox-heading__btn{cursor:pointer;padding:0 0 0 1em;font-size:1em;margin:var(--controlbox-heading-top-margin) 0 var(--inline-action-margin) 0;text-align:center}.conversejs #controlbox .controlbox-section .controlbox-heading__btn.fa-vcard{margin-top:1em}.conversejs #controlbox .dropdown a{width:143px;display:inline-block}.conversejs #controlbox .dropdown li{list-style:none;padding-left:0}.conversejs #controlbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;width:100%;z-index:21;background-color:var(--light-background-color)}.conversejs #controlbox .dropdown dd ul li:hover{background-color:var(--highlight-color)}.conversejs #controlbox .dropdown dd.search-xmpp{height:0}.conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container{position:absolute;z-index:22}.conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container form{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4);background-color:#fff}.conversejs #controlbox .dropdown dd.search-xmpp li:hover{background-color:var(--light-background-color)}.conversejs #controlbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}.conversejs #controlbox .controlbox-panes{background-color:var(--controlbox-pane-background-color);border-right:.2143rem solid var(--panel-divider-color);height:100%;overflow-y:auto}.conversejs #controlbox .controlbox-subtitle{font-size:90%;padding:.5em;text-align:right}.conversejs #controlbox .controlbox-pane{background-color:var(--controlbox-pane-background-color);border:0;font-size:var(--font-size);left:0;text-align:left;overflow-x:hidden;padding:0 0 1em 0}.conversejs #controlbox .controlbox-pane .controlbox-padded{padding-left:1em;padding-right:1em;align-items:center;line-height:normal}.conversejs #controlbox .controlbox-pane .controlbox-padded .change-status{min-width:25px;text-align:center}.conversejs #controlbox .controlbox-pane .add-converse-contact{margin:0 0 .75em 0}.conversejs #controlbox .controlbox-pane .chatbox-btn{margin:0}.conversejs #controlbox .controlbox-pane .switch-form{text-align:center;padding:2em 0}.conversejs #controlbox .controlbox-pane dd{margin-left:0;margin-bottom:0}.conversejs #controlbox .controlbox-pane dd.odd{background-color:#dceac5}.conversejs #controlbox .add-xmpp-contact{padding:1em .5em}.conversejs #controlbox .add-xmpp-contact input{margin:0 0 1rem;width:100%}.conversejs #controlbox .add-xmpp-contact button{width:100%}.conversejs converse-chats.converse-overlayed{display:flex;flex-direction:row-reverse}.conversejs converse-chats.converse-overlayed .toggle-controlbox{order:-2;text-align:center;background-color:var(--link-color);border-top-left-radius:var(--button-border-radius);border-top-right-radius:var(--button-border-radius);color:#0a0a0a;float:right;height:100%;margin:0 var(--chat-gutter);padding:1em}.conversejs converse-chats.converse-overlayed .toggle-controlbox span{color:var(--inverse-link-color)}.conversejs converse-chats.converse-overlayed #controlbox{order:-1;min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}.conversejs converse-chats.converse-overlayed #controlbox .box-flyout{min-width:var(--controlbox-width)!important;width:var(--controlbox-width)}@media screen and (max-width:480px){.conversejs converse-chats.converse-overlayed #controlbox{margin-left:-15px}}@media(max-width:767.98px){.conversejs converse-chats.converse-overlayed #controlbox{margin-left:-15px}}.conversejs converse-chats.converse-overlayed #controlbox .login-trusted{white-space:nowrap;font-size:90%}.conversejs converse-chats.converse-overlayed #controlbox #converse-login-trusted{margin-top:.5em}.conversejs converse-chats.converse-overlayed #controlbox:not(.logged-out) .controlbox-head{height:15px}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-head{display:flex;flex-direction:row-reverse;flex-wrap:nowrap;justify-content:space-between;min-height:0}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-head .brand-heading{color:var(--controlbox-text-color);font-size:2em}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-head .chatbox-btn{color:var(--controlbox-head-color);margin:0}.conversejs converse-chats.converse-overlayed #controlbox #converse-login,.conversejs converse-chats.converse-overlayed #controlbox #converse-register{flex:0 0 100%;max-width:100%;padding-bottom:0}.conversejs converse-chats.converse-overlayed #controlbox #converse-register .button-cancel{font-size:90%}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-panes{border-radius:var(--chatbox-border-radius)}.conversejs converse-chats.converse-overlayed .brand-heading{padding-top:.8rem;padding-left:.8rem;width:100%}.conversejs converse-chats.converse-overlayed .converse-svg-logo{height:1em}.conversejs converse-chats.converse-overlayed #controlbox #converse-login-panel{height:100%}.conversejs converse-chats.converse-overlayed #controlbox .controlbox-panes{margin-top:.5em}.conversejs converse-chats.converse-embedded .toggle-controlbox,.conversejs converse-chats.converse-fullscreen .toggle-controlbox{display:none}.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{position:relative;width:100%;padding-right:15px;padding-left:15px;margin:0}@media(min-width:768px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 33.3333333333%;max-width:33.3333333333%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 25%;max-width:25%}}@media(min-width:1200px){.conversejs converse-chats.converse-embedded #controlbox,.conversejs converse-chats.converse-fullscreen #controlbox,.conversejs converse-chats.converse-mobile #controlbox{flex:0 0 16.6666666667%;max-width:16.6666666667%}}.conversejs converse-chats.converse-embedded #controlbox.logged-out,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out,.conversejs converse-chats.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%}.conversejs converse-chats.converse-embedded #controlbox .flyout,.conversejs converse-chats.converse-fullscreen #controlbox .flyout,.conversejs converse-chats.converse-mobile #controlbox .flyout{border-radius:0}.conversejs converse-chats.converse-embedded #controlbox #converse-login-panel,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login-panel,.conversejs converse-chats.converse-mobile #controlbox #converse-login-panel{border-radius:0}.conversejs converse-chats.converse-embedded #controlbox #converse-login-panel .converse-form,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login-panel .converse-form,.conversejs converse-chats.converse-mobile #controlbox #converse-login-panel .converse-form{padding:3em 2em 3em}.conversejs converse-chats.converse-embedded #controlbox .toggle-register-login,.conversejs converse-chats.converse-fullscreen #controlbox .toggle-register-login,.conversejs converse-chats.converse-mobile #controlbox .toggle-register-login{line-height:var(--line-height-huge)}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo{flex:0 0 100%;max-width:100%;margin-top:5em;margin-bottom:1em}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-heading{width:100%;font-size:500%;padding:.7em 0 0 0;opacity:.8;color:var(--brand-heading-color)}.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-subtitle,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-subtitle,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-subtitle{font-size:90%;padding:.5em}@media screen and (max-width:480px){.conversejs converse-chats.converse-embedded #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-fullscreen #controlbox converse-brand-logo .brand-heading,.conversejs converse-chats.converse-mobile #controlbox converse-brand-logo .brand-heading{font-size:300%}}.conversejs converse-chats.converse-embedded #controlbox.logged-out,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out,.conversejs converse-chats.converse-mobile #controlbox.logged-out{flex:0 0 100%;max-width:100%;opacity:0;-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease;animation-timing-function:ease;width:100%}.conversejs converse-chats.converse-embedded #controlbox.logged-out .box-flyout,.conversejs converse-chats.converse-fullscreen #controlbox.logged-out .box-flyout,.conversejs converse-chats.converse-mobile #controlbox.logged-out .box-flyout{width:100%}.conversejs converse-chats.converse-embedded #controlbox .box-flyout,.conversejs converse-chats.converse-fullscreen #controlbox .box-flyout,.conversejs converse-chats.converse-mobile #controlbox .box-flyout{border:0;width:100%;z-index:1;background-color:var(--controlbox-head-color)}.conversejs converse-chats.converse-embedded #controlbox .box-flyout .controlbox-head,.conversejs converse-chats.converse-fullscreen #controlbox .box-flyout .controlbox-head,.conversejs converse-chats.converse-mobile #controlbox .box-flyout .controlbox-head{display:none}.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{position:relative;width:100%;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-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{flex:0 0 66.6666666667%;max-width:66.6666666667%;margin-left:16.6666666667%}}@media(min-width:768px){.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{flex:0 0 66.6666666667%;max-width:66.6666666667%;margin-left:16.6666666667%}}@media(min-width:992px){.conversejs converse-chats.converse-embedded #controlbox #converse-login,.conversejs converse-chats.converse-embedded #controlbox #converse-register,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register,.conversejs converse-chats.converse-mobile #controlbox #converse-login,.conversejs converse-chats.converse-mobile #controlbox #converse-register{flex:0 0 50%;max-width:50%;margin-left:25%}}.conversejs converse-chats.converse-embedded #controlbox #converse-login .instructions,.conversejs converse-chats.converse-embedded #controlbox #converse-login .title,.conversejs converse-chats.converse-embedded #controlbox #converse-register .instructions,.conversejs converse-chats.converse-embedded #controlbox #converse-register .title,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login .instructions,.conversejs converse-chats.converse-fullscreen #controlbox #converse-login .title,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register .instructions,.conversejs converse-chats.converse-fullscreen #controlbox #converse-register .title,.conversejs converse-chats.converse-mobile #controlbox #converse-login .instructions,.conversejs converse-chats.converse-mobile #controlbox #converse-login .title,.conversejs converse-chats.converse-mobile #controlbox #converse-register .instructions,.conversejs converse-chats.converse-mobile #controlbox #converse-register .title{margin:1em 0}.conversejs converse-chats.converse-embedded #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-embedded #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-embedded #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-embedded #controlbox #converse-register input[type=submit],.conversejs converse-chats.converse-fullscreen #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-fullscreen #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-fullscreen #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-fullscreen #controlbox #converse-register input[type=submit],.conversejs converse-chats.converse-mobile #controlbox #converse-login input[type=button],.conversejs converse-chats.converse-mobile #controlbox #converse-login input[type=submit],.conversejs converse-chats.converse-mobile #controlbox #converse-register input[type=button],.conversejs converse-chats.converse-mobile #controlbox #converse-register input[type=submit]{width:auto}.conversejs converse-chats.converse-fullscreen #controlbox{margin-left:-15px}@media screen and (max-width:480px){.conversejs converse-chats.converse-fullscreen #controlbox{margin-left:0}}@media(max-width:767.98px){.conversejs converse-chats.converse-fullscreen #controlbox{margin-left:0}}.conversejs converse-chats.converse-fullscreen .controlbox-panes{padding-top:2em}@media(max-width:767.98px){.conversejs{left:0;right:0;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}.conversejs .converse-chatboxes{margin:0!important;flex-direction:row!important;justify-content:space-between}.conversejs .converse-chatboxes .converse-chatroom{font-size:14px}.conversejs .converse-chatboxes .chatbox .box-flyout{left:0;bottom:0;border-radius:0;width:100vw!important;height:var(--fullpage-chat-height)}.conversejs .converse-chatboxes #controlbox{margin-left:0;width:100vw!important}.conversejs .converse-chatboxes #controlbox .box-flyout{width:100vw!important;height:var(--fullpage-chat-height);margin-right:-15px}.conversejs .converse-chatboxes #controlbox .sidebar{display:block}.conversejs .converse-chatboxes.sidebar-open .chatbox:not(#controlbox){display:none}.conversejs .converse-chatboxes.sidebar-open #controlbox .controlbox-pane{display:block}} +.media{display:flex;align-items:flex-start}.media-body{flex:1}#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--toolbar-btn-text-color:white;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs converse-chats.converse-embedded.converse-singleton .flyout,.conversejs converse-chats.converse-fullscreen.converse-singleton .flyout{border:none!important}.conversejs converse-chats.converse-embedded.converse-singleton .chat-head,.conversejs converse-chats.converse-fullscreen.converse-singleton .chat-head{padding:.5em}.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{margin:0;position:relative;margin-left:-15px}@media screen and (max-width:480px){.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{margin-left:0}}@media(max-width:767.98px){.conversejs converse-chats.converse-embedded.converse-singleton .chatbox,.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{margin-left:0}}.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{position:relative;width:100%;padding-right:15px;padding-left:15px}@media(min-width:768px){.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media(min-width:992px){.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}}@media(min-width:1200px){.conversejs converse-chats.converse-fullscreen.converse-singleton .chatbox{flex:0 0 100%;max-width:100%}} +body.converse-fullscreen{margin:0;background-color:var(--global-background-color);overflow:hidden} .conversejs .chat-head-headline{background-color:var(--headline-head-color)}.conversejs .chatbox.headlines .chat-head.chat-head-chatbox{background-color:var(--headline-head-color)}.conversejs .chatbox.headlines .chat-body{background-color:var(--headline-head-color)}.conversejs .chatbox.headlines .chat-body .chat-message{color:var(--headline-message-color)}.conversejs .chatbox.headlines .chat-content{height:100%}.conversejs .message.chat-msg.headline .chat-msg__body{margin-left:0}.conversejs converse-chats.converse-fullscreen .chatbox.headlines .box-flyout{background-color:var(--headline-head-color)}.conversejs converse-chats.converse-fullscreen .chatbox.headlines .chat-head.chat-head-chatbox{background-color:var(--headline-head-color)}.conversejs converse-chats.converse-fullscreen .chatbox.headlines .flyout{border-color:var(--headline-head-color)} converse-mam-placeholder .mam-placeholder{position:relative;height:2em;margin:.5em 0}converse-mam-placeholder .mam-placeholder:after,converse-mam-placeholder .mam-placeholder:before{content:"";display:block;position:absolute;left:0;right:0}converse-mam-placeholder .mam-placeholder:before{height:1em;top:1em;background:linear-gradient(-135deg,#d3d3d3 .5em,transparent 0) 0 .5em,linear-gradient(135deg,#d3d3d3 .5em,transparent 0) 0 .5em;background-position:top left;background-repeat:repeat-x;background-size:1em 1em}converse-mam-placeholder .mam-placeholder:after{height:1em;top:.75em;background:linear-gradient(-135deg,var(--chat-background-color) .5em,transparent 0) 0 .5em,linear-gradient(135deg,var(--chat-background-color) .5em,transparent 0) 0 .5em;background-position:top left;background-repeat:repeat-x;background-size:1em 1em} .conversejs converse-chats.converse-overlayed converse-minimized-chats{order:100}.conversejs converse-chats.converse-overlayed #minimized-chats{width:var(--minimized-chats-width);margin-bottom:0;border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);color:var(--inverse-link-color);margin-right:var(--chat-gutter);padding:0}.conversejs converse-chats.converse-overlayed #minimized-chats .badge{bottom:8px;border:1px solid var(--overlayed-badge-color)}.conversejs converse-chats.converse-overlayed #minimized-chats #toggle-minimized-chats{border-top-left-radius:var(--chatbox-border-radius);border-top-right-radius:var(--chatbox-border-radius);background-color:var(--link-color);padding:1em 0 0 0;text-align:center;color:#fff;white-space:nowrap;overflow-y:hidden;text-overflow:ellipsis;display:block;height:45px;width:9em}.conversejs converse-chats.converse-overlayed #minimized-chats a.restore-chat{cursor:pointer;padding:1px 0 1px 5px;color:var(--chat-head-text-color);line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs converse-chats.converse-overlayed #minimized-chats a.restore-chat:hover{text-decoration:none}.conversejs converse-chats.converse-overlayed #minimized-chats a.restore-chat:visited{color:var(--chat-head-text-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout{flex-direction:column-reverse;bottom:45px;width:var(--minimized-chats-width)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head{min-height:0;padding:.3em;border-radius:var(--chatbox-border-radius);height:35px;margin-bottom:.2em;width:100%;max-width:9em;flex-wrap:nowrap;background-color:var(--chat-head-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head-chatroom{background-color:var(--chatroom-head-bg-color)}.conversejs converse-chats.converse-overlayed #minimized-chats .minimized-chats-flyout.minimized{height:auto}.conversejs converse-chats.converse-overlayed #minimized-chats .unread-message-count{font-weight:700;background-color:#fff;border:1px solid;text-shadow:1px 1px 0 var(--text-shadow-color);color:var(--warning-color);border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}.conversejs converse-chats.converse-overlayed #minimized-chats .chat-head-message-count-hidden,.conversejs converse-chats.converse-overlayed #minimized-chats .unread-message-count-hidden{display:none} .conversejs [hidden]{display:none}.conversejs .visually-hidden{position:absolute;clip:rect(0,0,0,0)}.conversejs .form-group .suggestion-box{width:100%}.conversejs .suggestion-box{position:relative}.conversejs .suggestion-box mark{background:var(--completion-light-color)}.conversejs .suggestion-box>input{display:block}.conversejs .suggestion-box .suggestion-box__results,.conversejs .suggestion-box>ul{border-radius:.3em;border:1px solid rgba(0,0,0,.3);box-shadow:.05em .2em .6em rgba(0,0,0,.1);box-sizing:border-box;left:0;list-style:none;margin:.2em 0 0;min-width:100%;padding:0;position:absolute;right:0;text-shadow:none;z-index:2}.conversejs .suggestion-box .suggestion-box__results:before,.conversejs .suggestion-box>ul:before{content:"";position:absolute;top:-.43em;left:1em;width:0;height:0;padding:.4em;background:#fff;border:inherit;border-right:0;border-bottom:0;transform:rotate(45deg);z-index:-1}.conversejs .suggestion-box .suggestion-box__results>li,.conversejs .suggestion-box>ul>li{background:rgba(255,255,255,.9);background:linear-gradient(to bottom right,#fff,rgba(255,255,255,.9));color:var(--text-color);cursor:pointer;display:flex;overflow-x:hidden;padding:1em;position:relative;text-overflow:ellipsis}.conversejs .suggestion-box .suggestion-box__results--below{top:2em}.conversejs .suggestion-box .suggestion-box__results--above{bottom:4.5em}.conversejs .suggestion-box .suggestion-box__results--above:before{display:none}.conversejs .suggestion-box .suggestion-box__results--above:after{z-index:-1;content:"";position:absolute;bottom:-.43em;left:1em;width:0;height:0;padding:.4em;background:#fff;border:inherit;border-left:0;border-top:0;transform:rotate(45deg)}.conversejs .suggestion-box>ul:empty,.conversejs .suggestion-box>ul[hidden]{display:none}@supports(transform:scale(0)){.conversejs .suggestion-box>ul{transition:.3s cubic-bezier(.4,.2,.5,1.4);transform-origin:1.43em -.43em}.conversejs .suggestion-box>ul:empty,.conversejs .suggestion-box>ul[hidden]{opacity:0;transform:scale(0);display:block;transition-timing-function:ease}}.conversejs .suggestion-box>ul>li[aria-selected=true]{background:var(--completion-dark-color);color:var(--inverse-link-color)}.conversejs .suggestion-box li:hover mark{background:var(--completion-light-color);color:var(--inverse-link-color)}.conversejs .suggestion-box li[aria-selected=true] mark{background:var(--completion-normal-color);color:inherit}.conversejs.converse-fullscreen .suggestion-box__results--above{bottom:4.5em}.conversejs.converse-overlayed .suggestion-box__results--above{bottom:3.5em} .conversejs converse-muc.chatroom converse-muc-bottom-panel{display:contents;height:3em;padding:.5em;text-align:center;font-size:var(--font-size-small);background-color:var(--chatroom-head-bg-color);color:#fff}.conversejs converse-muc.chatroom converse-muc-bottom-panel.muc-bottom-panel--muted{height:4em;width:100%}.conversejs converse-muc.chatroom converse-muc-bottom-panel.muc-bottom-panel--nickname{padding:0;height:16em}.conversejs converse-muc.chatroom converse-muc-bottom-panel.muc-bottom-panel--nickname .muc-form-container .chatroom-form{padding-top:2em;padding-bottom:0}.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage .suggestion-box__results--above{bottom:4.5em}.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage .chat-textarea:active,.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage .chat-textarea:focus,.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage input:active,.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage input:focus{outline-color:var(--chatroom-head-bg-color)!important}.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage .chat-textarea.correcting,.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage input.correcting{background-color:var(--chatroom-correcting-color)}.conversejs converse-muc.chatroom converse-muc-bottom-panel .sendXMPPMessage .chat-textarea{width:100%;border:none;border-bottom-right-radius:0} -.conversejs converse-muc.chatroom .box-flyout .occupants{display:flex;flex-direction:column;justify-content:space-between;overflow-x:hidden;overflow-y:hidden;vertical-align:top;background-color:var(--occupants-background-color);border-left:var(--occupants-border-left);padding:.5em;max-width:75%;min-width:20%;flex:0 0 25%}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header{display:flex;flex-direction:column}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header .hide-occupants{align-self:flex-end;cursor:pointer;font-size:var(--font-size-small)}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header--title{margin-top:.5em;margin-bottom:.5em;display:flex;flex-direction:row}.conversejs converse-muc.chatroom .box-flyout .occupants .fa-user-plus{margin-right:.25em}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-heading{font-family:var(--heading-font);color:var(--groupchats-header-color-dark);padding-left:0;margin-right:1em}.conversejs converse-muc.chatroom .box-flyout .occupants .suggestion-box ul{padding:0}.conversejs converse-muc.chatroom .box-flyout .occupants .suggestion-box ul li{padding:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul{padding:0;margin-bottom:.5em;overflow-x:hidden;overflow-y:auto;list-style:none}.conversejs converse-muc.chatroom .box-flyout .occupants ul.occupant-list{overflow-y:auto;flex-basis:0;flex-grow:1}.conversejs converse-muc.chatroom .box-flyout .occupants ul li{cursor:default;display:block;font-size:var(--font-size-small);overflow:hidden;padding:.25em .25em .25em 0;text-overflow:ellipsis}.conversejs converse-muc.chatroom .box-flyout .occupants ul li .fa{margin-right:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.feature{font-size:var(--font-size-tiny)}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant{cursor:pointer}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge{display:flex;justify-content:space-between;flex-wrap:wrap}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge .occupant-badges{display:flex;justify-content:flex-end;flex-wrap:wrap;flex-direction:row}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge .occupant-badges span{margin-right:.25rem}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant div.row.no-gutters{flex-wrap:nowrap;min-height:1.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .badge{margin-bottom:.125rem}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-status{display:inline-block;margin:0 .5em .125em 0;width:.5em;height:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-status.occupant-chat,.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-status.occupant-online{background-color:#1a9707}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-status.occupant-dnd{background-color:red}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-status.occupant-away{background-color:#ff8c00}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-status.occupant-xa{background-color:orange}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-status.occupant-offline{background-color:#a9a9a9} +.conversejs .chat-status{vertical-align:middle;margin-right:0;border-radius:50%;font-size:1em}.conversejs .chat-status.chat-status--avatar{font-size:.6rem;margin-left:-.7em;margin-bottom:-1.9em;border-radius:50%}.conversejs .chat-status--offline{margin-right:.8em}.conversejs .chat-status--online{color:var(--chat-status-online)}.conversejs .chat-status--busy{color:var(--chat-status-busy)}.conversejs .chat-status--away{color:var(--chat-status-away)}.conversejs .chat-status--offline{display:none}.conversejs .fa-times-circle,.conversejs .far.fa-circle{color:var(--subdued-color)} +.conversejs converse-muc.chatroom .chat-status--avatar{background:var(--occupants-background-color);border:1px solid var(--occupants-background-color)}.conversejs converse-muc.chatroom .badge-groupchat{background-color:var(--groupchats-header-color)}.conversejs converse-muc.chatroom .box-flyout .occupants{display:flex;flex-direction:column;justify-content:space-between;overflow-x:hidden;overflow-y:hidden;vertical-align:top;background-color:var(--occupants-background-color);border-left:var(--occupants-border-left);padding:.5em;max-width:75%;min-width:20%;flex:0 0 25%}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header{display:flex;flex-direction:column}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header .hide-occupants{align-self:flex-end;cursor:pointer;font-size:var(--font-size-small)}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-header--title{margin-top:.5em;margin-bottom:.5em;display:flex;flex-direction:row}.conversejs converse-muc.chatroom .box-flyout .occupants .fa-user-plus{margin-right:.25em}.conversejs converse-muc.chatroom .box-flyout .occupants .occupants-heading{font-family:var(--heading-font);color:var(--groupchats-header-color-dark);padding-left:0;margin-right:1em}.conversejs converse-muc.chatroom .box-flyout .occupants .suggestion-box ul{padding:0}.conversejs converse-muc.chatroom .box-flyout .occupants .suggestion-box ul li{padding:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul{padding:0;margin-bottom:.5em;overflow-x:hidden;overflow-y:auto;list-style:none}.conversejs converse-muc.chatroom .box-flyout .occupants ul.occupant-list{overflow-y:auto;flex-basis:0;flex-grow:1}.conversejs converse-muc.chatroom .box-flyout .occupants ul li{cursor:default;display:block;font-size:var(--font-size-small);overflow:hidden;padding:.25em .25em .25em 0;text-overflow:ellipsis}.conversejs converse-muc.chatroom .box-flyout .occupants ul li .fa{margin-right:.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.feature{font-size:var(--font-size-tiny)}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant{cursor:pointer}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge{display:flex;justify-content:space-between;flex-wrap:wrap}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge .occupant-badges{display:flex;justify-content:flex-end;flex-wrap:wrap;flex-direction:row}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .occupant-nick-badge .occupant-badges span{height:1.6em;margin-right:.25rem}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant div.row.no-gutters{flex-wrap:nowrap;min-height:1.5em}.conversejs converse-muc.chatroom .box-flyout .occupants ul li.occupant .badge{margin-bottom:.125rem} +converse-rich-text{display:block}.reason converse-rich-text{display:inline-block} .conversejs converse-muc.chatroom .chat-head-chatroom{color:var(--chatroom-head-color);background-color:var(--chatroom-head-bg-color);border-bottom:var(--chatroom-head-border-bottom)}.conversejs converse-muc.chatroom .chat-head-chatroom .chat-head__desc{color:var(--chatroom-head-color);display:var(--chatroom-head-description-display)}.conversejs converse-muc.chatroom .chat-head-chatroom .chat-head__desc a{color:var(--chatroom-head-description-link-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chat-head__desc:hover button{display:inline-block}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title .btn--transparent i{color:var(--chatroom-head-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title .chatbox-title__text--bookmarked{margin-left:.5em;color:var(--chatroom-head-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title__buttons{background-color:var(--chatroom-head-bg-color)}.conversejs converse-muc.chatroom .chat-head-chatroom a.chatbox-btn.fa,.conversejs converse-muc.chatroom .chat-head-chatroom a:hover.chatbox-btn.fa,.conversejs converse-muc.chatroom .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa,.conversejs converse-muc.chatroom .chat-head-chatroom a:visited.chatbox-btn.fa{color:var(--chat-head-text-color)}.conversejs converse-muc.chatroom .chat-head-chatroom a.chatbox-btn.fa.button-on:before,.conversejs converse-muc.chatroom .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before,.conversejs converse-muc.chatroom .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,.conversejs converse-muc.chatroom .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before{color:var(--chatroom-head-button-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-btn.button-on:before{color:var(--chatroom-head-button-color)}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title__text{display:var(--heading-display);font-weight:var(--chatroom-head-title-font-weight);margin:auto 0;padding-right:var(--chatroom-head-title-padding-right);white-space:nowrap}.conversejs converse-muc.chatroom .chat-head-chatroom .chatbox-title__text .chatroom-jid{font-size:var(--font-size-small)} -#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--avatar-border:1px solid lightgrey;--avatar-background-color:white;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--avatar-border:0px;--avatar-background-color:none;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height:450px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width:480px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}.conversejs .chatbox converse-controlbox-navback{display:none}.conversejs .chatbox .flyout{position:absolute}@media screen and (max-height:450px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-height:450px){.conversejs .chatbox .flyout{bottom:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{bottom:0}}.conversejs .chatbox .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}.conversejs .chatbox .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height:450px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}.conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}.conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-textarea-background-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0}@media screen and (max-height:450px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}.conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}.conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}.conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}.conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}.conversejs .chatbox .chat-content .chat-content__help{max-height:100%}.conversejs .chatbox .chat-content .chat-content__help converse-chat-help{border-top:1px solid var(--chat-head-color);display:block;height:100%;overflow-y:auto;padding:.5em 0}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}.conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}.conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}.conversejs .chatbox .chat-content .chat-content__notifications:before{content:" "}.conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}.conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}.conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}.conversejs .chatbox .dragresize-left,.conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}.conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}converse-muc-config-form{width:100%;overflow:auto}.conversejs .chatroom .box-flyout .muc-form-container{background-color:#fff;border:0;color:var(--text-color);font-size:var(--font-size);height:100%;width:100%;overflow-y:auto}.conversejs .chatroom .box-flyout .muc-form-container .validation-message{font-size:90%;color:var(--error-color)}.conversejs .chatroom .box-flyout .muc-form-container input[type=button],.conversejs .chatroom .box-flyout .muc-form-container input[type=submit]{margin:0 .5em}.conversejs .chatroom .box-flyout .muc-form-container .button-primary{background-color:var(--chatroom-head-button-color)}.conversejs .chatroom .box-flyout .chatroom-form{display:flex;flex-direction:column;justify-content:center;padding:2em}.conversejs .chatroom{width:var(--chatroom-width)}@media screen and (max-height:450px){.conversejs .chatroom{width:var(--mobile-chat-width)}}@media screen and (max-width:480px){.conversejs .chatroom{width:var(--mobile-chat-width)}}.conversejs .chatroom .box-flyout{background-color:var(--chatroom-head-bg-color);overflow-y:hidden;width:var(--chatroom-width)}@media screen and (max-height:450px){.conversejs .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){.conversejs .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatroom .box-flyout .empty-history-feedback{position:relative}.conversejs .chatroom .box-flyout .empty-history-feedback span{width:100%;text-align:center;position:absolute;margin-top:50%}.conversejs .chatroom .box-flyout .chatroom-body{flex-direction:row;flex-flow:nowrap;background-color:#fff;border-top:0;height:100%;width:100%;overflow:hidden}.conversejs .chatroom .box-flyout .chatroom-body converse-muc-chatarea{width:100%;display:flex;flex-direction:row;flex-flow:nowrap}.conversejs .chatroom .box-flyout .chatroom-body .row{flex-direction:row}.conversejs .chatroom .box-flyout .chatroom-body .chat-topic{font-weight:700;color:var(--chatroom-head-bg-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-info{color:var(--chat-info-color);line-height:normal}.conversejs .chatroom .box-flyout .chatroom-body .chat-info.badge{color:var(--chat-head-text-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-info.chat-msg--retracted{color:var(--subdued-color)}.conversejs .chatroom .box-flyout .chatroom-body .disconnect-container{margin:1em;width:100%}.conversejs .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg{padding-bottom:1em}.conversejs .chatroom .box-flyout .chatroom-body .chat-area{display:flex;flex-direction:column;flex:0 1 100%;justify-content:flex-end;min-width:25%;word-wrap:break-word}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator{background-color:var(--chatroom-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content{height:100%}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help converse-chat-help{border-top:1px solid var(--chatroom-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help .close-chat-help svg{fill:var(--chatroom-color)}.conversejs .chatroom .room-invite .invited-contact{margin:-1px 0 0 -1px;width:100%;border:1px solid #999}#muc-details-modal .features-list{margin-left:1em}#muc-details-modal .chatroom-features{width:100%}#muc-details-modal .chatroom-features .features-list{padding-top:0}#muc-details-modal .chatroom-features .features-list .feature{width:100%;margin-right:.5em;padding-right:0;font-size:1em;cursor:help}#muc-details-modal .chatroom-features .features-list .feature .fa{margin-right:.5em;color:var(--text-color)}converse-muc-destroyed,converse-muc-disconnected{padding:2em;width:100%;height:100%}.conversejs .badge--muc,.conversejs.converse-embedded .badge--muc{background-color:var(--groupchats-header-color)}.conversejs .add-chatroom input[type=button],.conversejs .add-chatroom input[type=submit],.conversejs.converse-embedded .add-chatroom input[type=button],.conversejs.converse-embedded .add-chatroom input[type=submit]{margin:.3em 0}.conversejs converse-chats.converse-overlayed .chatbox.chatroom{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .box-flyout{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatbox-title__text{flex:0 0 58.3333333333%;max-width:58.3333333333%}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatbox-title__buttons{flex:0 0 41.6666666667%;max-width:41.6666666667%}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chat-head__desc{font-size:80%;margin-bottom:1em}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupants-heading{padding:0}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupant-list{border-bottom:none}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-nick-badge .occupant-badges{display:none}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-status{margin-top:6px}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .chat-area{min-width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout,.conversejs converse-chats.converse-mobile .chatroom .box-flyout{width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator{max-width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants{padding:var(--occupants-padding)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{font-size:var(--font-size-large)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li{font-size:var(--font-size-small)}.conversejs converse-chats.converse-embedded .chatroom .room-invite span .invited-contact,.conversejs converse-chats.converse-fullscreen .chatroom .room-invite span .invited-contact,.conversejs converse-chats.converse-mobile .chatroom .room-invite span .invited-contact{margin:0 0 .5em -1px}.conversejs converse-chats.converse-embedded .chatroom{margin:0;width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .occupants-heading{font-size:120%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chat-content .chat-message{margin:.5em;font-size:120%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .sendXMPPMessage .chat-textarea{padding:.5em;font-size:110%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body{height:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .muc-form-container{height:100%;position:relative}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .occupants .occupant-list{padding-left:.3em} -.conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:0;height:var(--roster-height);padding:0;overflow:hidden;height:calc(100% - 70px)}.conversejs #converse-roster #online-count{display:none}.conversejs #converse-roster .search-xmpp ul li.chat-info{padding-left:10px}.conversejs #converse-roster .roster-filter-form{width:100%}.conversejs #converse-roster .roster-filter-form .button-group{padding:.2em}.conversejs #converse-roster .roster-filter-form span{padding:.3em;cursor:pointer;min-width:25px;text-align:center}.conversejs #converse-roster .roster-filter-form .roster-filter{width:100%;margin:.2em;font-size:calc(var(--font-size) - 2px)}.conversejs #converse-roster .roster-filter-form .state-type{font-size:calc(var(--font-size) - 2px);width:100%}.conversejs #converse-roster .roster-contacts{padding:0;margin:0 0 .2em 0;height:100%;overflow-x:hidden;overflow-y:auto;color:var(--text-color)}.conversejs #converse-roster .roster-contacts converse-roster-contact{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:flex;justify-content:space-between}.conversejs #converse-roster .roster-contacts .group-toggle{font-family:var(--heading-font);display:block;width:100%;margin:.75em 0 .25em 0}.conversejs #converse-roster .roster-contacts .group-toggle,.conversejs #converse-roster .roster-contacts .group-toggle .fa{color:var(--chat-head-color-dark)!important}.conversejs #converse-roster .roster-contacts .group-toggle .fa:hover,.conversejs #converse-roster .roster-contacts .group-toggle:hover{color:var(--chat-head-color-darker)!important}.conversejs #converse-roster .roster-contacts .current-xmpp-contact{margin:.25em 0}.conversejs #converse-roster .roster-contacts .current-xmpp-contact .chat-status{vertical-align:middle;font-size:.6em;margin-right:0;margin-left:-.7em;margin-bottom:-1.5em;border-radius:50%;border:2px solid var(--occupants-background-color)}.conversejs #converse-roster .roster-contacts .current-xmpp-contact .chat-status--offline{margin-right:.8em}.conversejs #converse-roster .roster-contacts .current-xmpp-contact .chat-status--online{color:var(--chat-status-online)}.conversejs #converse-roster .roster-contacts .current-xmpp-contact .chat-status--busy{color:var(--chat-status-busy)}.conversejs #converse-roster .roster-contacts .current-xmpp-contact .chat-status--away{color:var(--chat-status-away)}.conversejs #converse-roster .roster-contacts .current-xmpp-contact .chat-status--offline{display:none}.conversejs #converse-roster .roster-contacts .current-xmpp-contact .fa-times-circle,.conversejs #converse-roster .roster-contacts .current-xmpp-contact .far.fa-circle{color:var(--subdued-color)}.conversejs #converse-roster .roster-contacts li.requesting-xmpp-contact a{line-height:var(--line-height)}.conversejs #converse-roster .roster-contacts li.requesting-xmpp-contact .req-contact-name{padding:0 .2em 0 0}.conversejs #converse-roster .roster-contacts li .open-chat{margin:0;padding:0}.conversejs #converse-roster .roster-contacts li .open-chat.unread-msgs{font-weight:700}.conversejs #converse-roster .roster-contacts li .open-chat.unread-msgs .contact-name{width:70%}.conversejs #converse-roster .roster-contacts li .open-chat .msgs-indicator{color:#fff;background-color:var(--chat-head-color);opacity:1;border-radius:10%;padding:.2em .4em;font-size:var(--font-size-small);margin-right:0}.conversejs #converse-roster .roster-contacts li .open-chat .contact-name{padding:0;margin:0;max-width:85%;float:none;height:100%}.conversejs #converse-roster .roster-contacts li .open-chat .contact-name.unread-msgs{max-width:60%}.conversejs #converse-roster .roster-contacts li .open-chat .contact-name.contact-name--offline{margin-left:.25em}.conversejs #converse-roster .roster-contacts li.odd{background-color:#dceac5}.conversejs #converse-roster .roster-contacts li a,.conversejs #converse-roster .roster-contacts li span{white-space:nowrap;text-overflow:ellipsis}.conversejs #converse-roster .roster-contacts li .span{display:inline-block}.conversejs #converse-roster .roster-contacts li .decline-xmpp-request{margin-left:5px}.conversejs #converse-roster .roster-contacts li:hover{background-color:var(controlbox-pane-bg-hover-color)}.conversejs #converse-roster span.pending-contact-name{line-height:var(--line-height);width:100%} +converse-muc-nickname-form{width:100%} +#conversejs-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--toolbar-btn-text-color:white;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.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-bg,.conversejs,.conversejs-bg,body.converse-fullscreen{--subdued-color:#A8ABA1;--green:#3AA569;--redder-orange:#E77051;--orange:#E7A151;--light-blue:#578EA9;--lighter-blue:#85B47B;--chat-status-online:var(--green);--chat-status-busy:var(--redder-orange);--chat-status-away:var(--orange);--brand-heading-color:#387592;--completion-light-color:#FFB9A7;--completion-normal-color:var(--redder-orange);--completion-dark-color:#D24E2B;--link-color:var(--light-blue);--link-hover-color:#345566;--link-color-lighten-10-percent:#79a5ba;--dark-link-color:#206485;--global-background-color:#397491;--inverse-link-color:white;--text-shadow-color:#FAFAFA;--text-color:#666;--controlbox-text-color:#666;--text-color-lighten-15-percent:#8c8c8c;--message-text-color:#555;--message-receipt-color:var(--green);--save-button-color:var(--green);--button-text-color:white;--message-avatar-width:36px;--message-avatar-height:36px;--chat-background-color:white;--chat-textarea-color:#666;--chat-textarea-background-color:white;--chat-textarea-height:60px;--send-button-height:27px;--send-button-margin:3px;--inline-action-margin:0.75em;--roster-height:194px;--chat-correcting-color:var(--chat-head-color-lighten-50-percent);--chat-head-color-dark:#1E9652;--chat-head-color-darker:#0E763B;--chat-head-color-lighten-50-percent:#e7f7ee;--chat-head-color:var(--green);--chat-head-text-color:white;--chat-toolbar-btn-color:var(--green);--chat-toolbar-btn-disabled-color:gray;--toolbar-btn-text-color:white;--chat-content-background-color:white;--chat-info-color:var(--chatroom-head-bg-color);--highlight-color:#DCF9F6;--highlight-color-darker:#B0E8E2;--primary-color:var(--light-blue);--primary-color-dark:#397491;--secondary-color:#818479;--secondary-color-dark:#585B51;--warning-color:var(--orange);--warning-color-dark:#D2842B;--danger-color:#D24E2B;--danger-color-dark:#A93415;--light-background-color:#FCFDFD;--error-color:#D24E2B;--info-color:#1E9652;--button-border-radius:5px;--chatbox-border-radius:4px;--groupchats-header-color:var(--chatroom-head-bg-color);--groupchats-header-color-dark:var(--chatroom-head-bg-color-dark);--controlbox-width:250px;--controlbox-head-color:var(--light-blue);--controlbox-heading-color:inherit;--controlbox-heading-font-weight:bold;--controlbox-heading-top-margin:0.75em;--controlbox-pane-background-color:white;--controlbox-pane-bg-hover-color:#eff4f7;--panel-divider-color:#e7e7e7;--chat-gutter:0.5em;--minimized-chats-width:130px;--mobile-chat-width:100%;--mobile-chat-height:400px;--normal-font:"Helvetica","Arial",sans-serif;--heading-font:"Muli",normal;--branding-font:"Baumans",cursive;--heading-display:block;--heading-color:white;--chatroom-color:var(--redder-orange);--chatroom-badge-color:var(--chatroom-head-bg-color);--chatroom-badge-hover-color:var(--chatroom-head-bg-color-dark);--chatroom-correcting-color:#fadfd7;--chatroom-head-bg-color-dark:#D24E2B;--chatroom-head-bg-color:var(--redder-orange);--chatroom-head-border-bottom:0px;--chatroom-head-button-color:var(--chatroom-head-bg-color);--chatroom-head-color:white;--chatroom-head-description-display:block;--chatroom-head-description-link-color:white;--chatroom-head-title-font-weight:normal;--chatroom-head-title-padding-right:0px;--chatroom-width:500px;--muc-toolbar-btn-color:var(--redder-orange);--muc-toolbar-btn-disabled-color:gray;--headline-head-color:var(--orange);--headline-message-color:#D2842B;--chatbox-button-size:14px;--fullpage-chatbox-button-size:16px;--font-size-tiny:10px;--font-size-small:12px;--font-size:14px;--font-size-large:16px;--font-size-huge:20px;--message-font-size:var(--font-size);--separator-text-color:var(--message-text-color);--chat-separator-border-bottom:2px solid var(--chat-head-color);--chatroom-separator-border-bottom:2px solid var(--chatroom-head-bg-color);--chatbox-message-input-border-top:4px solid var(--chat-head-color);--chatroom-message-input-border-top:4px solid var(--chatroom-head-bg-color);--line-height-small:14px;--line-height:16px;--line-height-large:20px;--line-height-huge:27px;--occupants-padding:1em;--occupants-background-color:white;--occupants-border-left:0.2143rem solid var(--panel-divider-color);--occupants-border-bottom:1px solid lightgrey;--embedded-emoji-picker-height:300px;--avatar-border-radius:10%;--fullpage-chat-height:calc(var(--vh, 1vh) * 100);--fullpage-chat-width:100%;--fullpage-emoji-picker-height:300px;--fullpage-max-chat-textarea-height:15em;--overlayed-chat-head-height:55px;--overlayed-chat-height:450px;--overlayed-chat-width:300px;--overlayed-chatbox-hover-height:1em;--overlayed-emoji-picker-height:200px;--overlayed-max-chat-textarea-height:200px;--overlayed-badge-color:#818479;--list-toggle-color:#818479;--list-toggle-hover-color:#585B51;--list-toggle-font-weight:normal;--list-item-hover-color:rgba(0, 0, 0, 0.035);--list-item-action-color:#e3eef3;--list-item-link-color:inherit;--list-item-link-hover-color:var(--dark-link-color);--list-item-open-color:var(--controlbox-head-color);--list-item-open-hover-color:var(--controlbox-head-color);--list-dot-circle-color:#f6dec1}.conversejs.theme-concord{--avatar-border-radius:10%;--controlbox-pane-background-color:#333;--panel-divider-color:#333;--controlbox-pane-bg-hover-color:#464646;--controlbox-heading-color:#777;--controlbox-heading-font-weight:bold;--groupchats-header-color:var(--redder-orange);--chat-textarea-background-color:#F6F6F6;--chat-correcting-color:#FFFFC0;--controlbox-text-color:#DDD;--chat-info-color:var(--subdued-color);--chatbox-border-radius:0px;--heading-display:inline;--heading-color:#9B4D;--link-hover-color:var(--lighter-blue);--chatroom-badge-color:var(--redder-orange);--chatroom-badge-hover-color:#D24E2B;--chatroom-correcting-color:#FFFFC0;--chatroom-head-bg-color:white;--chatroom-head-border-bottom:1px solid #EEE;--chatroom-head-button-color:#999;--chatroom-head-color:#7E7E7E;--chatroom-head-description-border-left:1px solid #DDD;--chatroom-head-description-color:black;--chatroom-head-description-display:inline;--chatroom-head-description-link-color:#00b3f4;--chatroom-head-description-padding-left:12px;--chatroom-head-title-font-weight:bold;--chatroom-head-title-padding-right:12px;--muc-toolbar-btn-color:#7E7E7E;--muc-toolbar-btn-disabled-color:lightgray;--occupants-background-color:#F3F3F3;--occupants-border-left:0px;--occupants-border-bottom:0px;--separator-text-color:#AAA;--chat-separator-border-bottom:1px solid #AAA;--chatroom-separator-border-bottom:1px solid #AAA;--chatroom-message-input-border-top:1px solid #CCC;--chatbox-message-input-border-top:1px solid #CCC;--fullpage-chatbox-button-size:24px;--list-toggle-font-weight:bold;--list-item-link-color:#F1F1F1;--list-item-link-hover-color:#DDD;--list-item-open-color:#444;--list-item-open-hover-color:#444}.conversejs .chatbox{text-align:left;margin:0 var(--chat-gutter)}@media screen and (max-height:450px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}@media screen and (max-width:480px){.conversejs .chatbox{margin:0;width:var(--mobile-chat-width)}}.conversejs .chatbox converse-controlbox-navback{display:none}.conversejs .chatbox .flyout{position:absolute}@media screen and (max-height:450px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{border-radius:0}}@media screen and (max-height:450px){.conversejs .chatbox .flyout{bottom:0}}@media screen and (max-width:480px){.conversejs .chatbox .flyout{bottom:0}}.conversejs .chatbox .chatbox-btn{border-radius:25%;border:none;cursor:pointer;font-size:var(--chatbox-button-size);margin:0 .2em;padding:0 0 0 .5em;text-decoration:none}.conversejs .chatbox .chatbox-btn:active{position:relative;top:1px}.conversejs .chatbox .box-flyout{display:flex;flex-direction:column;justify-content:space-between;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);z-index:2;overflow:hidden;width:100%}@media screen and (max-height:450px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){.conversejs .chatbox .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatbox .chat-title{display:var(--heading-display);font-family:var(--heading-font);color:var(--heading-color);display:block;line-height:var(--line-height-large);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conversejs .chatbox .chat-title.groupchat{padding-right:var(--chatroom-head-title-padding-right)}.conversejs .chatbox .chat-title a{color:var(--chat-head-text-color);width:100%}.conversejs .chatbox .chat-body{display:flex;flex-direction:column;justify-content:space-between;background-color:var(--chat-textarea-background-color);border-bottom-left-radius:var(--chatbox-border-radius);border-bottom-right-radius:var(--chatbox-border-radius);border-top:0}@media screen and (max-height:450px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}@media screen and (max-width:480px){.conversejs .chatbox .chat-body{border-bottom-left-radius:0;border-bottom-right-radius:0}}.conversejs .chatbox .chat-body p{color:var(--text-color);font-size:var(--message-font-size);margin:0;padding:5px}.conversejs .chatbox .new-msgs-indicator{position:relative;width:100%;cursor:pointer;background-color:var(--chat-head-color);color:var(--light-background-color);padding:.5em;font-size:.9em;text-align:center;z-index:20;white-space:nowrap;margin-bottom:.25em}.conversejs .chatbox .chat-content{background-color:var(--chat-content-background-color);border:0;color:var(--text-color);font-size:var(--message-font-size);height:100%;line-height:1.3em;overflow:hidden;padding:0;display:flex;flex-direction:column;justify-content:space-between}.conversejs .chatbox .chat-content converse-chat-message .spinner{width:100%;overflow-y:hidden}.conversejs .chatbox .chat-content .chat-content__help{max-height:100%}.conversejs .chatbox .chat-content .chat-content__help converse-chat-help{border-top:1px solid var(--chat-head-color);display:block;height:100%;overflow-y:auto;padding:.5em 0}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help{float:right;padding-right:1em;cursor:pointer;color:var(--chat-content-background-color)}.conversejs .chatbox .chat-content .chat-content__help .close-chat-help svg{fill:var(--chat-head-color)}.conversejs .chatbox .chat-content .chat-content__messages{overflow-x:hidden;overflow-y:auto;height:100%}.conversejs .chatbox .chat-content .chat-content__notifications{height:1.7em;white-space:pre;background-color:var(--chat-content-background-color);color:var(--subdued-color);font-size:90%;font-style:italic;line-height:var(--line-height-small);padding:0 1em .3em}.conversejs .chatbox .chat-content .chat-content__notifications:before{content:" "}.conversejs .chatbox .chat-content progress{margin:.5em 0;width:100%}.conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}.conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}.conversejs .chatbox .dragresize-left,.conversejs .chatbox .dragresize-occupants-left{cursor:w-resize;width:5px;height:100%;left:0}.conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}converse-muc-config-form{width:100%;overflow:auto}.conversejs .chatroom .box-flyout .muc-form-container{background-color:#fff;border:0;color:var(--text-color);font-size:var(--font-size);height:100%;width:100%;overflow-y:auto}.conversejs .chatroom .box-flyout .muc-form-container .validation-message{font-size:90%;color:var(--error-color)}.conversejs .chatroom .box-flyout .muc-form-container input[type=button],.conversejs .chatroom .box-flyout .muc-form-container input[type=submit]{margin:0 .5em}.conversejs .chatroom .box-flyout .muc-form-container .button-primary{background-color:var(--chatroom-head-button-color)}.conversejs .chatroom .box-flyout .chatroom-form{display:flex;flex-direction:column;justify-content:center;padding:2em}.conversejs .chatroom{width:var(--chatroom-width)}@media screen and (max-height:450px){.conversejs .chatroom{width:var(--mobile-chat-width)}}@media screen and (max-width:480px){.conversejs .chatroom{width:var(--mobile-chat-width)}}.conversejs .chatroom .box-flyout{background-color:var(--chatroom-head-bg-color);overflow-y:hidden;width:var(--chatroom-width)}@media screen and (max-height:450px){.conversejs .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}@media screen and (max-width:480px){.conversejs .chatroom .box-flyout{height:var(--mobile-chat-height);width:var(--mobile-chat-width);height:var(--fullpage-chat-height)}}.conversejs .chatroom .box-flyout .empty-history-feedback{position:relative}.conversejs .chatroom .box-flyout .empty-history-feedback span{width:100%;text-align:center;position:absolute;margin-top:50%}.conversejs .chatroom .box-flyout .chatroom-body{flex-direction:row;flex-flow:nowrap;background-color:#fff;border-top:0;height:100%;width:100%;overflow:hidden}.conversejs .chatroom .box-flyout .chatroom-body converse-muc-chatarea{width:100%;display:flex;flex-direction:row;flex-flow:nowrap}.conversejs .chatroom .box-flyout .chatroom-body .row{flex-direction:row}.conversejs .chatroom .box-flyout .chatroom-body .chat-topic{font-weight:700;color:var(--chatroom-head-bg-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-info{color:var(--chat-info-color);line-height:normal}.conversejs .chatroom .box-flyout .chatroom-body .chat-info.badge{color:var(--chat-head-text-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-info.chat-msg--retracted{color:var(--subdued-color)}.conversejs .chatroom .box-flyout .chatroom-body .disconnect-container{margin:1em;width:100%}.conversejs .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg{padding-bottom:1em}.conversejs .chatroom .box-flyout .chatroom-body .chat-area{display:flex;flex-direction:column;flex:0 1 100%;justify-content:flex-end;min-width:25%;word-wrap:break-word}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator{background-color:var(--chatroom-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content{height:100%}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help converse-chat-help{border-top:1px solid var(--chatroom-color)}.conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content__help .close-chat-help svg{fill:var(--chatroom-color)}.conversejs .chatroom .room-invite .invited-contact{margin:-1px 0 0 -1px;width:100%;border:1px solid #999}#muc-details-modal .features-list{margin-left:1em}#muc-details-modal .chatroom-features{width:100%}#muc-details-modal .chatroom-features .features-list{padding-top:0}#muc-details-modal .chatroom-features .features-list .feature{width:100%;margin-right:.5em;padding-right:0;font-size:1em;cursor:help}#muc-details-modal .chatroom-features .features-list .feature .fa{margin-right:.5em;color:var(--text-color)}converse-muc-destroyed,converse-muc-disconnected{padding:2em;width:100%;height:100%}.conversejs .badge--muc,.conversejs.converse-embedded .badge--muc{background-color:var(--groupchats-header-color)}.conversejs .add-chatroom input[type=button],.conversejs .add-chatroom input[type=submit],.conversejs.converse-embedded .add-chatroom input[type=button],.conversejs.converse-embedded .add-chatroom input[type=submit]{margin:.3em 0}.conversejs converse-chats.converse-overlayed .chatbox.chatroom{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .box-flyout{min-width:var(--chatroom-width)!important;width:var(--chatroom-width)}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatbox-title__text{flex:0 0 58.3333333333%;max-width:58.3333333333%}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatbox-title__buttons{flex:0 0 41.6666666667%;max-width:41.6666666667%}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chat-head__desc{font-size:80%;margin-bottom:1em}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupants-heading{padding:0}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .occupant-list{border-bottom:none}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .occupants ul .occupant .occupant-nick-badge .occupant-badges{display:none}.conversejs converse-chats.converse-overlayed .chatbox.chatroom .chatroom-body .chat-area{min-width:var(--overlayed-chat-width)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout,.conversejs converse-chats.converse-mobile .chatroom .box-flyout{width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator{max-width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants{padding:var(--occupants-padding)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{font-size:var(--font-size-large)}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,.conversejs converse-chats.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,.conversejs converse-chats.converse-mobile .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li{font-size:var(--font-size-small)}.conversejs converse-chats.converse-embedded .chatroom .room-invite span .invited-contact,.conversejs converse-chats.converse-fullscreen .chatroom .room-invite span .invited-contact,.conversejs converse-chats.converse-mobile .chatroom .room-invite span .invited-contact{margin:0 0 .5em -1px}.conversejs converse-chats.converse-embedded .chatroom{margin:0;width:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .occupants-heading{font-size:120%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chat-content .chat-message{margin:.5em;font-size:120%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .sendXMPPMessage .chat-textarea{padding:.5em;font-size:110%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body{height:100%}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .chatroom-body .muc-form-container{height:100%;position:relative}.conversejs converse-chats.converse-embedded .chatroom .box-flyout .occupants .occupant-list{padding-left:.3em} +converse-root.converse-js.converse-fullpage,converse-root.converse-js.converse-mobile,converse-root.converse-js.converse-overlayed{bottom:0;height:100%;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);position:fixed;z-index:1031}converse-root.converse-js.converse-embedded{position:relative} +.conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:0;height:var(--roster-height);padding:0;overflow:hidden;height:calc(100% - 70px)}.conversejs #converse-roster #online-count{display:none}.conversejs #converse-roster .search-xmpp ul li.chat-info{padding-left:10px}.conversejs #converse-roster .roster-filter-form{width:100%}.conversejs #converse-roster .roster-filter-form .button-group{padding:.2em}.conversejs #converse-roster .roster-filter-form span{padding:.3em;cursor:pointer;min-width:25px;text-align:center}.conversejs #converse-roster .roster-filter-form .roster-filter{width:100%;margin:.2em;font-size:calc(var(--font-size) - 2px)}.conversejs #converse-roster .roster-filter-form .state-type{font-size:calc(var(--font-size) - 2px);width:100%}.conversejs #converse-roster .roster-contacts{padding:0;margin:0 0 .2em 0;height:100%;overflow-x:hidden;overflow-y:auto;color:var(--text-color)}.conversejs #converse-roster .roster-contacts converse-roster-contact{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:flex;justify-content:space-between}.conversejs #converse-roster .roster-contacts .group-toggle{font-family:var(--heading-font);display:block;width:100%;margin:.75em 0 .25em 0}.conversejs #converse-roster .roster-contacts .group-toggle,.conversejs #converse-roster .roster-contacts .group-toggle .fa{color:var(--chat-head-color-dark)!important}.conversejs #converse-roster .roster-contacts .group-toggle .fa:hover,.conversejs #converse-roster .roster-contacts .group-toggle:hover{color:var(--chat-head-color-darker)!important}.conversejs #converse-roster .roster-contacts .current-xmpp-contact{margin:.25em 0}.conversejs #converse-roster .roster-contacts li.requesting-xmpp-contact a{line-height:var(--line-height)}.conversejs #converse-roster .roster-contacts li.requesting-xmpp-contact .req-contact-name{padding:0 .2em 0 0}.conversejs #converse-roster .roster-contacts li .open-chat{margin:0;padding:0}.conversejs #converse-roster .roster-contacts li .open-chat.unread-msgs{font-weight:700}.conversejs #converse-roster .roster-contacts li .open-chat.unread-msgs .contact-name{width:70%}.conversejs #converse-roster .roster-contacts li .open-chat .msgs-indicator{color:#fff;background-color:var(--chat-head-color);opacity:1;border-radius:10%;padding:.2em .4em;font-size:var(--font-size-small);margin-right:0}.conversejs #converse-roster .roster-contacts li .open-chat .contact-name{padding:0;margin:0;max-width:85%;float:none;height:100%}.conversejs #converse-roster .roster-contacts li .open-chat .contact-name.unread-msgs{max-width:60%}.conversejs #converse-roster .roster-contacts li .open-chat .contact-name.contact-name--offline{margin-left:.25em}.conversejs #converse-roster .roster-contacts li.odd{background-color:#dceac5}.conversejs #converse-roster .roster-contacts li a,.conversejs #converse-roster .roster-contacts li span{white-space:nowrap;text-overflow:ellipsis}.conversejs #converse-roster .roster-contacts li .span{display:inline-block}.conversejs #converse-roster .roster-contacts li .decline-xmpp-request{margin-left:5px}.conversejs #converse-roster .roster-contacts li:hover{background-color:var(controlbox-pane-bg-hover-color)}.conversejs #converse-roster span.pending-contact-name{line-height:var(--line-height);width:100%} -/*# sourceMappingURL=converse.min.css.map*/ -/* Localized */ \ No newline at end of file +/*# sourceMappingURL=converse.min.css.map*/ \ No newline at end of file diff --git a/sources/dist/converse.min.js b/sources/dist/converse.min.js index d391bf6..ba5a2e6 100644 --- a/sources/dist/converse.min.js +++ b/sources/dist/converse.min.js @@ -1,13 +1,13 @@ /*! For license information please see converse.min.js.LICENSE.txt */ -(()=>{var e,t,n,s,i={9494:(e,t,n)=>{"use strict";const s=n(7672),i=n(4817);e.exports={atob:s,btoa:i}},7672:e=>{"use strict";function t(e){const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(e);return t<0?void 0:t}e.exports=function(e){if((e=(e=`${e}`).replace(/[ \t\n\f\r]/g,"")).length%4==0&&(e=e.replace(/==?$/,"")),e.length%4==1||/[^+/0-9A-Za-z]/.test(e))return null;let n="",s=0,i=0;for(let r=0;r>16),n+=String.fromCharCode((65280&s)>>8),n+=String.fromCharCode(255&s),s=i=0);return 12===i?(s>>=4,n+=String.fromCharCode(s)):18===i&&(s>>=2,n+=String.fromCharCode((65280&s)>>8),n+=String.fromCharCode(255&s)),n}},4817:e=>{"use strict";function t(e){if(e>=0&&e<64)return"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e]}e.exports=function(e){let n;for(e=`${e}`,n=0;n255)return null;let s="";for(n=0;n>2,i[1]=(3&e.charCodeAt(n))<<4,e.length>n+1&&(i[1]|=e.charCodeAt(n+1)>>4,i[2]=(15&e.charCodeAt(n+1))<<2),e.length>n+2&&(i[2]|=e.charCodeAt(n+2)>>6,i[3]=63&e.charCodeAt(n+2));for(let e=0;e{var s;!function(){"use strict";var i={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[+-]/};function r(e){return a(l(e),arguments)}function o(e,t){return r.apply(null,[e].concat(t||[]))}function a(e,t){var n,s,o,a,c,l,d,u,h,m=1,f=e.length,g="";for(s=0;s=0),a.type){case"b":n=parseInt(n,10).toString(2);break;case"c":n=String.fromCharCode(parseInt(n,10));break;case"d":case"i":n=parseInt(n,10);break;case"j":n=JSON.stringify(n,null,a.width?parseInt(a.width):0);break;case"e":n=a.precision?parseFloat(n).toExponential(a.precision):parseFloat(n).toExponential();break;case"f":n=a.precision?parseFloat(n).toFixed(a.precision):parseFloat(n);break;case"g":n=a.precision?String(Number(n.toPrecision(a.precision))):parseFloat(n);break;case"o":n=(parseInt(n,10)>>>0).toString(8);break;case"s":n=String(n),n=a.precision?n.substring(0,a.precision):n;break;case"t":n=String(!!n),n=a.precision?n.substring(0,a.precision):n;break;case"T":n=Object.prototype.toString.call(n).slice(8,-1).toLowerCase(),n=a.precision?n.substring(0,a.precision):n;break;case"u":n=parseInt(n,10)>>>0;break;case"v":n=n.valueOf(),n=a.precision?n.substring(0,a.precision):n;break;case"x":n=(parseInt(n,10)>>>0).toString(16);break;case"X":n=(parseInt(n,10)>>>0).toString(16).toUpperCase()}i.json.test(a.type)?g+=n:(!i.number.test(a.type)||u&&!a.sign?h="":(h=u?"+":"-",n=n.toString().replace(i.sign,"")),l=a.pad_char?"0"===a.pad_char?"0":a.pad_char.charAt(1):" ",d=a.width-(h+n).length,c=a.width&&d>0?l.repeat(d):"",g+=a.align?h+n+c:"0"===l?h+c+n:c+h+n)}return g}var c=Object.create(null);function l(e){if(c[e])return c[e];for(var t,n=e,s=[],r=0;n;){if(null!==(t=i.text.exec(n)))s.push(t[0]);else if(null!==(t=i.modulo.exec(n)))s.push("%");else{if(null===(t=i.placeholder.exec(n)))throw new SyntaxError("[sprintf] unexpected placeholder");if(t[2]){r|=1;var o=[],a=t[2],l=[];if(null===(l=i.key.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(o.push(l[1]);""!==(a=a.substring(l[0].length));)if(null!==(l=i.key_access.exec(a)))o.push(l[1]);else{if(null===(l=i.index_access.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");o.push(l[1])}t[2]=o}else r|=2;if(3===r)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");s.push({placeholder:t[0],param_no:t[1],keys:t[2],sign:t[3],pad_char:t[4],align:t[5],width:t[6],precision:t[7],type:t[8]})}n=n.substring(t[0].length)}return c[e]=s}t.sprintf=r,t.vsprintf=o,"undefined"!=typeof window&&(window.sprintf=r,window.vsprintf=o,void 0===(s=function(){return{sprintf:r,vsprintf:o}}.call(t,n,t,e))||(e.exports=s))}()},1059:function(e,t,n){var s,i;!function(r,o){"use strict";e.exports?e.exports=o():void 0===(i="function"==typeof(s=o)?s.call(t,n,t,e):s)||(e.exports=i)}(0,(function(e){"use strict";var t=e&&e.IPv6;return{best:function(e){var t,n,s=e.toLowerCase().split(":"),i=s.length,r=8;for(""===s[0]&&""===s[1]&&""===s[2]?(s.shift(),s.shift()):""===s[0]&&""===s[1]?s.shift():""===s[i-1]&&""===s[i-2]&&s.pop(),-1!==s[(i=s.length)-1].indexOf(".")&&(r=7),t=0;t1;a++)n.splice(0,1);s[o]=n.join("")}var c=-1,l=0,d=0,u=-1,h=!1;for(o=0;ol&&(c=u,l=d)):"0"===s[o]&&(h=!0,u=o,d=1);d>l&&(c=u,l=d),l>1&&s.splice(c,l,""),i=s.length;var m="";for(""===s[0]&&(m=":"),o=0;o=e.length-1)return!1;var s=e.lastIndexOf(".",t-1);if(s<=0||s>=t-1)return!1;var i=n.list[e.slice(t+1)];return!!i&&i.indexOf(" "+e.slice(s+1,t)+" ")>=0},is:function(e){var t=e.lastIndexOf(".");if(t<=0||t>=e.length-1)return!1;if(e.lastIndexOf(".",t-1)>=0)return!1;var s=n.list[e.slice(t+1)];return!!s&&s.indexOf(" "+e.slice(0,t)+" ")>=0},get:function(e){var t=e.lastIndexOf(".");if(t<=0||t>=e.length-1)return null;var s=e.lastIndexOf(".",t-1);if(s<=0||s>=t-1)return null;var i=n.list[e.slice(t+1)];return i?i.indexOf(" "+e.slice(s+1,t)+" ")<0?null:e.slice(s+1):null},noConflict:function(){return e.SecondLevelDomains===this&&(e.SecondLevelDomains=t),this}};return n}))},2369:function(e,t,n){var s,i,r;!function(o,a){"use strict";e.exports?e.exports=a(n(6635),n(1059),n(4463)):(i=[n(6635),n(1059),n(4463)],void 0===(r="function"==typeof(s=a)?s.apply(t,i):s)||(e.exports=r))}(0,(function(e,t,n,s){"use strict";var i=s&&s.URI;function r(e,t){var n=arguments.length>=1,s=arguments.length>=2;if(!(this instanceof r))return n?s?new r(e,t):new r(e):new r;if(void 0===e){if(n)throw new TypeError("undefined is not a valid argument for URI");e="undefined"!=typeof location?location.href+"":""}if(null===e&&n)throw new TypeError("null is not a valid argument for URI");return this.href(e),void 0!==t?this.absoluteTo(t):this}r.version="1.19.7";var o=r.prototype,a=Object.prototype.hasOwnProperty;function c(e){return e.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function l(e){return void 0===e?"Undefined":String(Object.prototype.toString.call(e)).slice(8,-1)}function d(e){return"Array"===l(e)}function u(e,t){var n,s,i={};if("RegExp"===l(t))i=null;else if(d(t))for(n=0,s=t.length;n]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi,r.findUri={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,end:/[\s\r\n]|$/,trim:/[`!()\[\]{};:'".,<>?«»“”„‘’]+$/,parens:/(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g},r.defaultPorts={http:"80",https:"443",ftp:"21",gopher:"70",ws:"80",wss:"443"},r.hostProtocols=["http","https"],r.invalid_hostname_characters=/[^a-zA-Z0-9\.\-:_]/,r.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src",audio:"src",video:"src"},r.getDomAttribute=function(e){if(e&&e.nodeName){var t=e.nodeName.toLowerCase();if("input"!==t||"image"===e.type)return r.domAttributes[t]}},r.encode=p,r.decode=decodeURIComponent,r.iso8859=function(){r.encode=escape,r.decode=unescape},r.unicode=function(){r.encode=p,r.decode=decodeURIComponent},r.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/gi,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/gi,map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@","%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}},urnpath:{encode:{expression:/%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/gi,map:{"%21":"!","%24":"$","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"=","%40":"@"}},decode:{expression:/[\/\?#:]/g,map:{"/":"%2F","?":"%3F","#":"%23",":":"%3A"}}}},r.encodeQuery=function(e,t){var n=r.encode(e+"");return void 0===t&&(t=r.escapeQuerySpace),t?n.replace(/%20/g,"+"):n},r.decodeQuery=function(e,t){e+="",void 0===t&&(t=r.escapeQuerySpace);try{return r.decode(t?e.replace(/\+/g,"%20"):e)}catch(t){return e}};var v,b={encode:"encode",decode:"decode"},y=function(e,t){return function(n){try{return r[t](n+"").replace(r.characters[e][t].expression,(function(n){return r.characters[e][t].map[n]}))}catch(e){return n}}};for(v in b)r[v+"PathSegment"]=y("pathname",b[v]),r[v+"UrnPathSegment"]=y("urnpath",b[v]);var _=function(e,t,n){return function(s){var i;i=n?function(e){return r[t](r[n](e))}:r[t];for(var o=(s+"").split(e),a=0,c=o.length;a-1&&(t.fragment=e.substring(n+1)||null,e=e.substring(0,n)),(n=e.indexOf("?"))>-1&&(t.query=e.substring(n+1)||null,e=e.substring(0,n)),"//"===(e=e.replace(/^(https?|ftp|wss?)?:[/\\]*/,"$1://")).substring(0,2)?(t.protocol=null,e=e.substring(2),e=r.parseAuthority(e,t)):(n=e.indexOf(":"))>-1&&(t.protocol=e.substring(0,n)||null,t.protocol&&!t.protocol.match(r.protocol_expression)?t.protocol=void 0:"//"===e.substring(n+1,n+3).replace(/\\/g,"/")?(e=e.substring(n+3),e=r.parseAuthority(e,t)):(e=e.substring(n+1),t.urn=!0)),t.path=e,t},r.parseHost=function(e,t){e||(e="");var n,s,i=(e=e.replace(/\\/g,"/")).indexOf("/");if(-1===i&&(i=e.length),"["===e.charAt(0))n=e.indexOf("]"),t.hostname=e.substring(1,n)||null,t.port=e.substring(n+2,i)||null,"/"===t.port&&(t.port=null);else{var o=e.indexOf(":"),a=e.indexOf("/"),c=e.indexOf(":",o+1);-1!==c&&(-1===a||c-1?i:e.length-1);return o>-1&&(-1===i||o-1?m.slice(0,f)+m.slice(f).replace(o,""):m.replace(o,"")).length<=l[0].length||n.ignore&&n.ignore.test(m))){var v=t(m,d,h=d+m.length,e);void 0!==v?(v=String(v),e=e.slice(0,d)+v+e.slice(h),s.lastIndex=d+v.length):s.lastIndex=h}}return s.lastIndex=0,e},r.ensureValidHostname=function(t,n){var s=!!t,i=!1;if(!!n&&(i=h(r.hostProtocols,n)),i&&!s)throw new TypeError("Hostname cannot be empty, if protocol is "+n);if(t&&t.match(r.invalid_hostname_characters)){if(!e)throw new TypeError('Hostname "'+t+'" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available');if(e.toASCII(t).match(r.invalid_hostname_characters))throw new TypeError('Hostname "'+t+'" contains characters other than [A-Z0-9.-:_]')}},r.ensureValidPort=function(e){if(e){var t=Number(e);if(!(/^[0-9]+$/.test(t)&&t>0&&t<65536))throw new TypeError('Port "'+e+'" is not a valid port')}},r.noConflict=function(e){if(e){var t={URI:this.noConflict()};return s.URITemplate&&"function"==typeof s.URITemplate.noConflict&&(t.URITemplate=s.URITemplate.noConflict()),s.IPv6&&"function"==typeof s.IPv6.noConflict&&(t.IPv6=s.IPv6.noConflict()),s.SecondLevelDomains&&"function"==typeof s.SecondLevelDomains.noConflict&&(t.SecondLevelDomains=s.SecondLevelDomains.noConflict()),t}return s.URI===this&&(s.URI=i),this},o.build=function(e){return!0===e?this._deferred_build=!0:(void 0===e||this._deferred_build)&&(this._string=r.build(this._parts),this._deferred_build=!1),this},o.clone=function(){return new r(this)},o.valueOf=o.toString=function(){return this.build(!1)._string},o.protocol=w("protocol"),o.username=w("username"),o.password=w("password"),o.hostname=w("hostname"),o.port=w("port"),o.query=S("query","?"),o.fragment=S("fragment","#"),o.search=function(e,t){var n=this.query(e,t);return"string"==typeof n&&n.length?"?"+n:n},o.hash=function(e,t){var n=this.fragment(e,t);return"string"==typeof n&&n.length?"#"+n:n},o.pathname=function(e,t){if(void 0===e||!0===e){var n=this._parts.path||(this._parts.hostname?"/":"");return e?(this._parts.urn?r.decodeUrnPath:r.decodePath)(n):n}return this._parts.urn?this._parts.path=e?r.recodeUrnPath(e):"":this._parts.path=e?r.recodePath(e):"/",this.build(!t),this},o.path=o.pathname,o.href=function(e,t){var n;if(void 0===e)return this.toString();this._string="",this._parts=r._parts();var s=e instanceof r,i="object"==typeof e&&(e.hostname||e.path||e.pathname);if(e.nodeName&&(e=e[r.getDomAttribute(e)]||"",i=!1),!s&&i&&void 0!==e.pathname&&(e=e.toString()),"string"==typeof e||e instanceof String)this._parts=r.parse(String(e),this._parts);else{if(!s&&!i)throw new TypeError("invalid input");var o=s?e._parts:e;for(n in o)"query"!==n&&a.call(this._parts,n)&&(this._parts[n]=o[n]);o.query&&this.query(o.query,!1)}return this.build(!t),this},o.is=function(e){var t=!1,s=!1,i=!1,o=!1,a=!1,c=!1,l=!1,d=!this._parts.urn;switch(this._parts.hostname&&(d=!1,s=r.ip4_expression.test(this._parts.hostname),i=r.ip6_expression.test(this._parts.hostname),a=(o=!(t=s||i))&&n&&n.has(this._parts.hostname),c=o&&r.idn_expression.test(this._parts.hostname),l=o&&r.punycode_expression.test(this._parts.hostname)),e.toLowerCase()){case"relative":return d;case"absolute":return!d;case"domain":case"name":return o;case"sld":return a;case"ip":return t;case"ip4":case"ipv4":case"inet4":return s;case"ip6":case"ipv6":case"inet6":return i;case"idn":return c;case"url":return!this._parts.urn;case"urn":return!!this._parts.urn;case"punycode":return l}return null};var x=o.protocol,E=o.port,A=o.hostname;o.protocol=function(e,t){if(e&&!(e=e.replace(/:(\/\/)?$/,"")).match(r.protocol_expression))throw new TypeError('Protocol "'+e+"\" contains characters other than [A-Z0-9.+-] or doesn't start with [A-Z]");return x.call(this,e,t)},o.scheme=o.protocol,o.port=function(e,t){return this._parts.urn?void 0===e?"":this:(void 0!==e&&(0===e&&(e=null),e&&(":"===(e+="").charAt(0)&&(e=e.substring(1)),r.ensureValidPort(e))),E.call(this,e,t))},o.hostname=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0!==e){var n={preventInvalidHostname:this._parts.preventInvalidHostname};if("/"!==r.parseHost(e,n))throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-]');e=n.hostname,this._parts.preventInvalidHostname&&r.ensureValidHostname(e,this._parts.protocol)}return A.call(this,e,t)},o.origin=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e){var n=this.protocol();return this.authority()?(n?n+"://":"")+this.authority():""}var s=r(e);return this.protocol(s.protocol()).authority(s.authority()).build(!t),this},o.host=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e)return this._parts.hostname?r.buildHost(this._parts):"";if("/"!==r.parseHost(e,this._parts))throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-]');return this.build(!t),this},o.authority=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e)return this._parts.hostname?r.buildAuthority(this._parts):"";if("/"!==r.parseAuthority(e,this._parts))throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-]');return this.build(!t),this},o.userinfo=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e){var n=r.buildUserinfo(this._parts);return n?n.substring(0,n.length-1):n}return"@"!==e[e.length-1]&&(e+="@"),r.parseUserinfo(e,this._parts),this.build(!t),this},o.resource=function(e,t){var n;return void 0===e?this.path()+this.search()+this.hash():(n=r.parse(e),this._parts.path=n.path,this._parts.query=n.query,this._parts.fragment=n.fragment,this.build(!t),this)},o.subdomain=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e){if(!this._parts.hostname||this.is("IP"))return"";var n=this._parts.hostname.length-this.domain().length-1;return this._parts.hostname.substring(0,n)||""}var s=this._parts.hostname.length-this.domain().length,i=this._parts.hostname.substring(0,s),o=new RegExp("^"+c(i));if(e&&"."!==e.charAt(e.length-1)&&(e+="."),-1!==e.indexOf(":"))throw new TypeError("Domains cannot contain colons");return e&&r.ensureValidHostname(e,this._parts.protocol),this._parts.hostname=this._parts.hostname.replace(o,e),this.build(!t),this},o.domain=function(e,t){if(this._parts.urn)return void 0===e?"":this;if("boolean"==typeof e&&(t=e,e=void 0),void 0===e){if(!this._parts.hostname||this.is("IP"))return"";var n=this._parts.hostname.match(/\./g);if(n&&n.length<2)return this._parts.hostname;var s=this._parts.hostname.length-this.tld(t).length-1;return s=this._parts.hostname.lastIndexOf(".",s-1)+1,this._parts.hostname.substring(s)||""}if(!e)throw new TypeError("cannot set domain empty");if(-1!==e.indexOf(":"))throw new TypeError("Domains cannot contain colons");if(r.ensureValidHostname(e,this._parts.protocol),!this._parts.hostname||this.is("IP"))this._parts.hostname=e;else{var i=new RegExp(c(this.domain())+"$");this._parts.hostname=this._parts.hostname.replace(i,e)}return this.build(!t),this},o.tld=function(e,t){if(this._parts.urn)return void 0===e?"":this;if("boolean"==typeof e&&(t=e,e=void 0),void 0===e){if(!this._parts.hostname||this.is("IP"))return"";var s=this._parts.hostname.lastIndexOf("."),i=this._parts.hostname.substring(s+1);return!0!==t&&n&&n.list[i.toLowerCase()]&&n.get(this._parts.hostname)||i}var r;if(!e)throw new TypeError("cannot set TLD empty");if(e.match(/[^a-zA-Z0-9-]/)){if(!n||!n.is(e))throw new TypeError('TLD "'+e+'" contains characters other than [A-Z0-9]');r=new RegExp(c(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(r,e)}else{if(!this._parts.hostname||this.is("IP"))throw new ReferenceError("cannot set TLD on non-domain host");r=new RegExp(c(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(r,e)}return this.build(!t),this},o.directory=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e||!0===e){if(!this._parts.path&&!this._parts.hostname)return"";if("/"===this._parts.path)return"/";var n=this._parts.path.length-this.filename().length-1,s=this._parts.path.substring(0,n)||(this._parts.hostname?"/":"");return e?r.decodePath(s):s}var i=this._parts.path.length-this.filename().length,o=this._parts.path.substring(0,i),a=new RegExp("^"+c(o));return this.is("relative")||(e||(e="/"),"/"!==e.charAt(0)&&(e="/"+e)),e&&"/"!==e.charAt(e.length-1)&&(e+="/"),e=r.recodePath(e),this._parts.path=this._parts.path.replace(a,e),this.build(!t),this},o.filename=function(e,t){if(this._parts.urn)return void 0===e?"":this;if("string"!=typeof e){if(!this._parts.path||"/"===this._parts.path)return"";var n=this._parts.path.lastIndexOf("/"),s=this._parts.path.substring(n+1);return e?r.decodePathSegment(s):s}var i=!1;"/"===e.charAt(0)&&(e=e.substring(1)),e.match(/\.?\//)&&(i=!0);var o=new RegExp(c(this.filename())+"$");return e=r.recodePath(e),this._parts.path=this._parts.path.replace(o,e),i?this.normalizePath(t):this.build(!t),this},o.suffix=function(e,t){if(this._parts.urn)return void 0===e?"":this;if(void 0===e||!0===e){if(!this._parts.path||"/"===this._parts.path)return"";var n,s,i=this.filename(),o=i.lastIndexOf(".");return-1===o?"":(n=i.substring(o+1),s=/^[a-z0-9%]+$/i.test(n)?n:"",e?r.decodePathSegment(s):s)}"."===e.charAt(0)&&(e=e.substring(1));var a,l=this.suffix();if(l)a=e?new RegExp(c(l)+"$"):new RegExp(c("."+l)+"$");else{if(!e)return this;this._parts.path+="."+r.recodePath(e)}return a&&(e=r.recodePath(e),this._parts.path=this._parts.path.replace(a,e)),this.build(!t),this},o.segment=function(e,t,n){var s=this._parts.urn?":":"/",i=this.path(),r="/"===i.substring(0,1),o=i.split(s);if(void 0!==e&&"number"!=typeof e&&(n=t,t=e,e=void 0),void 0!==e&&"number"!=typeof e)throw new Error('Bad segment "'+e+'", must be 0-based integer');if(r&&o.shift(),e<0&&(e=Math.max(o.length+e,0)),void 0===t)return void 0===e?o:o[e];if(null===e||void 0===o[e])if(d(t)){o=[];for(var a=0,c=t.length;a= 0x80 (not a basic code point)","invalid-input":"Invalid input"},m=Math.floor,f=String.fromCharCode;function g(e){throw new RangeError(h[e])}function p(e,t){for(var n=e.length,s=[];n--;)s[n]=t(e[n]);return s}function v(e,t){var n=e.split("@"),s="";return n.length>1&&(s=n[0]+"@",e=n[1]),s+p((e=e.replace(u,".")).split("."),t).join(".")}function b(e){for(var t,n,s=[],i=0,r=e.length;i=55296&&t<=56319&&i65535&&(t+=f((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+f(e)})).join("")}function _(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function w(e,t,n){var s=0;for(e=n?m(e/700):e>>1,e+=m(e/t);e>455;s+=c)e=m(e/35);return m(s+36*e/(e+38))}function S(e){var t,n,s,i,r,o,l,d,u,h,f,p=[],v=e.length,b=0,_=128,S=72;for((n=e.lastIndexOf("-"))<0&&(n=0),s=0;s=128&&g("not-basic"),p.push(e.charCodeAt(s));for(i=n>0?n+1:0;i=v&&g("invalid-input"),((d=(f=e.charCodeAt(i++))-48<10?f-22:f-65<26?f-65:f-97<26?f-97:c)>=c||d>m((a-b)/o))&&g("overflow"),b+=d*o,!(d<(u=l<=S?1:l>=S+26?26:l-S));l+=c)o>m(a/(h=c-u))&&g("overflow"),o*=h;S=w(b-r,t=p.length+1,0==r),m(b/t)>a-_&&g("overflow"),_+=m(b/t),b%=t,p.splice(b++,0,_)}return y(p)}function x(e){var t,n,s,i,r,o,l,d,u,h,p,v,y,S,x,E=[];for(v=(e=b(e)).length,t=128,n=0,r=72,o=0;o=t&&pm((a-n)/(y=s+1))&&g("overflow"),n+=(l-t)*y,t=l,o=0;oa&&g("overflow"),p==t){for(d=n,u=c;!(d<(h=u<=r?1:u>=r+26?26:u-r));u+=c)x=d-h,S=c-h,E.push(f(_(h+x%S,0))),d=m(x/S);E.push(f(_(d,0))),r=w(n,y,s==i),n=0,++s}++n,++t}return E.join("")}o={version:"1.3.2",ucs2:{decode:b,encode:y},decode:S,encode:x,toASCII:function(e){return v(e,(function(e){return d.test(e)?"xn--"+x(e):e}))},toUnicode:function(e){return v(e,(function(e){return l.test(e)?S(e.slice(4).toLowerCase()):e}))}},void 0===(s=function(){return o}.call(t,n,t,e))||(e.exports=s)}()},7962:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>nx});var s=n(2369),i=n.n(s),r=n(4457);const o={initialize(){},__:(...e)=>(0,r.sprintf)(...e)},a=function(e){return null!=e&&"object"==typeof e},c="object"==typeof global&&global&&global.Object===Object&&global;var l="object"==typeof self&&self&&self.Object===Object&&self;const d=c||l||Function("return this")(),u=d.Symbol;var h=Object.prototype,m=h.hasOwnProperty,f=h.toString,g=u?u.toStringTag:void 0;var p=Object.prototype.toString;var v=u?u.toStringTag:void 0;const b=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":v&&v in Object(e)?function(e){var t=m.call(e,g),n=e[g];try{e[g]=void 0;var s=!0}catch(e){}var i=f.call(e);return s&&(t?e[g]=n:delete e[g]),i}(e):function(e){return p.call(e)}(e)},y=function(e,t){return function(n){return e(t(n))}},_=y(Object.getPrototypeOf,Object);var w=Function.prototype,S=Object.prototype,x=w.toString,E=S.hasOwnProperty,A=x.call(Object);const C=function(e){if(!a(e)||"[object Object]"!=b(e))return!1;var t=_(e);if(null===t)return!0;var n=E.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&x.call(n)==A},T=function(e){return a(e)&&1===e.nodeType&&!C(e)};var k,j,N,O;const $={debug:0,info:1,warn:2,error:3,fatal:4},I=Object.assign({debug:null!==(k=console)&&void 0!==k&&k.log?console.log.bind(console):function(){},error:null!==(j=console)&&void 0!==j&&j.log?console.log.bind(console):function(){},info:null!==(N=console)&&void 0!==N&&N.log?console.log.bind(console):function(){},warn:null!==(O=console)&&void 0!==O&&O.log?console.log.bind(console):function(){}},console),M={setLogLevel(e){if(!["debug","info","warn","error","fatal"].includes(e))throw new Error(`Invalid loglevel: ${e}`);this.loglevel=e},log(e,t,n=""){if($[t]<$[this.loglevel])return;"error"===t||"fatal"===t?n=n||"color: maroon":"debug"===t&&(n=n||"color: green"),e instanceof Error?e=e.stack:T(e)&&(e=e.outerHTML);const s=n?"%c":"";"error"===t?I.error(`${s} ERROR: ${e}`,n):"warn"===t?I.warn(`${s} ${(new Date).toISOString()} WARNING: ${e}`,n):"fatal"===t?I.error(`${s} FATAL: ${e}`,n):"debug"===t?I.debug(`${s} ${(new Date).toISOString()} DEBUG: ${e}`,n):I.info(`${s} ${(new Date).toISOString()} INFO: ${e}`,n)},debug(e,t){this.log(e,"debug",t)},error(e,t){this.log(e,"error",t)},info(e,t){this.log(e,"info",t)},warn(e,t){this.log(e,"warn",t)},fatal(e,t){this.log(e,"fatal",t)}},R=function(){let e=n.g.WebSocket;if(void 0===e)try{e=n(7026)}catch(e){throw new Error('You must install the "ws" package to use Strophe in nodejs.')}return e}(),D=function(){let e=n.g.DOMParser;if(void 0===e)try{e=n(647).a}catch(e){throw new Error('You must install the "xmldom" package to use Strophe in nodejs.')}return e}();const L=function(e,t){const n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n},z=function(e){if("string"!=typeof e)throw new Error("str2binl was passed a non-string");const t=[];for(let n=0;n<8*e.length;n+=8)t[n>>5]|=(255&e.charCodeAt(n/8))<>>32-a,n);var o,a},F=function(e,t,n,s,i,r,o){return P(t&n|~t&s,e,t,i,r,o)},U=function(e,t,n,s,i,r,o){return P(t&s|n&~s,e,t,i,r,o)},B=function(e,t,n,s,i,r,o){return P(t^n^s,e,t,i,r,o)},q=function(e,t,n,s,i,r,o){return P(n^(t|~s),e,t,i,r,o)},H=function(e,t){e[t>>5]|=128<>>9<<4)]=t;let n,s,i,r,o=1732584193,a=-271733879,c=-1732584194,l=271733878;for(let t=0;t>2]>>s%4*8+4&15)+t.charAt(e[s>>2]>>s%4*8&15);return n}(H(z(e),8*e.length))},hash:function(e){return function(e){let t="";for(let n=0;n<32*e.length;n+=8)t+=String.fromCharCode(e[n>>5]>>>n%32&255);return t}(H(z(e),8*e.length))}};class W{constructor(e,t,n){this.mechname=e,this.isClientFirst=t,this.priority=n}test(){return!0}onStart(e){this._connection=e}onChallenge(e,t){throw new Error("You should implement challenge handling!")}clientChallenge(e){if(!this.isClientFirst)throw new Error("clientChallenge should not be called if isClientFirst is false!");return this.onChallenge(e)}onFailure(){this._connection=null}onSuccess(){this._connection=null}}const V=function(e){var t,n,s="",i=e.length;for(t=0;t=0&&n<=127?s+=e.charAt(t):n>2047?(s+=String.fromCharCode(224|n>>12&15),s+=String.fromCharCode(128|n>>6&63),s+=String.fromCharCode(128|n>>0&63)):(s+=String.fromCharCode(192|n>>6&31),s+=String.fromCharCode(128|n>>0&63));return s};function J(e,t){e[t>>5]|=128<<24-t%32,e[15+(t+64>>9<<4)]=t;var n,s,i,r,o,a,c,l,d=new Array(80),u=1732584193,h=-271733879,m=-1732584194,f=271733878,g=-1009589776;for(n=0;n16&&(n=J(n,8*e.length));for(var s=new Array(16),i=new Array(16),r=0;r<16;r++)s[r]=909522486^n[r],i[r]=1549556828^n[r];var o=J(s.concat(ee(t)),512+8*t.length);return J(i.concat(o),672)}function X(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function Z(e,t){return e<>>32-t}function ee(e){for(var t=[],n=0;n<8*e.length;n+=8)t[n>>5]|=(255&e.charCodeAt(n/8))<<24-n%32;return t}function te(e){for(var t,n,s="",i=0;i<4*e.length;i+=3)for(t=(e[i>>2]>>8*(3-i%4)&255)<<16|(e[i+1>>2]>>8*(3-(i+1)%4)&255)<<8|e[i+2>>2]>>8*(3-(i+2)%4)&255,n=0;n<4;n++)8*i+6*n>32*e.length?s+="=":s+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(t>>6*(3-n)&63);return s}function ne(e){for(var t="",n=0;n<32*e.length;n+=8)t+=String.fromCharCode(e[n>>5]>>>24-n%32&255);return t}const se={b64_hmac_sha1:function(e,t){return te(Q(e,t))},b64_sha1:function(e){return te(J(ee(e),8*e.length))},binb2str:ne,core_hmac_sha1:Q,str_hmac_sha1:function(e,t){return ne(Q(e,t))},str_sha1:function(e){return ne(J(ee(e),8*e.length))}};var ie=n(9494);function re(e,t){return new le.Builder(e,t)}function oe(e){return new le.Builder("message",e)}function ae(e){return new le.Builder("iq",e)}function ce(e){return new le.Builder("presence",e)}const le={VERSION:"1.4.2",NS:{HTTPBIND:"http://jabber.org/protocol/httpbind",BOSH:"urn:xmpp:xbosh",CLIENT:"jabber:client",AUTH:"jabber:iq:auth",ROSTER:"jabber:iq:roster",PROFILE:"jabber:iq:profile",DISCO_INFO:"http://jabber.org/protocol/disco#info",DISCO_ITEMS:"http://jabber.org/protocol/disco#items",MUC:"http://jabber.org/protocol/muc",SASL:"urn:ietf:params:xml:ns:xmpp-sasl",STREAM:"http://etherx.jabber.org/streams",FRAMING:"urn:ietf:params:xml:ns:xmpp-framing",BIND:"urn:ietf:params:xml:ns:xmpp-bind",SESSION:"urn:ietf:params:xml:ns:xmpp-session",VERSION:"jabber:iq:version",STANZAS:"urn:ietf:params:xml:ns:xmpp-stanzas",XHTML_IM:"http://jabber.org/protocol/xhtml-im",XHTML:"http://www.w3.org/1999/xhtml"},XHTML:{tags:["a","blockquote","br","cite","em","img","li","ol","p","span","strong","ul","body"],attributes:{a:["href"],blockquote:["style"],br:[],cite:["style"],em:[],img:["src","alt","style","height","width"],li:["style"],ol:["style"],p:["style"],span:["style"],strong:[],ul:["style"],body:[]},css:["background-color","color","font-family","font-size","font-style","font-weight","margin-left","margin-right","text-align","text-decoration"],validTag(e){for(let t=0;t0)for(let n=0;ne.tagName===t,_xmlGenerator:null,xmlGenerator:()=>(le._xmlGenerator||(le._xmlGenerator=function(){if("undefined"==typeof document)try{return(new(0,n(647).DOMImplementation)).createDocument("jabber:client","strophe",null)}catch(e){throw new Error('You must install the "xmldom" package to use Strophe in nodejs.')}if(void 0===document.implementation.createDocument||document.implementation.createDocument&&document.documentMode&&document.documentMode<10){const e=function(){const e=["Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.5.0","Msxml2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument","MSXML.DOMDocument","Microsoft.XMLDOM"];for(let t=0;t(e=(e=(e=(e=e.replace(/\&/g,"&")).replace(//g,">")).replace(/'/g,"'")).replace(/"/g,"""),xmlunescape:e=>(e=(e=(e=(e=e.replace(/\&/g,"&")).replace(/</g,"<")).replace(/>/g,">")).replace(/'/g,"'")).replace(/"/g,'"'),xmlTextNode:e=>le.xmlGenerator().createTextNode(e),xmlHtmlNode(e){let t;return D?t=(new D).parseFromString(e,"text/xml"):(t=new ActiveXObject("Microsoft.XMLDOM"),t.async="false",t.loadXML(e)),t},getText(e){if(!e)return null;let t="";0===e.childNodes.length&&e.nodeType===le.ElementType.TEXT&&(t+=e.nodeValue);for(let n=0;n0&&(r=e.join("; "),t.setAttribute(i,r))}else t.setAttribute(i,r)}for(let n=0;n"string"!=typeof e?e:e.replace(/^\s+|\s+$/g,"").replace(/\\/g,"\\5c").replace(/ /g,"\\20").replace(/\"/g,"\\22").replace(/\&/g,"\\26").replace(/\'/g,"\\27").replace(/\//g,"\\2f").replace(/:/g,"\\3a").replace(//g,"\\3e").replace(/@/g,"\\40"),unescapeNode:e=>"string"!=typeof e?e:e.replace(/\\20/g," ").replace(/\\22/g,'"').replace(/\\26/g,"&").replace(/\\27/g,"'").replace(/\\2f/g,"/").replace(/\\3a/g,":").replace(/\\3c/g,"<").replace(/\\3e/g,">").replace(/\\40/g,"@").replace(/\\5c/g,"\\"),getNodeFromJid:e=>e.indexOf("@")<0?null:e.split("@")[0],getDomainFromJid(e){const t=le.getBareJidFromJid(e);if(t.indexOf("@")<0)return t;{const e=t.split("@");return e.splice(0,1),e.join("@")}},getResourceFromJid(e){if(!e)return null;const t=e.split("/");return t.length<2?null:(t.splice(0,1),t.join("/"))},getBareJidFromJid:e=>e?e.split("/")[0]:null,_handleError(e){void 0!==e.stack&&le.fatal(e.stack),e.sourceURL?le.fatal("error: "+this.handler+" "+e.sourceURL+":"+e.line+" - "+e.name+": "+e.message):e.fileName?le.fatal("error: "+this.handler+" "+e.fileName+":"+e.lineNumber+" - "+e.name+": "+e.message):le.fatal("error: "+e.message)},log(e,t){var n;e===this.LogLevel.FATAL&&(null===(n=console)||void 0===n||n.error(t))},debug(e){this.log(this.LogLevel.DEBUG,e)},info(e){this.log(this.LogLevel.INFO,e)},warn(e){this.log(this.LogLevel.WARN,e)},error(e){this.log(this.LogLevel.ERROR,e)},fatal(e){this.log(this.LogLevel.FATAL,e)},serialize(e){if(!e)return null;"function"==typeof e.tree&&(e=e.tree());const t=[...Array(e.attributes.length).keys()].map((t=>e.attributes[t].nodeName));t.sort();let n=t.reduce(((t,n)=>`${t} ${n}="${le.xmlescape(e.attributes.getNamedItem(n).value)}"`),`<${e.nodeName}`);if(e.childNodes.length>0){n+=">";for(let t=0;t"}}n+=""}else n+="/>";return n},_requestId:0,_connectionPlugins:{},addConnectionPlugin(e,t){le._connectionPlugins[e]=t},Builder:class{constructor(e,t){"presence"!==e&&"message"!==e&&"iq"!==e||(t&&!t.xmlns?t.xmlns=le.NS.CLIENT:t||(t={xmlns:le.NS.CLIENT})),this.nodeTree=le.xmlElement(e,t),this.node=this.nodeTree}tree(){return this.nodeTree}toString(){return le.serialize(this.nodeTree)}up(){return this.node=this.node.parentNode,this}root(){return this.node=this.nodeTree,this}attrs(e){for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(void 0===e[t]?this.node.removeAttribute(t):this.node.setAttribute(t,e[t]));return this}c(e,t,n){const s=le.xmlElement(e,t,n);return this.node.appendChild(s),"string"!=typeof n&&"number"!=typeof n&&(this.node=s),this}cnode(e){let t;const n=le.xmlGenerator();try{t=void 0!==n.importNode}catch(e){t=!1}const s=t?n.importNode(e,!0):le.copyElement(e);return this.node.appendChild(s),this.node=s,this}t(e){const t=le.xmlTextNode(e);return this.node.appendChild(t),this}h(e){const t=le.xmlGenerator().createElement("body");t.innerHTML=e;const n=le.createHtml(t);for(;n.childNodes.length>0;)this.node.appendChild(n.childNodes[0]);return this}},Handler:function(e,t,n,s,i,r,o){this.handler=e,this.ns=t,this.name=n,this.type=s,this.id=i,this.options=o||{matchBareFromJid:!1,ignoreNamespaceFragment:!1},this.options.matchBare&&(le.warn('The "matchBare" option is deprecated, use "matchBareFromJid" instead.'),this.options.matchBareFromJid=this.options.matchBare,delete this.options.matchBare),this.options.matchBareFromJid?this.from=r?le.getBareJidFromJid(r):null:this.from=r,this.user=!0}};le.Handler.prototype={getNamespace(e){let t=e.getAttribute("xmlns");return t&&this.options.ignoreNamespaceFragment&&(t=t.split("#")[0]),t},namespaceMatch(e){let t=!1;return!this.ns||(le.forEachChild(e,null,(e=>{this.getNamespace(e)===this.ns&&(t=!0)})),t||this.getNamespace(e)===this.ns)},isMatch(e){let t=e.getAttribute("from");this.options.matchBareFromJid&&(t=le.getBareJidFromJid(t));const n=e.getAttribute("type");return!(!this.namespaceMatch(e)||this.name&&!le.isTagEqual(e,this.name)||this.type&&(Array.isArray(this.type)?-1===this.type.indexOf(n):n!==this.type)||this.id&&e.getAttribute("id")!==this.id||this.from&&t!==this.from)},run(e){let t=null;try{t=this.handler(e)}catch(e){throw le._handleError(e),e}return t},toString(){return"{Handler: "+this.handler+"("+this.name+","+this.id+","+this.ns+")}"}},le.TimedHandler=class{constructor(e,t){this.period=e,this.handler=t,this.lastCalled=(new Date).getTime(),this.user=!0}run(){return this.lastCalled=(new Date).getTime(),this.handler()}reset(){this.lastCalled=(new Date).getTime()}toString(){return"{TimedHandler: "+this.handler+"("+this.period+")}"}},le.Connection=class{constructor(e,t){this.service=e,this.options=t||{},this.setProtocol(),this.jid="",this.domain=null,this.features=null,this._sasl_data={},this.do_bind=!1,this.do_session=!1,this.mechanisms={},this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this.protocolErrorHandlers={HTTP:{},websocket:{}},this._idleTimeout=null,this._disconnectTimeout=null,this.authenticated=!1,this.connected=!1,this.disconnecting=!1,this.do_authentication=!0,this.paused=!1,this.restored=!1,this._data=[],this._uniqueId=0,this._sasl_success_handler=null,this._sasl_failure_handler=null,this._sasl_challenge_handler=null,this.maxRetries=5,this._idleTimeout=setTimeout((()=>this._onIdle()),100),function(e){e=e||{};for(const t in e)if(Object.prototype.hasOwnProperty.call(e,t)){let n="",s="",i="";const r=e[t],o="object"==typeof r,a=escape(unescape(o?r.value:r));o&&(n=r.expires?";expires="+r.expires:"",s=r.domain?";domain="+r.domain:"",i=r.path?";path="+r.path:""),document.cookie=t+"="+a+n+s+i}}(this.options.cookies),this.registerSASLMechanisms(this.options.mechanisms);for(const e in le._connectionPlugins)if(Object.prototype.hasOwnProperty.call(le._connectionPlugins,e)){const t=function(){};t.prototype=le._connectionPlugins[e],this[e]=new t,this[e].init(this)}}setProtocol(){const e=this.options.protocol||"";this.options.worker?this._proto=new le.WorkerWebsocket(this):0===this.service.indexOf("ws:")||0===this.service.indexOf("wss:")||0===e.indexOf("ws")?this._proto=new le.Websocket(this):this._proto=new le.Bosh(this)}reset(){this._proto._reset(),this.do_session=!1,this.do_bind=!1,this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this.authenticated=!1,this.connected=!1,this.disconnecting=!1,this.restored=!1,this._data=[],this._requests=[],this._uniqueId=0}pause(){this.paused=!0}resume(){this.paused=!1}getUniqueId(e){const t="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}));return"string"==typeof e||"number"==typeof e?t+":"+e:t+""}addProtocolErrorHandler(e,t,n){this.protocolErrorHandlers[e][t]=n}connect(e,t,n,s,i,r,o){this.jid=e,this.authzid=le.getBareJidFromJid(this.jid),this.authcid=o||le.getNodeFromJid(this.jid),this.pass=t,this.connect_callback=n,this.disconnecting=!1,this.connected=!1,this.authenticated=!1,this.restored=!1,this.domain=le.getDomainFromJid(this.jid),this._changeConnectStatus(le.Status.CONNECTING,null),this._proto._connect(s,i,r)}attach(e,t,n,s,i,r,o){if(this._proto._attach)return this._proto._attach(e,t,n,s,i,r,o);{const e=new Error('The "attach" method is not available for your connection protocol');throw e.name="StropheSessionError",e}}restore(e,t,n,s,i){if(!this._sessionCachingSupported()){const e=new Error('The "restore" method can only be used with a BOSH connection.');throw e.name="StropheSessionError",e}this._proto._restore(e,t,n,s,i)}_sessionCachingSupported(){if(this._proto instanceof le.Bosh){if(!JSON)return!1;try{sessionStorage.setItem("_strophe_","_strophe_"),sessionStorage.removeItem("_strophe_")}catch(e){return!1}return!0}return!1}xmlInput(e){}xmlOutput(e){}rawInput(e){}rawOutput(e){}nextValidRid(e){}send(e){if(null!==e){if("function"==typeof e.sort)for(let t=0;t{i&&this.deleteTimedHandler(i),"error"===e.getAttribute("type")?n&&n(e):t&&t(e)}),null,"presence",null,r);s&&(i=this.addTimedHandler(s,(()=>(this.deleteHandler(e),n&&n(null),!1))))}return this.send(e),r}sendIQ(e,t,n,s){let i=null;"function"==typeof e.tree&&(e=e.tree());let r=e.getAttribute("id");if(r||(r=this.getUniqueId("sendIQ"),e.setAttribute("id",r)),"function"==typeof t||"function"==typeof n){const e=this.addHandler((e=>{i&&this.deleteTimedHandler(i);const s=e.getAttribute("type");if("result"===s)t&&t(e);else{if("error"!==s){const e=new Error(`Got bad IQ type of ${s}`);throw e.name="StropheError",e}n&&n(e)}}),null,"iq",["error","result"],r);s&&(i=this.addTimedHandler(s,(()=>(this.deleteHandler(e),n&&n(null),!1))))}return this.send(e),r}_queueData(e){if(null===e||!e.tagName||!e.childNodes){const e=new Error("Cannot queue non-DOMElement.");throw e.name="StropheError",e}this._data.push(e)}_sendRestart(){this._data.push("restart"),this._proto._sendRestart(),this._idleTimeout=setTimeout((()=>this._onIdle()),100)}addTimedHandler(e,t){const n=new le.TimedHandler(e,t);return this.addTimeds.push(n),n}deleteTimedHandler(e){this.removeTimeds.push(e)}addHandler(e,t,n,s,i,r,o){const a=new le.Handler(e,t,n,s,i,r,o);return this.addHandlers.push(a),a}deleteHandler(e){this.removeHandlers.push(e);const t=this.addHandlers.indexOf(e);t>=0&&this.addHandlers.splice(t,1)}registerSASLMechanisms(e){this.mechanisms={},(e=e||[le.SASLAnonymous,le.SASLExternal,le.SASLOAuthBearer,le.SASLXOAuth2,le.SASLPlain,le.SASLSHA1]).forEach((e=>this.registerSASLMechanism(e)))}registerSASLMechanism(e){const t=new e;this.mechanisms[t.mechname]=t}disconnect(e){if(this._changeConnectStatus(le.Status.DISCONNECTING,e),e?le.warn("Disconnect was called because: "+e):le.info("Disconnect was called"),this.connected){let e=!1;this.disconnecting=!0,this.authenticated&&(e=ce({xmlns:le.NS.CLIENT,type:"unavailable"})),this._disconnectTimeout=this._addSysTimedHandler(3e3,this._onDisconnectTimeout.bind(this)),this._proto._disconnect(e)}else le.warn("Disconnect was called before Strophe connected to the server"),this._proto._abortAllRequests(),this._doDisconnect()}_changeConnectStatus(e,t,n){for(const n in le._connectionPlugins)if(Object.prototype.hasOwnProperty.call(le._connectionPlugins,n)){const s=this[n];if(s.statusChanged)try{s.statusChanged(e,t)}catch(e){le.error(`${n} plugin caused an exception changing status: ${e}`)}}if(this.connect_callback)try{this.connect_callback(e,t,n)}catch(e){le._handleError(e),le.error(`User connection callback caused an exception: ${e}`)}}_doDisconnect(e){"number"==typeof this._idleTimeout&&clearTimeout(this._idleTimeout),null!==this._disconnectTimeout&&(this.deleteTimedHandler(this._disconnectTimeout),this._disconnectTimeout=null),le.debug("_doDisconnect was called"),this._proto._doDisconnect(),this.authenticated=!1,this.disconnecting=!1,this.restored=!1,this.handlers=[],this.timedHandlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._changeConnectStatus(le.Status.DISCONNECTED,e),this.connected=!1}_dataRecv(e,t){const n=this._proto._reqToData(e);if(null===n)return;for(this.xmlInput!==le.Connection.prototype.xmlInput&&(n.nodeName===this._proto.strip&&n.childNodes.length?this.xmlInput(n.childNodes[0]):this.xmlInput(n)),this.rawInput!==le.Connection.prototype.rawInput&&(t?this.rawInput(t):this.rawInput(le.serialize(n)));this.removeHandlers.length>0;){const e=this.removeHandlers.pop(),t=this.handlers.indexOf(e);t>=0&&this.handlers.splice(t,1)}for(;this.addHandlers.length>0;)this.handlers.push(this.addHandlers.pop());if(this.disconnecting&&this._proto._emptyQueue())return void this._doDisconnect();const s=n.getAttribute("type");if(null!==s&&"terminate"===s){if(this.disconnecting)return;let e=n.getAttribute("condition");const t=n.getElementsByTagName("conflict");return null!==e?("remote-stream-error"===e&&t.length>0&&(e="conflict"),this._changeConnectStatus(le.Status.CONNFAIL,e)):this._changeConnectStatus(le.Status.CONNFAIL,le.ErrorCondition.UNKOWN_REASON),void this._doDisconnect(e)}le.forEachChild(n,null,(e=>{const t=this.handlers;this.handlers=[];for(let n=0;n0:s.getElementsByTagName("stream:features").length>0||s.getElementsByTagName("features").length>0,!i)return void this._proto._no_auth_received(t);const r=Array.from(s.getElementsByTagName("mechanism")).map((e=>this.mechanisms[e.textContent])).filter((e=>e));0!==r.length||0!==s.getElementsByTagName("auth").length?!1!==this.do_authentication&&this.authenticate(r):this._proto._no_auth_received(t)}sortMechanismsByPriority(e){for(let t=0;te[n].priority&&(n=s);if(n!==t){const s=e[t];e[t]=e[n],e[n]=s}}return e}authenticate(e){this._attemptSASLAuth(e)||this._attemptLegacyAuth()}_attemptSASLAuth(e){e=this.sortMechanismsByPriority(e||[]);let t=!1;for(let n=0;n{for(;e.length;)this.deleteHandler(e.pop());return this._onStreamFeaturesAfterSASL(t),!1};return t.push(this._addSysHandler((e=>n(t,e)),null,"stream:features",null,null)),t.push(this._addSysHandler((e=>n(t,e)),le.NS.STREAM,"features",null,null)),this._sendRestart(),!1}_onStreamFeaturesAfterSASL(e){this.features=e;for(let t=0;t0&&(t=le.ErrorCondition.CONFLICT),this._changeConnectStatus(le.Status.AUTHFAIL,t,e),!1}const t=e.getElementsByTagName("bind");if(!(t.length>0))return le.warn("Resource binding failed."),this._changeConnectStatus(le.Status.AUTHFAIL,null,e),!1;{const e=t[0].getElementsByTagName("jid");e.length>0&&(this.authenticated=!0,this.jid=le.getText(e[0]),this.do_session?this._establishSession():this._changeConnectStatus(le.Status.CONNECTED,null))}}_establishSession(){if(!this.do_session)throw new Error(`Strophe.Connection.prototype._establishSession called but apparently ${le.NS.SESSION} wasn't advertised by the server`);this._addSysHandler(this._onSessionResultIQ.bind(this),null,null,null,"_session_auth_2"),this.send(ae({type:"set",id:"_session_auth_2"}).c("session",{xmlns:le.NS.SESSION}).tree())}_onSessionResultIQ(e){if("result"===e.getAttribute("type"))this.authenticated=!0,this._changeConnectStatus(le.Status.CONNECTED,null);else if("error"===e.getAttribute("type"))return this.authenticated=!1,le.warn("Session creation failed."),this._changeConnectStatus(le.Status.AUTHFAIL,null,e),!1;return!1}_sasl_failure_cb(e){return this._sasl_success_handler&&(this.deleteHandler(this._sasl_success_handler),this._sasl_success_handler=null),this._sasl_challenge_handler&&(this.deleteHandler(this._sasl_challenge_handler),this._sasl_challenge_handler=null),this._sasl_mechanism&&this._sasl_mechanism.onFailure(),this._changeConnectStatus(le.Status.AUTHFAIL,null,e),!1}_auth2_cb(e){return"result"===e.getAttribute("type")?(this.authenticated=!0,this._changeConnectStatus(le.Status.CONNECTED,null)):"error"===e.getAttribute("type")&&(this._changeConnectStatus(le.Status.AUTHFAIL,null,e),this.disconnect("authentication failed")),!1}_addSysTimedHandler(e,t){const n=new le.TimedHandler(e,t);return n.user=!1,this.addTimeds.push(n),n}_addSysHandler(e,t,n,s,i){const r=new le.Handler(e,t,n,s,i);return r.user=!1,this.addHandlers.push(r),r}_onDisconnectTimeout(){return le.debug("_onDisconnectTimeout was called"),this._changeConnectStatus(le.Status.CONNTIMEOUT,null),this._proto._onDisconnectTimeout(),this._doDisconnect(),!1}_onIdle(){for(;this.addTimeds.length>0;)this.timedHandlers.push(this.addTimeds.pop());for(;this.removeTimeds.length>0;){const e=this.removeTimeds.pop(),t=this.timedHandlers.indexOf(e);t>=0&&this.timedHandlers.splice(t,1)}const e=(new Date).getTime(),t=[];for(let n=0;nthis._onIdle()),100))}},le.SASLMechanism=W,le.SASLAnonymous=class extends W{constructor(e="ANONYMOUS",t=!1,n=20){super(e,t,n)}test(e){return null===e.authcid}},le.SASLPlain=class extends W{constructor(e="PLAIN",t=!0,n=50){super(e,t,n)}test(e){return null!==e.authcid}onChallenge(e){const{authcid:t,authzid:n,domain:s,pass:i}=e;if(!s)throw new Error("SASLPlain onChallenge: domain is not defined!");let r=n!==`${t}@${s}`?n:"";return r+="\0",r+=t,r+="\0",r+=i,V(r)}},le.SASLSHA1=class extends W{constructor(e="SCRAM-SHA-1",t=!0,n=60){super(e,t,n)}test(e){return null!==e.authcid}onChallenge(e,t){let n,s,i,r,o,a,c,l,d="c=biws,",u=`${e._sasl_data["client-first-message-bare"]},${t},`;const h=e._sasl_data.cnonce,m=/([a-z]+)=([^,]+)(,|$)/;for(;t.match(m);){const e=t.match(m);switch(t=t.replace(e[0],""),e[1]){case"r":n=e[2];break;case"s":s=e[2];break;case"i":i=e[2]}}if(n.substr(0,h.length)!==h)return e._sasl_data={},e._sasl_failure_cb();d+="r="+n,u+=d,s=atob(s),s+="\0\0\0";const f=V(e.pass);for(r=a=se.core_hmac_sha1(f,s),c=1;c0&&(t="conflict"),this._conn._changeConnectStatus(le.Status.CONNFAIL,t)):this._conn._changeConnectStatus(le.Status.CONNFAIL,"unknown"),this._conn._doDisconnect(t),le.Status.CONNFAIL}this.sid||(this.sid=e.getAttribute("sid"));const n=e.getAttribute("requests");n&&(this.window=parseInt(n,10));const s=e.getAttribute("hold");s&&(this.hold=parseInt(s,10));const i=e.getAttribute("wait");i&&(this.wait=parseInt(i,10));const r=e.getAttribute("inactivity");r&&(this.inactivity=parseInt(r,10))}_disconnect(e){this._sendTerminate(e)}_doDisconnect(){this.sid=null,this.rid=Math.floor(4294967295*Math.random()),this._conn._sessionCachingSupported()&&window.sessionStorage.removeItem("strophe-bosh-session"),this._conn.nextValidRid(this.rid)}_emptyQueue(){return 0===this._requests.length}_callProtocolErrorHandlers(t){const n=e._getRequestStatus(t),s=this._conn.protocolErrorHandlers.HTTP[n];s&&s.call(this,n)}_hitError(e){this.errors++,le.warn("request errored, status: "+e+", number of errors: "+this.errors),this.errors>4&&this._conn._onDisconnectTimeout()}_no_auth_received(e){le.warn("Server did not yet offer a supported authentication mechanism. Sending a blank poll request."),e=e?e.bind(this._conn):this._conn._connect_cb.bind(this._conn);const t=this._buildBody();this._requests.push(new le.Request(t.tree(),this._onRequestStateChange.bind(this,e),t.tree().getAttribute("rid"))),this._throttledRequestHandler()}_onDisconnectTimeout(){this._abortAllRequests()}_abortAllRequests(){for(;this._requests.length>0;){const e=this._requests.pop();e.abort=!0,e.xhr.abort(),e.xhr.onreadystatechange=function(){}}}_onIdle(){const e=this._conn._data;if(this._conn.authenticated&&0===this._requests.length&&0===e.length&&!this._conn.disconnecting&&(le.debug("no requests during idle cycle, sending blank request"),e.push(null)),!this._conn.paused){if(this._requests.length<2&&e.length>0){const t=this._buildBody();for(let n=0;n0){const e=this._requests[0].age();null!==this._requests[0].dead&&this._requests[0].timeDead()>Math.floor(le.SECONDARY_TIMEOUT*this.wait)&&this._throttledRequestHandler(),e>Math.floor(le.TIMEOUT*this.wait)&&(le.warn("Request "+this._requests[0].id+" timed out, over "+Math.floor(le.TIMEOUT*this.wait)+" seconds since last activity"),this._throttledRequestHandler())}}}static _getRequestStatus(e,t){let n;if(4===e.xhr.readyState)try{n=e.xhr.status}catch(e){le.error("Caught an error while retrieving a request's status, reqStatus: "+n)}return void 0===n&&(n="number"==typeof t?t:0),n}_onRequestStateChange(t,n){if(le.debug("request id "+n.id+"."+n.sends+" state changed to "+n.xhr.readyState),n.abort)return void(n.abort=!1);if(4!==n.xhr.readyState)return;const s=e._getRequestStatus(n);if(this.lastResponseHeaders=n.xhr.getAllResponseHeaders(),this._conn.disconnecting&&s>=400)return this._hitError(s),void this._callProtocolErrorHandlers(n);const i=s>0&&s<500,r=n.sends>this._conn.maxRetries;if((i||r)&&(this._removeRequest(n),le.debug("request id "+n.id+" should now be removed")),200===s){const e=this._requests[0]===n;(this._requests[1]===n||e&&this._requests.length>0&&this._requests[0].age()>Math.floor(le.SECONDARY_TIMEOUT*this.wait))&&this._restartRequest(0),this._conn.nextValidRid(Number(n.rid)+1),le.debug("request id "+n.id+"."+n.sends+" got 200"),t(n),this.errors=0}else 0===s||s>=400&&s<600||s>=12e3?(le.error("request id "+n.id+"."+n.sends+" error "+s+" happened"),this._hitError(s),this._callProtocolErrorHandlers(n),s>=400&&s<500&&(this._conn._changeConnectStatus(le.Status.DISCONNECTING,null),this._conn._doDisconnect())):le.error("request id "+n.id+"."+n.sends+" error "+s+" happened");i||r?r&&!this._conn.connected&&this._conn._changeConnectStatus(le.Status.CONNFAIL,"giving-up"):this._throttledRequestHandler()}_processRequest(t){let n=this._requests[t];const s=e._getRequestStatus(n,-1);if(n.sends>this._conn.maxRetries)return void this._conn._onDisconnectTimeout();const i=n.age(),r=!isNaN(i)&&i>Math.floor(le.TIMEOUT*this.wait),o=null!==n.dead&&n.timeDead()>Math.floor(le.SECONDARY_TIMEOUT*this.wait),a=4===n.xhr.readyState&&(s<1||s>=500);if((r||o||a)&&(o&&le.error(`Request ${this._requests[t].id} timed out (secondary), restarting`),n.abort=!0,n.xhr.abort(),n.xhr.onreadystatechange=function(){},this._requests[t]=new le.Request(n.xmlData,n.origFunc,n.rid,n.sends),n=this._requests[t]),0===n.xhr.readyState){le.debug("request id "+n.id+"."+n.sends+" posting");try{const e=this._conn.options.contentType||"text/xml; charset=utf-8";n.xhr.open("POST",this._conn.service,!this._conn.options.sync),void 0!==n.xhr.setRequestHeader&&n.xhr.setRequestHeader("Content-Type",e),this._conn.options.withCredentials&&(n.xhr.withCredentials=!0)}catch(e){return le.error("XHR open failed: "+e.toString()),this._conn.connected||this._conn._changeConnectStatus(le.Status.CONNFAIL,"bad-service"),void this._conn.disconnect()}const e=()=>{if(n.date=new Date,this._conn.options.customHeaders){const e=this._conn.options.customHeaders;for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&n.xhr.setRequestHeader(t,e[t])}n.xhr.send(n.data)};if(n.sends>1){const t=1e3*Math.min(Math.floor(le.TIMEOUT*this.wait),Math.pow(n.sends,3));setTimeout((function(){e()}),t)}else e();n.sends++,this._conn.xmlOutput!==le.Connection.prototype.xmlOutput&&(n.xmlData.nodeName===this.strip&&n.xmlData.childNodes.length?this._conn.xmlOutput(n.xmlData.childNodes[0]):this._conn.xmlOutput(n.xmlData)),this._conn.rawOutput!==le.Connection.prototype.rawOutput&&this._conn.rawOutput(n.data)}else le.debug("_processRequest: "+(0===t?"first":"second")+" request has readyState of "+n.xhr.readyState)}_removeRequest(e){le.debug("removing request");for(let t=this._requests.length-1;t>=0;t--)e===this._requests[t]&&this._requests.splice(t,1);e.xhr.onreadystatechange=function(){},this._throttledRequestHandler()}_restartRequest(e){const t=this._requests[e];null===t.dead&&(t.dead=new Date),this._processRequest(e)}_reqToData(e){try{return e.getResponse()}catch(e){if("parsererror"!==e.message)throw e;this._conn.disconnect("strophe-parsererror")}}_sendTerminate(e){le.debug("_sendTerminate was called");const t=this._buildBody().attrs({type:"terminate"});e&&t.cnode(e.tree());const n=new le.Request(t.tree(),this._onRequestStateChange.bind(this,this._conn._dataRecv.bind(this._conn)),t.tree().getAttribute("rid"));this._requests.push(n),this._throttledRequestHandler()}_send(){clearTimeout(this._conn._idleTimeout),this._throttledRequestHandler(),this._conn._idleTimeout=setTimeout((()=>this._conn._onIdle()),100)}_sendRestart(){this._throttledRequestHandler(),clearTimeout(this._conn._idleTimeout)}_throttledRequestHandler(){this._requests?le.debug("_throttledRequestHandler called with "+this._requests.length+" requests"):le.debug("_throttledRequestHandler called with undefined requests"),this._requests&&0!==this._requests.length&&(this._requests.length>0&&this._processRequest(0),this._requests.length>1&&Math.abs(this._requests[0].rid-this._requests[1].rid)this._onOpen(),this.socket.onerror=e=>this._onError(e),this.socket.onclose=e=>this._onClose(e),this.socket.onmessage=e=>this._onInitialMessage(e)}_connect_cb(e){if(this._checkStreamError(e,le.Status.CONNFAIL))return le.Status.CONNFAIL}_handleStreamStart(e){let t=!1;const n=e.getAttribute("xmlns");"string"!=typeof n?t="Missing xmlns in ":n!==le.NS.FRAMING&&(t="Wrong xmlns in : "+n);const s=e.getAttribute("version");return"string"!=typeof s?t="Missing version in ":"1.0"!==s&&(t="Wrong version in : "+s),!t||(this._conn._changeConnectStatus(le.Status.CONNFAIL,t),this._conn._doDisconnect(),!1)}_onInitialMessage(e){if(0===e.data.indexOf("\s*)*/,"");if(""===t)return;const n=(new D).parseFromString(t,"text/xml").documentElement;this._conn.xmlInput(n),this._conn.rawInput(e.data),this._handleStreamStart(n)&&this._connect_cb(n)}else if(0===e.data.indexOf("=0&&n.indexOf("wss:")>=0||e.indexOf("ws:")>=0)&&(this._conn._changeConnectStatus(le.Status.REDIRECT,"Received see-other-uri, resetting connection"),this._conn.reset(),this._conn.service=n,this._connect())}else this._conn._changeConnectStatus(le.Status.CONNFAIL,"Received closing stream"),this._conn._doDisconnect()}else{this._replaceMessageHandler();const t=this._streamWrap(e.data),n=(new D).parseFromString(t,"text/xml").documentElement;this._conn._connect_cb(n,null,e.data)}}_replaceMessageHandler(){this.socket.onmessage=e=>this._onMessage(e)}_disconnect(e){if(this.socket&&this.socket.readyState!==R.CLOSED){e&&this._conn.send(e);const t=re("close",{xmlns:le.NS.FRAMING});this._conn.xmlOutput(t.tree());const n=le.serialize(t);this._conn.rawOutput(n);try{this.socket.send(n)}catch(e){le.warn("Couldn't send tag.")}}setTimeout((()=>this._conn._doDisconnect),0)}_doDisconnect(){le.debug("WebSockets _doDisconnect was called"),this._closeSocket()}_streamWrap(e){return""+e+""}_closeSocket(){if(this.socket)try{this.socket.onclose=null,this.socket.onerror=null,this.socket.onmessage=null,this.socket.close()}catch(e){le.debug(e.message)}this.socket=null}_emptyQueue(){return!0}_onClose(e){this._conn.connected&&!this._conn.disconnecting?(le.error("Websocket closed unexpectedly"),this._conn._doDisconnect()):e&&1006===e.code&&!this._conn.connected&&this.socket?(le.error("Websocket closed unexcectedly"),this._conn._changeConnectStatus(le.Status.CONNFAIL,"The WebSocket connection could not be established or was disconnected."),this._conn._doDisconnect()):le.debug("Websocket closed")}_no_auth_received(e){le.error("Server did not offer a supported authentication mechanism"),this._conn._changeConnectStatus(le.Status.CONNFAIL,le.ErrorCondition.NO_AUTH_MECH),e&&e.call(this._conn),this._conn._doDisconnect()}_onDisconnectTimeout(){}_abortAllRequests(){}_onError(e){le.error("Websocket error "+e),this._conn._changeConnectStatus(le.Status.CONNFAIL,"The WebSocket connection could not be established or was disconnected."),this._disconnect()}_onIdle(){const e=this._conn._data;if(e.length>0&&!this._conn.paused){for(let t=0;t{var t;null===(t=console)||void 0===t||t.error(e),le.log(le.LogLevel.ERROR,`Shared Worker Error: ${e}`)}}get socket(){return{send:e=>this.worker.port.postMessage(["send",e])}}_connect(){this._messageHandler=e=>this._onInitialMessage(e),this.worker.port.start(),this.worker.port.onmessage=e=>this._onWorkerMessage(e),this.worker.port.postMessage(["_connect",this._conn.service,this._conn.jid])}_attach(e){this._messageHandler=e=>this._onMessage(e),this._conn.connect_callback=e,this.worker.port.start(),this.worker.port.onmessage=e=>this._onWorkerMessage(e),this.worker.port.postMessage(["_attach",this._conn.service])}_attachCallback(e,t){e===le.Status.ATTACHED?(this._conn.jid=t,this._conn.authenticated=!0,this._conn.connected=!0,this._conn.restored=!0,this._conn._changeConnectStatus(le.Status.ATTACHED)):e===le.Status.ATTACHFAIL&&(this._conn.authenticated=!1,this._conn.connected=!1,this._conn.restored=!1,this._conn._changeConnectStatus(le.Status.ATTACHFAIL))}_disconnect(e,t){t&&this._conn.send(t);const n=re("close",{xmlns:le.NS.FRAMING});this._conn.xmlOutput(n.tree());const s=le.serialize(n);this._conn.rawOutput(s),this.worker.port.postMessage(["send",s]),this._conn._doDisconnect()}_onClose(e){this._conn.connected&&!this._conn.disconnecting?(le.error("Websocket closed unexpectedly"),this._conn._doDisconnect()):e&&1006===e.code&&!this._conn.connected?(le.error("Websocket closed unexcectedly"),this._conn._changeConnectStatus(le.Status.CONNFAIL,"The WebSocket connection could not be established or was disconnected."),this._conn._doDisconnect()):le.debug("Websocket closed")}_closeSocket(){this.worker.port.postMessage(["_closeSocket"])}_replaceMessageHandler(){this._messageHandler=e=>this._onMessage(e)}_onWorkerMessage(e){const{data:t}=e,n=t[0];if("_onMessage"===n)this._messageHandler(t[1]);else if(n in this)try{this[n].apply(this,e.data.slice(1))}catch(e){le.log(le.LogLevel.ERROR,e)}else if("log"===n){const e=t[1],n=t[2];le.log(ue[e],n)}else le.log(le.LogLevel.ERROR,`Found unhandled service worker message: ${t}`)}},n.g.$build=de.$build,n.g.$iq=de.$iq,n.g.$msg=de.$msg,n.g.$pres=de.$pres,n.g.Strophe=de.Strophe;const{b64_sha1:he}=se,me={};me[le.Status.ATTACHED]="ATTACHED",me[le.Status.AUTHENTICATING]="AUTHENTICATING",me[le.Status.AUTHFAIL]="AUTHFAIL",me[le.Status.CONNECTED]="CONNECTED",me[le.Status.CONNECTING]="CONNECTING",me[le.Status.CONNFAIL]="CONNFAIL",me[le.Status.DISCONNECTED]="DISCONNECTED",me[le.Status.DISCONNECTING]="DISCONNECTING",me[le.Status.ERROR]="ERROR",me[le.Status.RECONNECTING]="RECONNECTING",me[le.Status.REDIRECT]="REDIRECT";const fe=["converse-adhoc","converse-bookmarks","converse-bosh","converse-caps","converse-carbons","converse-chat","converse-chatboxes","converse-disco","converse-emoji","converse-headlines","converse-mam","converse-muc","converse-ping","converse-pubsub","converse-roster","converse-smacks","converse-status","converse-vcard"],ge={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|xmpp:|mailto:|www\.)/gi},pe=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)},ve=function(e){if(!pe(e))return!1;var t=b(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t},be=d["__core-js_shared__"];var ye,_e=(ye=/[^.]+$/.exec(be&&be.keys&&be.keys.IE_PROTO||""))?"Symbol(src)_1."+ye:"";var we=Function.prototype.toString;const Se=function(e){if(null!=e){try{return we.call(e)}catch(e){}try{return e+""}catch(e){}}return""};var xe=/^\[object .+?Constructor\]$/,Ee=Function.prototype,Ae=Object.prototype,Ce=Ee.toString,Te=Ae.hasOwnProperty,ke=RegExp("^"+Ce.call(Te).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const je=function(e){return!(!pe(e)||(t=e,_e&&_e in t))&&(ve(e)?ke:xe).test(Se(e));var t},Ne=function(e,t){var n=function(e,t){return null==e?void 0:e[t]}(e,t);return je(n)?n:void 0},Oe=function(){try{var e=Ne(Object,"defineProperty");return e({},"",{}),e}catch(e){}}(),$e=function(e,t,n){"__proto__"==t&&Oe?Oe(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n},Ie=function(e,t){return e===t||e!=e&&t!=t};var Me=Object.prototype.hasOwnProperty;const Re=function(e,t,n){var s=e[t];Me.call(e,t)&&Ie(s,n)&&(void 0!==n||t in e)||$e(e,t,n)},De=function(e,t,n,s){var i=!n;n||(n={});for(var r=-1,o=t.length;++r0){if(++We>=800)return arguments[0]}else We=0;return Ge.apply(void 0,arguments)});var Ge,We,Ve;const Je=function(e,t){return He(Fe(e,t,Le),e+"")},Ke=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991},Ye=function(e){return null!=e&&Ke(e.length)&&!ve(e)};var Qe=/^(?:0|[1-9]\d*)$/;const Xe=function(e,t){var n=typeof e;return!!(t=null==t?9007199254740991:t)&&("number"==n||"symbol"!=n&&Qe.test(e))&&e>-1&&e%1==0&&e1?n[i-1]:void 0,o=i>2?n[2]:void 0;for(r=e.length>3&&"function"==typeof r?(i--,r):void 0,o&&Ze(n[0],n[1],o)&&(r=i<3?void 0:r,i=1),t=Object(t);++s-1},Nt.prototype.set=function(e,t){var n=this.__data__,s=kt(n,e);return s<0?(++this.size,n.push([e,t])):n[s][1]=t,this};const Ot=Nt,$t=Ne(d,"Map"),It=Ne(Object,"create");var Mt=Object.prototype.hasOwnProperty;var Rt=Object.prototype.hasOwnProperty;function Dt(e){var t=-1,n=null==e?0:e.length;for(this.clear();++ta))return!1;var l=r.get(e),d=r.get(t);if(l&&d)return l==t&&d==e;var u=-1,h=!0,m=2&n?new Ht:void 0;for(r.set(e,t),r.set(t,e);++u0&&(n=t.apply(this,arguments)),e<=1&&(t=void 0),n}}(2,e)};var Cs=0;const Ts=function(e){var t=++Cs;return Qn(e)+t},ks={},js=/\s+/;let Ns;const Os=function(e,t,n,s,i){let r,o=0;if(n&&"object"==typeof n){void 0!==s&&"context"in i&&void 0===i.context&&(i.context=s);for(r=cn(n);o{e.resolve=t,e.reject=n}));return Object.assign(t,e),t.then((function(e){return t.isResolved=!0,t.isPending=!1,t.isRejected=!1,e}),(function(e){throw t.isResolved=!1,t.isPending=!1,t.isRejected=!0,e})),t}function Js(){throw new Error('A "url" property or function must be specified')}function Ks(e,t){const n=t.error;t.error=function(s){n&&n.call(t.context,e,s,t),e.trigger("error",e,s,t)}}Error;const Ys={create:"POST",update:"PUT",patch:"PATCH",delete:"DELETE",read:"GET"};function Qs(e){const t=Gs(e,"browserStorage")||Gs(e.collection,"browserStorage");return t?t.sync():Xs}function Xs(e,t,n={}){const s={type:Ys[e],dataType:"json"};n.url||(s.url=Gs(t,"url")||Js()),null!=n.data||!t||"create"!==e&&"update"!==e&&"patch"!==e||(s.contentType="application/json",s.data=JSON.stringify(n.attrs||t.toJSON(n))),"GET"!==s.type&&(s.processData=!1);const i=n.error;n.error=function(e,t,s){n.textStatus=t,n.errorThrown=s,i&&i.call(n.context,e,t,s)};const r=n.xhr=function(){return fetch.apply(this,arguments)}(Ct(s,n));return t.trigger("request",t,r,n),r}const Zs=function(){this.handlers=[],this.checkUrl=this.checkUrl.bind(this),"undefined"!=typeof window&&(this.location=window.location,this.history=window.history)};Zs.extend=Ws;const ei=/^[#\/]|\s+$/g,ti=/^\/+|\/+$/g,ni=/#.*$/;Zs.started=!1,Object.assign(Zs.prototype,ks,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root&&!this.getSearch()},matchRoot:function(){return this.decodeFragment(this.location.pathname).slice(0,this.root.length-1)+"/"===this.root},decodeFragment:function(e){return decodeURI(e.replace(/%25/g,"%2525"))},getSearch:function(){const e=this.location.href.replace(/#.*/,"").match(/\?.+/);return e?e[0]:""},getHash:function(e){const t=(e||this).location.href.match(/#(.*)$/);return t?t[1]:""},getPath:function(){const e=this.decodeFragment(this.location.pathname+this.getSearch()).slice(this.root.length-1);return"/"===e.charAt(0)?e.slice(1):e},getFragment:function(e){return null==e&&(e=this._usePushState||!this._wantsHashChange?this.getPath():this.getHash()),e.replace(ei,"")},start:function(e){if(Zs.started)throw new Error("history has already been started");if(Zs.started=!0,this.options=Ct({root:"/"},this.options,e),this.root=this.options.root,this._wantsHashChange=!1!==this.options.hashChange,this._hasHashChange="onhashchange"in window&&(void 0===document.documentMode||document.documentMode>7),this._useHashChange=this._wantsHashChange&&this._hasHashChange,this._wantsPushState=!!this.options.pushState,this._hasPushState=!(!this.history||!this.history.pushState),this._usePushState=this._wantsPushState&&this._hasPushState,this.fragment=this.getFragment(),this.root=("/"+this.root+"/").replace(ti,"/"),this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){const e=this.root.slice(0,-1)||"/";return this.location.replace(e+"#"+this.getPath()),!0}this._hasPushState&&this.atRoot()&&this.navigate(this.getHash(),{replace:!0})}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe"),this.iframe.src="javascript:0",this.iframe.style.display="none",this.iframe.tabIndex=-1;const e=document.body,t=e.insertBefore(this.iframe,e.firstChild).contentWindow;t.document.open(),t.document.close(),t.location.hash="#"+this.fragment}if(this._usePushState?addEventListener("popstate",this.checkUrl,!1):this._useHashChange&&!this.iframe?addEventListener("hashchange",this.checkUrl,!1):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval)),!this.options.silent)return this.loadUrl()},stop:function(){this._usePushState?removeEventListener("popstate",this.checkUrl,!1):this._useHashChange&&!this.iframe&&removeEventListener("hashchange",this.checkUrl,!1),this.iframe&&(document.body.removeChild(this.iframe),this.iframe=null),this._checkUrlInterval&&clearInterval(this._checkUrlInterval),Zs.started=!1},route:function(e,t){this.handlers.unshift({route:e,callback:t})},checkUrl:function(e){let t=this.getFragment();if(t===this.fragment&&this.iframe&&(t=this.getHash(this.iframe.contentWindow)),t===this.fragment)return!1;this.iframe&&this.navigate(t),this.loadUrl()},loadUrl:function(e){return!!this.matchRoot()&&(e=this.fragment=this.getFragment(e),hs(this.handlers,(function(t){if(t.route.test(e))return t.callback(e),!0})))},navigate:function(e,t){if(!Zs.started)return!1;t&&!0!==t||(t={trigger:!!t}),e=this.getFragment(e||"");let n=this.root;""!==e&&"?"!==e.charAt(0)||(n=n.slice(0,-1)||"/");const s=n+e;e=e.replace(ni,"");const i=this.decodeFragment(e);if(this.fragment!==i){if(this.fragment=i,this._usePushState)this.history[t.replace?"replaceState":"pushState"]({},document.title,s);else{if(!this._wantsHashChange)return this.location.assign(s);if(this._updateHash(this.location,e,t.replace),this.iframe&&e!==this.getHash(this.iframe.contentWindow)){const n=this.iframe.contentWindow;t.replace||(n.document.open(),n.document.close()),this._updateHash(n.location,e,t.replace)}}return t.trigger?this.loadUrl(e):void 0}},_updateHash:function(e,t,n){if(n){const n=e.href.replace(/(javascript:|#).*$/,"");e.replace(n+"#"+t)}else e.hash="#"+t}});const si=Zs;var ii=pt&&pt.isRegExp;const ri=ii?ht(ii):function(e){return a(e)&&"[object RegExp]"==b(e)},oi=function(e={}){this.history=e.history||new si,this.preinitialize.apply(this,arguments),e.routes&&(this.routes=e.routes),this._bindRoutes(),this.initialize.apply(this,arguments)};oi.extend=Ws;const ai=/\((.*?)\)/g,ci=/(\(\?)?:\w+/g,li=/\*\w+/g,di=/[\-{}\[\]+?.,\\\^$|#\s]/g;Object.assign(oi.prototype,ks,{preinitialize:function(){},initialize:function(){},route:function(e,t,n){return ri(e)||(e=this._routeToRegExp(e)),ve(t)&&(n=t,t=""),n||(n=this[t]),this.history.route(e,(s=>{const i=this._extractParameters(e,s);!1!==this.execute(n,i,t)&&(this.trigger.apply(this,["route:"+t].concat(i)),this.trigger("route",t,i),this.history.trigger("route",this,t,i))})),this},execute:function(e,t,n){e&&e.apply(this,t)},navigate:function(e,t){return this.history.navigate(e,t),this},_bindRoutes:function(){if(!this.routes)return;let e;this.routes=Gs(this,"routes");const t=cn(this.routes);for(;null!=(e=t.pop());)this.route(e,this.routes[e])},_routeToRegExp:function(e){return e=e.replace(di,"\\$&").replace(ai,"(?:$1)?").replace(ci,(function(e,t){return t?e:"([^/?]+)"})).replace(li,"([^?]*?)"),new RegExp("^"+e+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(e,t){const n=e.exec(t).slice(1);return n.map((function(e,t){return t===n.length-1?e||null:e?decodeURIComponent(e):null}))}});class ui extends Error{}const hi=function(e,t,n){(void 0!==n&&!Ie(e[t],n)||void 0===n&&!(t in e))&&$e(e,t,n)};var mi="object"==typeof exports&&exports&&!exports.nodeType&&exports,fi=mi&&"object"==typeof module&&module&&!module.nodeType&&module,gi=fi&&fi.exports===mi?d.Buffer:void 0,pi=gi?gi.allocUnsafe:void 0;const vi=function(e,t){if(t)return e.slice();var n=e.length,s=pi?pi(n):new e.constructor(n);return e.copy(s),s},bi=function(e){var t=new e.constructor(e.byteLength);return new Vt(t).set(new Vt(e)),t},yi=function(e,t){var n=t?bi(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)},_i=function(e,t){var n=-1,s=e.length;for(t||(t=Array(s));++n{e.resolve=t,e.reject=n}));return Object.assign(t,e),t.then((function(e){return t.isResolved=!0,t.isPending=!1,t.isRejected=!1,e}),(function(e){throw t.isResolved=!1,t.isPending=!1,t.isRejected=!0,e})),t}const Ni=Math.max,Oi=Math.min,$i=function(e,t,n={}){let s,i,r,o,a,c,l=0,d=!1,u=n.promise?ji():null;if("function"!=typeof e)throw new TypeError("Expected a function");function h(t){const r=s,a=i;return s=i=void 0,l=t,o=e.apply(a,r),n.promise&&(u.resolve(o),u=ji()),n.promise?u:o}function m(e){return l=e,a=setTimeout(g,t),n.promise?u:o}function f(e){const n=e-c;return void 0===c||n>=t||n<0||d&&e-l>=r}function g(){const e=ki();if(f(e))return p(e);a=setTimeout(g,function(e){const n=t-(e-c);return d?Oi(n,r-(e-l)):n}(e))}function p(e){return a=void 0,s?h(e):(s=i=void 0,n.promise?u:o)}function v(e,t){if(Array.isArray(e)&&Array.isArray(t))return null!=n&&n.dedupeArrays?e.concat(t.filter((t=>-1===e.indexOf(t)))):e.concat(t)}function b(e){var t;return null!==(t=s)&&void 0!==t&&t.length?e.length?null!=n&&n.concatArrays||null!=n&&n.dedupeArrays?Ti(s,e,v):Ci(s,e):s:e||[]}function y(){const e=ki(),r=f(e);if(s=b(Array.from(arguments)),i=this,c=e,r){if(void 0===a)return m(c);if(d)return clearTimeout(a),a=setTimeout(g,t),h(c)}return void 0===a&&(a=setTimeout(g,t)),n.promise?u:o}return t=Ss(t)||0,pe(n)&&(d="maxWait"in n,r=d?Ni(Ss(n.maxWait)||0,t):r),y.cancel=function(){void 0!==a&&clearTimeout(a),l=0,s=c=i=a=void 0},y.flush=function(){return void 0===a?o:p(ki())},y},Ii=function(){try{if("undefined"!=typeof indexedDB)return indexedDB;if("undefined"!=typeof webkitIndexedDB)return webkitIndexedDB;if("undefined"!=typeof mozIndexedDB)return mozIndexedDB;if("undefined"!=typeof OIndexedDB)return OIndexedDB;if("undefined"!=typeof msIndexedDB)return msIndexedDB}catch(e){return}}(),Mi=function(e,t){e=e||[],t=t||{};try{return new Blob(e,t)}catch(i){if("TypeError"!==i.name)throw i;for(var n=new("undefined"!=typeof BlobBuilder?BlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder?MozBlobBuilder:WebKitBlobBuilder),s=0;se.db.version;if(s&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),i||n){if(n){var r=e.db.version+1;r>e.version&&(e.version=r)}return!0}return!1}function Zi(e){var t=function(e){for(var t=e.length,n=new ArrayBuffer(t),s=new Uint8Array(n),i=0;i0&&(!e.db||"InvalidStateError"===i.name||"NotFoundError"===i.name))return Ri.resolve().then((()=>{if(!e.db||"NotFoundError"===i.name&&!e.db.objectStoreNames.contains(e.storeName)&&e.version<=e.db.version)return e.db&&(e.version=e.db.version+1),Qi(e)})).then((()=>function(e){Wi(e);for(var t=Bi[e.name],n=t.forages,s=0;s(e.db=t,Xi(e)?Qi(e):t))).then((s=>{e.db=t.db=s;for(var i=0;i{throw Ji(e,t),t}))}(e).then((function(){nr(e,t,n,s-1)})))).catch(n);n(i)}}const sr={_driver:"asyncStorage",_initStorage:function(e){var t=this,n={db:null};if(e)for(var s in e)n[s]=e[s];var i=Bi[n.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},Bi[n.name]=i),i.forages.push(t),t._initReady||(t._initReady=t.ready,t.ready=tr);var r=[];function o(){return Ri.resolve()}for(var a=0;a=43)}})).catch((function(){return!1}))}(e).then((function(e){return Ui=e,Ui}))).then((function(e){return e?t:(n=t,new Ri((function(e,t){var s=new FileReader;s.onerror=t,s.onloadend=function(t){var s=btoa(t.target.result||"");e({__local_forage_encoded_blob:!0,data:s,type:n.type})},s.readAsBinaryString(n)})));var n})):t;var e})).then((function(t){nr(s._dbInfo,Gi,(function(r,o){if(r)return i(r);try{var a=o.objectStore(s._dbInfo.storeName);null===t&&(t=void 0);var c=a.put(t,e);o.oncomplete=function(){void 0===t&&(t=null),n(t)},o.onabort=o.onerror=function(){var e=c.error?c.error:c.transaction.error;i(e)}}catch(e){i(e)}}))})).catch(i)}));return Di(i,n),i},removeItem:function(e,t){var n=this;e=zi(e);var s=new Ri((function(t,s){n.ready().then((function(){nr(n._dbInfo,Gi,(function(i,r){if(i)return s(i);try{var o=r.objectStore(n._dbInfo.storeName).delete(e);r.oncomplete=function(){t()},r.onerror=function(){s(o.error)},r.onabort=function(){var e=o.error?o.error:o.transaction.error;s(e)}}catch(e){s(e)}}))})).catch(s)}));return Di(s,t),s},clear:function(e){var t=this,n=new Ri((function(e,n){t.ready().then((function(){nr(t._dbInfo,Gi,(function(s,i){if(s)return n(s);try{var r=i.objectStore(t._dbInfo.storeName).clear();i.oncomplete=function(){e()},i.onabort=i.onerror=function(){var e=r.error?r.error:r.transaction.error;n(e)}}catch(e){n(e)}}))})).catch(n)}));return Di(n,e),n},length:function(e){var t=this,n=new Ri((function(e,n){t.ready().then((function(){nr(t._dbInfo,Hi,(function(s,i){if(s)return n(s);try{var r=i.objectStore(t._dbInfo.storeName).count();r.onsuccess=function(){e(r.result)},r.onerror=function(){n(r.error)}}catch(e){n(e)}}))})).catch(n)}));return Di(n,e),n},key:function(e,t){var n=this,s=new Ri((function(t,s){e<0?t(null):n.ready().then((function(){nr(n._dbInfo,Hi,(function(i,r){if(i)return s(i);try{var o=r.objectStore(n._dbInfo.storeName),a=!1,c=o.openKeyCursor();c.onsuccess=function(){var n=c.result;n?0===e||a?t(n.key):(a=!0,n.advance(e)):t(null)},c.onerror=function(){s(c.error)}}catch(e){s(e)}}))})).catch(s)}));return Di(s,t),s},keys:function(e){var t=this,n=new Ri((function(e,n){t.ready().then((function(){nr(t._dbInfo,Hi,(function(s,i){if(s)return n(s);try{var r=i.objectStore(t._dbInfo.storeName).openKeyCursor(),o=[];r.onsuccess=function(){var t=r.result;t?(o.push(t.key),t.continue()):e(o)},r.onerror=function(){n(r.error)}}catch(e){n(e)}}))})).catch(n)}));return Di(n,e),n},dropInstance:function(e,t){t=Pi.apply(this,arguments);var n=this.config();(e="function"!=typeof e&&e||{}).name||(e.name=e.name||n.name,e.storeName=e.storeName||n.storeName);var s,i=this;if(e.name){const t=e.name===n.name&&i._dbInfo.db?Ri.resolve(i._dbInfo.db):Yi(e).then((t=>{const n=Bi[e.name],s=n.forages;n.db=t;for(var i=0;i{if(!t.objectStoreNames.contains(e.storeName))return;const n=t.version+1;Wi(e);const s=Bi[e.name],i=s.forages;t.close();for(let e=0;e{const i=Ii.open(e.name,n);i.onerror=e=>{i.result.close(),s(e)},i.onupgradeneeded=()=>{i.result.deleteObjectStore(e.storeName)},i.onsuccess=()=>{const e=i.result;e.close(),t(e)}})).then((e=>{s.db=e;for(let t=0;t{throw(Ji(e,t)||Ri.resolve()).catch((()=>{})),t}))})):t.then((t=>{Wi(e);const n=Bi[e.name],s=n.forages;t.close();for(var i=0;i{var s=Ii.deleteDatabase(e.name);s.onerror=()=>{const e=s.result;e&&e.close(),n(s.error)},s.onblocked=()=>{console.warn('dropInstance blocked for database "'+e.name+'" until all open connections are closed')},s.onsuccess=()=>{const e=s.result;e&&e.close(),t(e)}})).then((e=>{n.db=e;for(var t=0;t{throw(Ji(e,t)||Ri.resolve()).catch((()=>{})),t}))}))}else s=Ri.reject("Invalid arguments");return Di(s,t),s}};var ir="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",rr=/^~~local_forage_type~([^~]+)~/,or="__lfsc__:",ar=or.length,cr="arbf",lr="blob",dr="si08",ur="ui08",hr="uic8",mr="si16",fr="si32",gr="ur16",pr="ui32",vr="fl32",br="fl64",yr=ar+cr.length,_r=Object.prototype.toString;function wr(e){var t,n,s,i,r,o=.75*e.length,a=e.length,c=0;"="===e[e.length-1]&&(o--,"="===e[e.length-2]&&o--);var l=new ArrayBuffer(o),d=new Uint8Array(l);for(t=0;t>4,d[c++]=(15&s)<<4|i>>2,d[c++]=(3&i)<<6|63&r;return l}function Sr(e){var t,n=new Uint8Array(e),s="";for(t=0;t>2],s+=ir[(3&n[t])<<4|n[t+1]>>4],s+=ir[(15&n[t+1])<<2|n[t+2]>>6],s+=ir[63&n[t+2]];return n.length%3==2?s=s.substring(0,s.length-1)+"=":n.length%3==1&&(s=s.substring(0,s.length-2)+"=="),s}const xr={serialize:function(e,t){var n="";if(e&&(n=_r.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===_r.call(e.buffer))){var s,i=or;e instanceof ArrayBuffer?(s=e,i+=cr):(s=e.buffer,"[object Int8Array]"===n?i+=dr:"[object Uint8Array]"===n?i+=ur:"[object Uint8ClampedArray]"===n?i+=hr:"[object Int16Array]"===n?i+=mr:"[object Uint16Array]"===n?i+=gr:"[object Int32Array]"===n?i+=fr:"[object Uint32Array]"===n?i+=pr:"[object Float32Array]"===n?i+=vr:"[object Float64Array]"===n?i+=br:t(new Error("Failed to get type for BinaryArray"))),t(i+Sr(s))}else if("[object Blob]"===n){var r=new FileReader;r.onload=function(){var n="~~local_forage_type~"+e.type+"~"+Sr(this.result);t("__lfsc__:blob"+n)},r.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}},deserialize:function(e){if(e.substring(0,ar)!==or)return JSON.parse(e);var t,n=e.substring(yr),s=e.substring(ar,yr);if(s===lr&&rr.test(n)){var i=n.match(rr);t=i[1],n=n.substring(i[0].length)}var r=wr(n);switch(s){case cr:return r;case lr:return Mi([r],{type:t});case dr:return new Int8Array(r);case ur:return new Uint8Array(r);case hr:return new Uint8ClampedArray(r);case mr:return new Int16Array(r);case gr:return new Uint16Array(r);case fr:return new Int32Array(r);case pr:return new Uint32Array(r);case vr:return new Float32Array(r);case br:return new Float64Array(r);default:throw new Error("Unkown type: "+s)}},stringToBuffer:wr,bufferToString:Sr};function Er(e,t,n,s){e.executeSql(`CREATE TABLE IF NOT EXISTS ${t.storeName} (id INTEGER PRIMARY KEY, key unique, value)`,[],n,s)}function Ar(e,t,n,s,i,r){e.executeSql(n,s,i,(function(e,o){o.code===o.SYNTAX_ERR?e.executeSql("SELECT name FROM sqlite_master WHERE type='table' AND name = ?",[t.storeName],(function(e,a){a.rows.length?r(e,o):Er(e,t,(function(){e.executeSql(n,s,i,r)}),r)}),r):r(e,o)}),r)}function Cr(e,t,n,s){var i=this;e=zi(e);var r=new Ri((function(r,o){i.ready().then((function(){void 0===t&&(t=null);var a=t,c=i._dbInfo;c.serializer.serialize(t,(function(t,l){l?o(l):c.db.transaction((function(n){Ar(n,c,`INSERT OR REPLACE INTO ${c.storeName} (key, value) VALUES (?, ?)`,[e,t],(function(){r(a)}),(function(e,t){o(t)}))}),(function(t){if(t.code===t.QUOTA_ERR){if(s>0)return void r(Cr.apply(i,[e,a,n,s-1]));o(t)}}))}))})).catch(o)}));return Di(r,n),r}function Tr(e){return new Ri((function(t,n){e.transaction((function(s){s.executeSql("SELECT name FROM sqlite_master WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'",[],(function(n,s){for(var i=[],r=0;r0?(this._dbInfo=t,t.serializer=xr,Ri.resolve()):Ri.reject()},_support:function(){try{return"undefined"!=typeof localStorage&&"setItem"in localStorage&&!!localStorage.setItem}catch(e){return!1}}(),iterate:function(e,t){var n=this,s=n.ready().then((function(){for(var t=n._dbInfo,s=t.keyPrefix,i=s.length,r=localStorage.length,o=1,a=0;a=0;n--){var s=localStorage.key(n);0===s.indexOf(e)&&localStorage.removeItem(s)}}));return Di(n,e),n},length:function(e){var t=this.keys().then((function(e){return e.length}));return Di(t,e),t},key:function(e,t){var n=this,s=n.ready().then((function(){var t,s=n._dbInfo;try{t=localStorage.key(e)}catch(e){t=null}return t&&(t=t.substring(s.keyPrefix.length)),t}));return Di(s,t),s},keys:function(e){var t=this,n=t.ready().then((function(){for(var e=t._dbInfo,n=localStorage.length,s=[],i=0;i=0;t--){var n=localStorage.key(t);0===n.indexOf(e)&&localStorage.removeItem(n)}})):Ri.reject("Invalid arguments"),Di(s,t),s}},Or=(e,t)=>e===t||"number"==typeof e&&"number"==typeof t&&isNaN(e)&&isNaN(t),$r=(e,t)=>{const n=e.length;let s=0;for(;s{}))}config(e){if("object"==typeof e){if(this._ready)return new Error("Can't call config() after localforage has been used.");for(let t in e){if("storeName"===t&&(e[t]=e[t].replace(/\W/g,"_")),"version"===t&&"number"!=typeof e[t])return new Error("Database version must be a number.");this._config[t]=e[t]}return!("driver"in e)||!e.driver||this.setDriver(this._config.driver)}return"string"==typeof e?this._config[e]:this._config}defineDriver(e,t,n){const s=new Ri((function(t,n){try{const s=e._driver,i=new Error("Custom driver not compliant; see https://mozilla.github.io/localForage/#definedriver");if(!e._driver)return void n(i);const r=Pr.concat("_initStorage");for(let t=0,s=r.length;t(null===t._ready&&(t._ready=t._initDriver()),t._ready)));return Li(n,e,e),n}setDriver(e,t,n){const s=this;Ir(e)||(e=[e]);const i=this._getSupportedDrivers(e);function r(){s._config.driver=s.driver()}function o(e){return s._extend(e),r(),s._ready=s._initStorage(s._config),s._ready}const a=null!==this._driverSet?this._driverSet.catch((()=>Ri.resolve())):Ri.resolve();return this._driverSet=a.then((()=>{const e=i[0];return s._dbInfo=null,s._ready=null,s.getDriver(e).then((e=>{s._driver=e._driver,r(),s._wrapLibraryMethodsWithReady(),s._initDriver=function(e){return function(){let t=0;return function n(){for(;t{r();const e=new Error("No available storage method found.");return s._driverSet=Ri.reject(e),s._driverSet})),Li(this._driverSet,t,n),this._driverSet}supports(e){return!!Rr[e]}_extend(e){Br(this,e)}_getSupportedDrivers(e){const t=[];for(let n=0,s=e.length;n=0;t--){const n=sessionStorage.key(t);0===n.indexOf(e)&&sessionStorage.removeItem(n)}}));return Di(t,e),t},length:function(e){const t=this.keys().then((function(e){return e.length}));return Di(t,e),t},key:function(e,t){const n=this.ready().then((function(){let t;try{t=sessionStorage.key(e)}catch(e){t=null}return t&&(t=t.substring(lo.keyPrefix.length)),t}));return Di(n,t),n},keys:function(e){const t=this.ready().then((function(){const e=sessionStorage.length,t=[];for(let n=0;n=0;t--){const n=sessionStorage.key(t);0===n.indexOf(e)&&sessionStorage.removeItem(n)}})):Promise.reject(new Error("Invalid arguments")),Di(s,t),s}};var ho=n(1459);const mo=Gr._driver;function fo(){return(65536*(1+Math.random())|0).toString(16).substring(1)}Hr.defineDriver(Gr),(0,ho.extendPrototype)(Hr);class go{constructor(e,t,n=!1){if("local"===t&&!window.localStorage)throw new Error("Skeletor.storage: Environment does not support localStorage.");if("session"===t&&!window.sessionStorage)throw new Error("Skeletor.storage: Environment does not support sessionStorage.");ao(t)?this.storeInitialized=this.initStore(t,n):(this.store=t,n&&(this.store.debouncedSetItems=$i((e=>this.store.setItems(e)),50,{promise:!0})),this.storeInitialized=Promise.resolve()),this.name=e}async initStore(e,t){if("session"===e)Hr.setDriver(uo._driver);else if("local"===e)await Hr.config({driver:Hr.LOCALSTORAGE});else if("in_memory"===e)Hr.config({driver:mo});else if("indexed"!==e)throw new Error("Skeletor.storage: No storage type was specified");this.store=Hr,t&&(this.store.debouncedSetItems=$i((e=>this.store.setItems(e)),50,{promise:!0}))}flush(){var e;return null===(e=this.store.debouncedSetItems)||void 0===e?void 0:e.flush()}async clear(){await this.store.removeItem(this.name).catch((e=>console.error(e)));const e=new RegExp(`^${this.name}-`),t=(await this.store.keys()).filter((t=>e.test(t)));await Promise.all(t.map((e=>this.store.removeItem(e).catch((e=>console.error(e))))))}sync(e){const t=this;async function n(e,n,s){let i,r,o,a;const c=n.collection;var l;["patch","update"].includes(e)&&(l=n.attributes,a=oo(l,5)),await t.storeInitialized;try{const r=n.attributes;switch(e){case"read":i=void 0!==n.id?await t.find(n):await t.findAll();break;case"create":i=await t.create(n,s);break;case"patch":case"update":s.wait&&(n.attributes=a),o=t.update(n,s),s.wait&&(n.attributes=r),i=await o;break;case"delete":i=await t.destroy(n,c)}}catch(e){r=22===e.code&&0===t.getStorageSize()?"Private browsing is unsupported":e.message}if(i){if(s&&s.success){const t="read"===e?i:null;s.success(t,s)}}else r=r||"Record Not Found",s&&s.error&&s.error(r)}return n.__name__="localSync",n}removeCollectionReference(e,t){if(!t)return;const n=t.filter((t=>t.id!==e.id)).map((e=>this.getItemName(e.id)));return this.store.setItem(this.name,n)}addCollectionReference(e,t){if(!t)return;const n=t.map((e=>this.getItemName(e.id))),s=this.getItemName(e.id);return n.includes(s)||n.push(s),this.store.setItem(this.name,n)}getCollectionReferenceData(e){if(!e.collection)return{};const t=e.collection.map((e=>this.getItemName(e.id))),n=this.getItemName(e.id);t.includes(n)||t.push(n);const s={};return s[this.name]=t,s}async save(e){if(this.store.setItems){const t={};return t[this.getItemName(e.id)]=e.toJSON(),Object.assign(t,this.getCollectionReferenceData(e)),this.store.debouncedSetItems?this.store.debouncedSetItems(t):this.store.setItems(t)}{const t=this.getItemName(e.id),n=await this.store.setItem(t,e.toJSON());return await this.addCollectionReference(e,e.collection),n}}create(e,t){return e.id||(e.id=fo()+fo()+"-"+fo()+"-"+fo()+"-"+fo()+"-"+fo()+fo()+fo(),e.set(e.idAttribute,e.id,t)),this.save(e)}update(e){return this.save(e)}find(e){return this.store.getItem(this.getItemName(e.id))}async findAll(){const e=await this.store.getItem(this.name);return e&&e.length?Promise.all(e.map((e=>this.store.getItem(e)))):[]}async destroy(e,t){return await this.flush(),await this.store.removeItem(this.getItemName(e.id)),await this.removeCollectionReference(e,t),e}getStorageSize(){return this.store.length}getItemName(e){return this.name+"-"+e}}go.sessionStorageInitialized=Hr.defineDriver(uo),go.localForage=Hr;const po=go;function vo(){return va.config.get("trusted")?"sessionStorage"===Cl.settings.get("persistent_store")?"session":"persistent":"session"}function bo(e){return"persistent"===e&&"IndexedDB"===Cl.settings.get("persistent_store")}function yo(e,t){const n=t||vo(),s=va.storage[n];if(void 0===s)throw new TypeError(`createStore: Could not find store for ${e}`);return new po(e,s,bo(t))}function _o(e,t,n){const s=n||vo();if(e.browserStorage=va.createStore(t,s),bo(s)){const t=()=>e.browserStorage.flush();window.addEventListener(va.unloadevent,t),e.on("destroy",(()=>window.removeEventListener(va.unloadevent,t))),e.listenTo(va,"beforeLogout",t)}}const wo=function(e,t,n,s){if(!pe(e))return e;for(var i=-1,r=(t=Xn(t,e)).length,o=r-1,a=e;null!=a&&++i0&&s(c)?n>1?e(c,n-1,s,i,r):Xt(r,c):i||(r[r.length]=c)}return r},Co=function(e){return null!=e&&e.length?Ao(e,1):[]},To=function(e){return He(Fe(e,void 0,Co),e+"")},ko=To((function(e,t){return null==e?{}:So(e,t)}));var jo=n(7856),No=n.n(jo);const Oo=function(e){for(var t=-1,n=null==e?0:e.length,s=0,i=[];++t2?t[2]:void 0;for(i&&Ze(t[0],t[1],i)&&(s=1);++n":">",'"':""","'":"'"},function(e){return null==Uo?void 0:Uo[e]});var Uo,Bo=/[&<>"']/g,qo=RegExp(Bo.source);var Ho=Object.prototype.toString;const Go=(Wo=function(e,t,n){null!=t&&"function"!=typeof t.toString&&(t=Ho.call(t)),e[t]=n},Vo=Ue(Le),function(e,t){return function(e,t,n,s){return cs(e,(function(e,i,r){t(s,n(e),i,r)})),s}(e,Wo,Vo(t),{})});var Wo,Vo;const Jo=function(e,t){return $n(e,t)},Ko=function(e,t){return t.length<2?e:es(e,function(e,t,n){var s=-1,i=e.length;t<0&&(t=-t>i?0:i+t),(n=n>i?i:n)<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var r=Array(i);++s1),t})),De(e,Vr(e),n),s&&(n=oo(n,7,Qo));for(var i=t.length;i--;)Yo(n,t[i]);return n})),Zo=function(e,t){let n=e||{};t||(t={}),this.preinitialize.apply(this,arguments),this.cid=Ts(this.cidPrefix),this.attributes={},t.collection&&(this.collection=t.collection),t.parse&&(n=this.parse(n,t)||{});const s=Gs(this,"defaults");n=zo(Ct({},s,n),s),this.set(n,t),this.changed={},this.initialize.apply(this,arguments)};function ea(e){return e instanceof Zo&&(e=e.attributes),!(e.oob_url||e.file||e.is_encrypted&&e.plaintext||e.message)}Zo.extend=Ws,Object.assign(Zo.prototype,ks,{changed:null,validationError:null,idAttribute:"id",cidPrefix:"c",preinitialize:function(){},initialize:function(){},toJSON:function(e){return Ro(this.attributes)},sync:function(e,t,n){return Qs(this)(e,t,n)},get:function(e){return this.attributes[e]},keys:function(){return Object.keys(this.attributes)},values:function(){return Object.values(this.attributes)},pairs:function(){return this.entries()},entries:function(){return Object.entries(this.attributes)},invert:function(){return Go(this.attributes)},pick:function(...e){return 1===e.length&&Array.isArray(e[0])&&(e=e[0]),ko(this.attributes,e)},omit:function(...e){return 1===e.length&&Array.isArray(e[0])&&(e=e[0]),Xo(this.attributes,e)},isEmpty:function(){return fs(this.attributes)},escape:function(e){return t=this.get(e),(t=Qn(t))&&qo.test(t)?t.replace(Bo,Fo):t;var t},has:function(e){return null!=this.get(e)},matches:function(e){return!!function(e){return os("function"==typeof e?e:oo(e,1))}(e)(this.attributes)},set:function(e,t,n){if(null==e)return this;let s;if("object"==typeof e?(s=e,n=t):(s={})[e]=t,n||(n={}),!this._validate(s,n))return!1;const i=n.unset,r=n.silent,o=[],a=this._changing;this._changing=!0,a||(this._previousAttributes=Ro(this.attributes),this.changed={});const c=this.attributes,l=this.changed,d=this._previousAttributes;for(const e in s)t=s[e],Jo(c[e],t)||o.push(e),Jo(d[e],t)?delete l[e]:l[e]=t,i?delete c[e]:c[e]=t;if(this.idAttribute in s&&(this.id=this.get(this.idAttribute)),!r){o.length&&(this._pending=n);for(let e=0;et.length?n:t}),"")},ta.prefixMentions=function(e){let t=e.get("message");return(e.get("references")||[]).sort(((e,t)=>t.begin-e.begin)).forEach((e=>{t=`${t.slice(0,e.begin)}@${t.slice(e.begin)}`})),t},ta.isValidJID=function(e){return"string"==typeof e&&2===Oo(e.split("@")).length&&!e.startsWith("@")&&!e.endsWith("@")},ta.isValidMUCJID=function(e){return!e.startsWith("@")&&!e.endsWith("@")},ta.isSameBareJID=function(e,t){return"string"==typeof e&&"string"==typeof t&&le.getBareJidFromJid(e).toLowerCase()===le.getBareJidFromJid(t).toLowerCase()},ta.isSameDomain=function(e,t){return"string"==typeof e&&"string"==typeof t&&le.getDomainFromJid(e).toLowerCase()===le.getDomainFromJid(t).toLowerCase()},ta.isNewMessage=function(e){return e instanceof Element?!(Mo()(`result[xmlns="${le.NS.MAM}"]`,e).length&&Mo()(`delay[xmlns="${le.NS.DELAY}"]`,e).length):(e instanceof Zo&&(e=e.attributes),!(e.is_delayed&&e.is_archived))},ta.shouldCreateMessage=function(e){return e.retracted||!ea(e)},ta.shouldCreateGroupchatMessage=function(e){return e.nick&&(ta.shouldCreateMessage(e)||e.is_tombstone)},ta.isChatRoom=function(e){return e&&"chatroom"===e.get("type")},ta.isErrorObject=function(e){return e instanceof Error},ta.isErrorStanza=function(e){return!!T(e)&&"error"===e.getAttribute("type")},ta.isForbiddenError=function(e){return!!T(e)&&Mo()(`error[type="auth"] forbidden[xmlns="${le.NS.STANZAS}"]`,e).length>0},ta.isServiceUnavailableError=function(e){return!!T(e)&&Mo()(`error[type="cancel"] service-unavailable[xmlns="${le.NS.STANZAS}"]`,e).length>0},ta.merge=function e(t,n){for(const s in n)pe(t[s])?e(t[s],n[s]):t[s]=n[s]},ta.getOuterWidth=function(e,t=!1){let n=e.offsetWidth;if(!t)return n;const s=window.getComputedStyle(e);return n+=parseInt(s.marginLeft?s.marginLeft:0,10)+parseInt(s.marginRight?s.marginRight:0,10),n},ta.stringToElement=function(e){var t=document.createElement("div");return t.innerHTML=e,t.firstElementChild},ta.matchesSelector=function(e,t){const n=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return!!n&&n.call(e,t)},ta.queryChildren=function(e,t){return Array.from(e.childNodes).filter((e=>ta.matchesSelector(e,t)))},ta.contains=function(e,t){const n=(e,n)=>e.get(n).toLowerCase().includes(t.toLowerCase());return function(t){if("object"==typeof e)return Object.keys(e).reduce(((e,s)=>e||n(t,s)),!1);if("string"==typeof e)return n(t,e);throw new TypeError("contains: wrong attribute type. Must be string or array.")}},ta.isOfType=function(e,t){return t.get("type")==e},ta.isInstance=function(e,t){return t instanceof e},ta.getAttribute=function(e,t){return t.get(e)},ta.contains.not=function(e,t){return function(n){return!ta.contains(e,t)(n)}},ta.rootContains=function(e,t){return e!==document||e.contains?e.contains?e.contains(t):window.HTMLElement.prototype.contains.call(e,t):document.head.contains(t)||document.body.contains(t)},ta.createFragmentFromText=function(e){var t,n=document.createDocumentFragment(),s=document.createElement("body");for(s.innerHTML=e;t=s.firstChild;)n.appendChild(t);return n},ta.isPersistableModel=function(e){return e.collection&&e.collection.browserStorage},ta.getResolveablePromise=ji,ta.getOpenPromise=ji,ta.interpolate=function(e,t){return e.replace(/{{{([^{}]*)}}}/g,((e,n)=>{var s=t[n];return"string"==typeof s||"number"==typeof s?s:e}))},ta.onMultipleEvents=function(e=[],t){let n=[];function s(s){n.push(s),e.length===n.length&&(t(n),n=[])}e.forEach((e=>e.object.on(e.event,s)))},ta.safeSave=ia,ta.siblingIndex=function(e){for(var t=0;e=e.previousElementSibling;t++);return t},ta.getCurrentWord=function(e,t,n){t||(t=e.selectionEnd||void 0);let[s]=e.value.slice(0,t).split(/\s/).slice(-1);return n&&([s]=s.split(n).slice(-1)),s},ta.isMentionBoundary=e=>"@"!==e&&RegExp("(\\p{Z}|\\p{P})","u").test(e),ta.replaceCurrentWord=function(e,t){const n=e.selectionEnd||void 0,s=$o(e.value.slice(0,n).split(/\s/)),i=e.value,r=ta.isMentionBoundary(s[0])?s[0]:"";e.value=i.slice(0,n-s.length)+r+`${t} `+i.slice(n);const o=n-s.length+t.length+1;e.selectionEnd=r?o+1:o},ta.triggerEvent=function(e,t,n="Event",s=!0,i=!0){const r=document.createEvent(n);r.initEvent(t,s,i),e.dispatchEvent(r)},ta.getSelectValues=function(e){const t=[],n=e&&e.options;for(var s=0,i=n.length;se.setSelectionRange(t,t)),1),this.scrollTop=999999},ta.getUniqueId=function(e){const t="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}));return"string"==typeof e||"number"==typeof e?t+":"+e:t},ta.httpToGeoUri=function(e,t){return e.replace(t.api.settings.get("geouri_regex"),"geo:$1,$2")},ta.waitUntil=function(e,t=300,n=3){try{const t=e();if(t)return Promise.resolve(t)}catch(e){return Promise.reject(e)}const s=ji(),i=new Error,r=setInterval((function(){try{const t=e();t&&(ra(o,r),s.resolve(t))}catch(e){ra(o,r),s.reject(e)}}),n),o=setTimeout((function(){ra(o,r);const e=`Wait until promise timed out: \n\n${i.stack}`;console.trace(),M.error(e),s.reject(new Error(e))}),t);return s};const aa=document.createElement("div");function ca(e){return e&&"string"==typeof e&&(aa.innerHTML=No().sanitize(e),e=aa.textContent,aa.textContent=""),e}const la=Object.assign({isEmptyMessage:ea},ta);let da,ua={},ha={};const ma={allow_non_roster_messaging:!1,allow_url_history_change:!0,assets_path:"/dist",authentication:"login",auto_login:!1,auto_reconnect:!0,blacklisted_plugins:[],clear_cache_on_logout:!1,connection_options:{},credentials_url:null,discover_connection_methods:!0,geouri_regex:/https\:\/\/www.openstreetmap.org\/.*#map=[0-9]+\/([\-0-9.]+)\/([\-0-9.]+)\S*/g,geouri_replacement:"https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2",i18n:void 0,idle_presence_timeout:300,jid:void 0,keepalive:!0,loglevel:"info",locales:["af","ar","bg","ca","cs","da","de","el","eo","es","eu","en","fa","fi","fr","gl","he","hi","hu","id","it","ja","lt","nb","nl","mr","oc","pl","pt","pt_BR","ro","ru","sv","th","tr","uk","vi","zh_CN","zh_TW"],nickname:void 0,password:void 0,persistent_store:"IndexedDB",rid:void 0,root:window.document,sid:void 0,singleton:!1,strict_plugin_dependencies:!1,view_mode:"overlayed",websocket_url:void 0,whitelisted_plugins:[]};function fa(){var e;if(!va.bare_jid){const e="No JID to fetch user settings for";throw M.error(e),Error(e)}if(null===(e=da)||void 0===e||!e.fetched){const e=`converse.user-settings.${va.bare_jid}`;da=new Zo({id:e}),_o(da,e),da.fetched=da.fetch({promise:!0})}return da.fetched}async function ga(){return await fa(),da}async function pa(e,t){return await fa(),da.save(e,t)}const va={log:M,CONNECTION_STATUS:me,templates:{},promises:{initialized:ji()},STATUS_WEIGHTS:{offline:6,unavailable:5,xa:4,away:3,dnd:2,chat:1,online:1},ANONYMOUS:"anonymous",CLOSED:"closed",EXTERNAL:"external",LOGIN:"login",LOGOUT:"logout",OPENED:"opened",PREBIND:"prebind",STANZA_TIMEOUT:1e4,SUCCESS:"success",FAILURE:"failure",DEFAULT_IMAGE_TYPE:"image/svg+xml",DEFAULT_IMAGE:"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+CiA8cmVjdCB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgZmlsbD0iIzU1NSIvPgogPGNpcmNsZSBjeD0iNjQiIGN5PSI0MSIgcj0iMjQiIGZpbGw9IiNmZmYiLz4KIDxwYXRoIGQ9Im0yOC41IDExMiB2LTEyIGMwLTEyIDEwLTI0IDI0LTI0IGgyMyBjMTQgMCAyNCAxMiAyNCAyNCB2MTIiIGZpbGw9IiNmZmYiLz4KPC9zdmc+Cg==",TIMEOUTS:{PAUSED:1e4,INACTIVE:9e4},INACTIVE:"inactive",ACTIVE:"active",COMPOSING:"composing",PAUSED:"paused",GONE:"gone",PRIVATE_CHAT_TYPE:"chatbox",CHATROOMS_TYPE:"chatroom",HEADLINES_TYPE:"headline",CONTROLBOX_TYPE:"controlbox",default_connection_options:{explicitResourceBinding:!0},router:new oi,TimeoutError:ui,isTestEnv:()=>"montague.lit/http-bind"===ua.bosh_service_url,getDefaultStore:vo,createStore:yo,__:(...e)=>o.__(...e),___:e=>e};var ba=n(8734),ya=n.n(ba),_a=n(7484),wa=n.n(_a);const Sa=function(e,t,n){t=Xn(t,e);var s=null==(e=Ko(e,t))?e:e[Zn($o(t))];return null==s?void 0:ze(s,e,n)},xa=Je(Sa);function Ea(e,t,n,s,...i){return"function"==typeof n&&(void 0===this.__super__&&(this.__super__=s),this.__super__[e]=n.bind(this)),t.apply(this,i)}class Aa{constructor(e,t){this.name=t,this.plugged=e,void 0===this.plugged.__super__?this.plugged.__super__={}:"string"==typeof this.plugged.__super__&&(this.plugged.__super__={__string__:this.plugged.__super__}),this.plugged.__super__[t]=this.plugged,this.plugins={},this.initialized_plugins=[]}_overrideAttribute(e,t){const n=t.overrides[e];if("function"==typeof n){const t={};t[this.name]=this.plugged;const s=this.plugged[e];this.plugged[e]=function(...i){return Ea.apply(this,[e,n,s,t,...i])}}else this.plugged[e]=n}_extendObject(e,t){e.prototype.__super__||(e.prototype.__super__={},e.prototype.__super__[this.name]=this.plugged);for(const[n,s]of Object.entries(t))if("events"===n)e.prototype[n]=Object.assign(s,e.prototype[n]);else if("function"==typeof s){const t={};t[this.name]=this.plugged;const i=e.prototype[n];e.prototype[n]=function(...e){return Ea.apply(this,[n,s,i,t,...e])}}else e.prototype[n]=s}loadPluginDependencies(e){var t;null===(t=e.dependencies)||void 0===t||t.forEach((t=>{const n=this.plugins[t];if(n){var s;if(null!==(s=n.dependencies)&&void 0!==s&&s.includes(e.__name__))throw'Found a circular dependency between the plugins "'+e.__name__+'" and "'+t+'"';this.initializePlugin(n)}else this.throwUndefinedDependencyError('Could not find dependency "'+t+'" for the plugin "'+e.__name__+"\". If it's needed, make sure it's loaded by require.js")}))}throwUndefinedDependencyError(e){if(this.plugged.strict_plugin_dependencies)throw e;console.warn?console.warn(e):console.log(e)}applyOverrides(e){Object.keys(e.overrides||{}).forEach((t=>{const n=e.overrides[t];"object"==typeof n?void 0===this.plugged[t]?this.throwUndefinedDependencyError(`Plugin "${e.__name__}" tried to override "${t}" but it's not found.`):this._extendObject(this.plugged[t],n):this._overrideAttribute(t,e)}))}initializePlugin(e){var t;Object.keys(this.allowed_plugins).includes(e.__name__)&&(this.initialized_plugins.includes(e.__name__)||("boolean"==typeof e.enabled&&e.enabled||null!==(t=e.enabled)&&void 0!==t&&t.call(e,this.plugged)||null==e.enabled)&&(Object.assign(e,this.properties),e.dependencies&&this.loadPluginDependencies(e),this.applyOverrides(e),"function"==typeof e.initialize&&e.initialize.bind(e)(this),this.initialized_plugins.push(e.__name__)))}registerPlugin(e,t){if(e in this.plugins)throw new Error("Error: Plugin name "+e+" is already taken");t.__name__=e,this.plugins[e]=t}initializePlugins(e={},t=[],n=[]){if(Object.keys(this.plugins).length){this.properties=e,this.allowed_plugins={};for(const[e,s]of Object.entries(this.plugins))t.length&&!t.includes(e)||n.includes(e)||(this.allowed_plugins[e]=s);Object.values(this.allowed_plugins).forEach((e=>this.initializePlugin(e)))}}}const Ca=function(e,t,n){return void 0===n&&(n="pluginSocket"),void 0===t&&(t="plugged"),e[n]=new Aa(e,t),e},Ta={extend:e=>function(e){la.merge(ma,e);const t=Object.keys(ko(e,Object.keys(ma))),n=ko(ua,t),s=Ct(ko(e,t),n);la.merge(ha,s),la.merge(va,s)}(e),update(e){return M.warn("The api.settings.update method has been deprecated and will be removed. Please use api.settings.extend instead."),this.extend(e)},get:e=>function(e){if(Object.keys(ma).includes(e))return ha[e]}(e),set(e,t){!function(e,t){const n={};pe(e)?(Ct(va,ko(e,Object.keys(ma))),Ct(ha,ko(e,Object.keys(ma)))):"string"==typeof e&&(n[e]=t,Ct(va,ko(n,Object.keys(ma))),Ct(ha,ko(n,Object.keys(ma))))}(e,t)}},ka=function(e,t,n,s){for(var i=-1,r=null==e?0:e.length;++i-1},La=function(e,t,n){for(var s=-1,i=null==e?0:e.length;++s=200&&(r=Gt,o=!1,t=new Ht(t));e:for(;++it||r&&o&&c&&!a&&!l||s&&o&&c||!n&&c||!i)return 1;if(!s&&!r&&!l&&e=a?c:c*("desc"==n[s]?-1:1)}return e.index-t.index}(e,t,n)}))},Za=Je((function(e,t){if(null==e)return[];var n=t.length;return n>1&&Ze(e,t[0],t[1])?t=[]:n>2&&Ze(t[0],t[1],t[2])&&(t=[t[0]]),Xa(e,Ao(t,1),[])})),ec=Array.prototype.slice,tc=function(e,t){t||(t={}),this.preinitialize.apply(this,arguments),t.model&&(this.model=t.model),void 0!==t.comparator&&(this.comparator=t.comparator),this._reset(),this.initialize.apply(this,arguments),e&&this.reset(e,Ct({silent:!0},t))};tc.extend=Ws;const nc={add:!0,remove:!0,merge:!0},sc={add:!0,remove:!1},ic=function(e,t,n){n=Math.min(Math.max(n,0),e.length);const s=Array(e.length-n),i=t.length;let r;for(r=0;rthis.length&&(s=this.length),s<0&&(s+=this.length+1);const i=[],r=[],o=[],a=[],c={},l=t.add,d=t.merge,u=t.remove;let h=!1;const m=this.comparator&&null==s&&!1!==t.sort,f=ao(this.comparator)?this.comparator:null;let g,p;for(p=0;pe!==i[t])),this.models.length=0,ic(this.models,i,0),this.length=this.models.length):r.length&&(m&&(h=!0),ic(this.models,r,null==s?this.length:s),this.length=this.models.length),h&&this.sort({silent:!0}),!t.silent){for(p=0;pe)){await Promise.all(this.models.filter(t).map((t=>new Promise((n=>{t.destroy(Object.assign(e,{success:n,error:(e,t)=>{console.error(t),n()}}))}))))),await this.browserStorage.clear(),this.reset()},reset:function(e,t){t=t?Ro(t):{};for(let e=0;et.matches(e),t)},every:function(e){return function(e,t,n){var s=ot(e)?Pa:Fa;return n&&Ze(e,t,n)&&(t=void 0),s(e,os(t))}(this.models.map((e=>e.attributes)),e)},difference:function(e){return za(this.models,e)},max:function(){return Math.max.apply(Math,this.models)},min:function(){return Math.min.apply(Math,this.models)},drop:function(e=1){return this.models.slice(e)},some:function(e){return hs(this.models.map((e=>e.attributes)),e)},sortBy:function(e){return Za(this.models,ve(e)?e:t=>ao(e)?t.get(e):t.matches(e))},isEmpty:function(){return fs(this.models)},keyBy:function(e){return Ja(this.models,e)},each:function(e,t){return this.forEach(e,t)},forEach:function(e,t){return this.models.forEach(e,t)},includes:function(e){return this.models.includes(e)},size:function(){return this.models.length},countBy:function(e){return $a(this.models,ve(e)?e:t=>ao(e)?t.get(e):t.matches(e))},groupBy:function(e){return Ga(this.models,ve(e)?e:t=>ao(e)?t.get(e):t.matches(e))},indexOf:function(e){return Va(this.models,e)},findLastIndex:function(e,t){return function(e,t,n){var s=null==e?0:e.length;if(!s)return-1;var i=s-1;return void 0!==n&&(i=Es(n),i=n<0?Ba(s+i,0):qa(i,s-1)),Ia(e,os(t),i,!0)}(this.models,ve(e)?e:t=>ao(e)?t.get(e):t.matches(e),t)},lastIndexOf:function(e){return function(e,t,n){var s=null==e?0:e.length;if(!s)return-1;var i=s;return void 0!==n&&(i=(i=Es(n))<0?Ka(s+i,0):Ya(i,s-1)),t==t?function(e,t,n){for(var s=n+1;s--;)if(e[s]===t)return s;return s}(e,t,i):Ia(e,Ma,i,!0)}(this.models,e)},findIndex:function(e){return function(e,t,n){var s=null==e?0:e.length;if(!s)return-1;var i=null==n?0:Es(n);return i<0&&(i=Ua(s+i,0)),Ia(e,os(t),i)}(this.models,ve(e)?e:t=>ao(e)?t.get(e):t.matches(e))},last:function(){const e=null==this.models?0:this.models.length;return e?this.models[e-1]:void 0},head:function(){return this.models[0]},first:function(){return this.head()},map:function(e,t){return this.models.map(ve(e)?e:t=>ao(e)?t.get(e):t.matches(e),t)},reduce:function(e,t){return this.models.reduce(e,t||this.models[0])},reduceRight:function(e,t){return this.models.reduceRight(e,t||this.models[0])},toArray:function(){return Array.from(this.models)},get:function(e){if(null!=e)return this._byId[e]||this._byId[this.modelId(this._isModel(e)?e.attributes:e)]||e.cid&&this._byId[e.cid]},has:function(e){return null!=this.get(e)},at:function(e){return e<0&&(e+=this.length),this.models[e]},where:function(e,t){return this[t?"find":"filter"](e)},findWhere:function(e){return this.where(e,!0)},find:function(e,t){const n=ve(e)?e:t=>t.matches(e);return this.models.find(n,t)},sort:function(e){let t=this.comparator;if(!t)throw new Error("Cannot sort a set without a comparator");e||(e={});const n=t.length;return ve(t)&&(t=t.bind(this)),1===n||ao(t)?this.models=this.sortBy(t):this.models.sort(t),e.silent||this.trigger("sort",this,e),this},pluck:function(e){return this.map(e+"")},fetch:function(e){const t=(e=Ct({parse:!0},e)).success,n=this,s=e.promise&&Vs();return e.success=function(i){const r=e.reset?"reset":"set";n[r](i,e),t&&t.call(e.context,n,i,e),s&&s.resolve(),n.trigger("sync",n,i,e)},Ks(this,e),s||this.sync("read",this,e)},create:function(e,t){const n=(t=t?Ro(t):{}).wait,s=t.promise,i=s&&Vs();if(!(e=this._prepareModel(e,t)))return!1;n||this.add(e,t);const r=this,o=t.success,a=t.error;return t.success=function(e,t,a){n&&r.add(e,a),o&&o.call(a.context,e,t,a),s&&i.resolve(e)},t.error=function(e,t,n){a&&a.call(n.context,e,t,n),s&&i.reject(t)},e.save(null,Object.assign(t,{promise:!1})),s?i:e},parse:function(e,t){return e},clone:function(){return new this.constructor(this.models,{model:this.model,comparator:this.comparator})},modelId:function(e){var t;return e[(null===(t=this.model.prototype)||void 0===t?void 0:t.idAttribute)||"id"]},values:function(){return new oc(this,ac)},keys:function(){return new oc(this,cc)},entries:function(){return new oc(this,lc)},_reset:function(){this.length=0,this.models=[],this._byId={}},_prepareModel:function(e,t){if(this._isModel(e))return e.collection||(e.collection=this),e;(t=t?Ro(t):{}).collection=this;const n=new this.model(e,t);return n.validationError?(this.trigger("invalid",this,n.validationError,t),!1):n},_removeModels:function(e,t){const n=[];for(let s=0;s=t||n<0||u&&e-l>=r}function p(){var e=ki();if(g(e))return v(e);a=setTimeout(p,function(e){var n=t-(e-c);return u?uc(n,r-(e-l)):n}(e))}function v(e){return a=void 0,h&&s?m(e):(s=i=void 0,o)}function b(){var e=ki(),n=g(e);if(s=arguments,i=this,c=e,n){if(void 0===a)return f(c);if(u)return clearTimeout(a),a=setTimeout(p,t),m(c)}return void 0===a&&(a=setTimeout(p,t)),o}return t=Ss(t)||0,pe(n)&&(d=!!n.leading,r=(u="maxWait"in n)?dc(Ss(n.maxWait)||0,t):r,h="trailing"in n?!!n.trailing:h),b.cancel=function(){void 0!==a&&clearTimeout(a),l=0,s=c=i=a=void 0},b.flush=function(){return void 0===a?o:v(ki())},b};class mc extends le.Connection{constructor(e,t){super(e,t),this.debouncedReconnect=hc(this.reconnect,2e3)}static generateResource(){return`/converse.js-${Math.floor(139749528*Math.random()).toString()}`}async bind(){await Cl.trigger("beforeResourceBinding",{synchronous:!0}),super.bind()}async onDomainDiscovered(e){const t=await e.text(),n=(new window.DOMParser).parseFromString(t,"text/xml").firstElementChild;if("XRD"!=n.nodeName||"http://docs.oasis-open.org/ns/xri/xrd-1.0"!=n.namespaceURI)return M.warn("Could not discover XEP-0156 connection methods");const s=Mo()('Link[rel="urn:xmpp:alt-connections:xbosh"]',n),i=Mo()('Link[rel="urn:xmpp:alt-connections:websocket"]',n),r=s.map((e=>e.getAttribute("href"))),o=i.map((e=>e.getAttribute("href")));0===r.length&&0===o.length?M.warn("Neither BOSH nor WebSocket connection methods have been specified with XEP-0156."):(Cl.settings.set("websocket_url",o.pop()),Cl.settings.set("bosh_service_url",r.pop()),this.service=Cl.settings.get("websocket_url")||Cl.settings.get("bosh_service_url"),this.setProtocol())}async discoverConnectionMethods(e){const t={mode:"cors",headers:{Accept:"application/xrd+xml, text/xml"}},n=`https://${e}/.well-known/host-meta`;let s;try{s=await fetch(n,t)}catch(e){return M.error(`Failed to discover alternative connection methods at ${n}`),void M.error(e)}s.status>=200&&s.status<400?await this.onDomainDiscovered(s):M.warn("Could not discover XEP-0156 connection methods")}async connect(e,t,n){if(Cl.settings.get("discover_connection_methods")){const t=le.getDomainFromJid(e);await this.discoverConnectionMethods(t)}super.connect(e,t,n||this.onConnectStatusChanged,59)}async reconnect(){const{__:e}=va;return M.debug("RECONNECTING: the connection has dropped, attempting to reconnect."),this.setConnectionStatus(le.Status.RECONNECTING,e("The connection has dropped, attempting to reconnect.")),Cl.trigger("will-reconnect"),this.reconnecting=!0,await Tl(),Cl.user.login()}async onConnected(e){delete this.reconnecting,this.flush(),await va.setUserJID(this.jid),await Cl.trigger("afterResourceBinding",e,{synchronous:!0}),e?Cl.trigger("reconnected"):Cl.trigger("connected")}setDisconnectionCause(e,t,n){void 0===e?(delete this.disconnection_cause,delete this.disconnection_reason):(void 0===this.disconnection_cause||n)&&(this.disconnection_cause=e,this.disconnection_reason=t)}setConnectionStatus(e,t){this.status=e,va.connfeedback.set({connection_status:e,message:t})}async finishDisconnection(){M.debug("DISCONNECTED"),delete this.reconnecting,this.reset(),Tl(),await kl(),delete va.connection,Cl.trigger("disconnected")}onDisconnected(){if(!Cl.settings.get("auto_reconnect"))return this.finishDisconnection();{const e=this.disconnection_reason;if(this.disconnection_cause===le.Status.AUTHFAIL)return Cl.settings.get("credentials_url")||Cl.settings.get("authentication")===va.ANONYMOUS?Cl.connection.reconnect():this.finishDisconnection();if(this.disconnection_cause===va.LOGOUT||e===le.ErrorCondition.NO_AUTH_MECH||"host-unknown"===e||"remote-connection-failed"===e)return this.finishDisconnection();Cl.connection.reconnect()}}onConnectStatusChanged(e,t){const{__:n}=va;var s;if(M.debug(`Status changed to: ${va.CONNECTION_STATUS[e]}`),e===le.Status.ATTACHFAIL)this.setConnectionStatus(e),null===(s=this.worker_attach_promise)||void 0===s||s.resolve(!1);else if(e===le.Status.CONNECTED||e===le.Status.ATTACHED){var i,r;if(null!==(i=this.worker_attach_promise)&&void 0!==i&&i.isResolved&&this.status===le.Status.ATTACHED)return;this.setConnectionStatus(e),null===(r=this.worker_attach_promise)||void 0===r||r.resolve(!0),va.send_initial_presence=!0,this.setDisconnectionCause(),this.reconnecting?(M.debug(e===le.Status.CONNECTED?"Reconnected":"Reattached"),this.onConnected(!0)):(M.debug(e===le.Status.CONNECTED?"Connected":"Attached"),this.restored&&(va.send_initial_presence=!1),this.onConnected())}else if(e===le.Status.DISCONNECTED)this.setDisconnectionCause(e,t),this.onDisconnected();else if(e===le.Status.BINDREQUIRED)this.bind();else if(e===le.Status.ERROR)this.setConnectionStatus(e,n("An error occurred while connecting to the chat server."));else if(e===le.Status.CONNECTING)this.setConnectionStatus(e);else if(e===le.Status.AUTHENTICATING)this.setConnectionStatus(e);else if(e===le.Status.AUTHFAIL)t||(t=n("Your XMPP address and/or password is incorrect. Please try again.")),this.setConnectionStatus(e,t),this.setDisconnectionCause(e,t,!0),this.onDisconnected();else if(e===le.Status.CONNFAIL){var o;let s=t;"host-unknown"===t||"remote-connection-failed"==t?s=n("Sorry, we could not connect to the XMPP host with domain: %1$s",`"${le.getDomainFromJid(this.jid)}"`):void 0!==t&&t===(null==le||null===(o=le.ErrorCondition)||void 0===o?void 0:o.NO_AUTH_MECH)&&(s=n("The XMPP server did not offer a supported authentication mechanism")),this.setConnectionStatus(e,s),this.setDisconnectionCause(e,t)}else e===le.Status.DISCONNECTING&&this.setDisconnectionCause(e,t)}isType(e){return"websocket"===e.toLowerCase()?this._proto instanceof le.Websocket:"bosh"===e.toLowerCase()?le.Bosh&&this._proto instanceof le.Bosh:void 0}hasResumed(){var e;return null!==(e=Cl.settings.get("connection_options"))&&void 0!==e&&e.worker||this.isType("bosh")?va.connfeedback.get("connection_status")===le.Status.ATTACHED:!this.do_bind}restoreWorkerSession(){return this.attach(this.onConnectStatusChanged),this.worker_attach_promise=ji(),this.worker_attach_promise}}class fc extends mc{constructor(e,t){super(e,t),this.sent_stanzas=[],this.IQ_stanzas=[],this.IQ_ids=[],this.features=le.xmlHtmlNode('').firstChild,this._proto._processRequest=()=>{},this._proto._disconnect=()=>this._onDisconnectTimeout(),this._proto._onDisconnectTimeout=()=>{},this._proto._connect=()=>{this.connected=!0,this.mock=!0,this.jid="romeo@montague.lit/orchard",this._changeConnectStatus(le.Status.BINDREQUIRED)}}_processRequest(){}sendIQ(e,t,n){T(e)||(e=e.nodeTree),this.IQ_stanzas.push(e);const s=super.sendIQ(e,t,n);return this.IQ_ids.push(s),s}send(e){return T(e)?this.sent_stanzas.push(e):this.sent_stanzas.push(e.nodeTree),super.send(e)}async bind(){await Cl.trigger("beforeResourceBinding",{synchronous:!0}),this.authenticated=!0,va.no_connection_on_bind||this._changeConnectStatus(le.Status.CONNECTED)}}const gc=window.ShadowRoot&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,pc=Symbol();class vc{constructor(e,t){if(t!==pc)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e}get styleSheet(){return gc&&void 0===this.t&&(this.t=new CSSStyleSheet,this.t.replaceSync(this.cssText)),this.t}toString(){return this.cssText}}const bc=new Map,yc=e=>{let t=bc.get(e);return void 0===t&&bc.set(e,t=new vc(e,pc)),t},_c=gc?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const n of e.cssRules)t+=n.cssText;return(e=>yc("string"==typeof e?e:e+""))(t)})(e):e;var wc,Sc,xc,Ec;const Ac={toAttribute(e,t){switch(t){case Boolean:e=e?"":null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let n=e;switch(t){case Boolean:n=null!==e;break;case Number:n=null===e?null:Number(e);break;case Object:case Array:try{n=JSON.parse(e)}catch(e){n=null}}return n}},Cc=(e,t)=>t!==e&&(t==t||e==e),Tc={attribute:!0,type:String,converter:Ac,reflect:!1,hasChanged:Cc};class kc extends HTMLElement{constructor(){super(),this.Πi=new Map,this.Πo=void 0,this.Πl=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this.Πh=null,this.u()}static addInitializer(e){var t;null!==(t=this.v)&&void 0!==t||(this.v=[]),this.v.push(e)}static get observedAttributes(){this.finalize();const e=[];return this.elementProperties.forEach(((t,n)=>{const s=this.Πp(n,t);void 0!==s&&(this.Πm.set(s,n),e.push(s))})),e}static createProperty(e,t=Tc){if(t.state&&(t.attribute=!1),this.finalize(),this.elementProperties.set(e,t),!t.noAccessor&&!this.prototype.hasOwnProperty(e)){const n="symbol"==typeof e?Symbol():"__"+e,s=this.getPropertyDescriptor(e,n,t);void 0!==s&&Object.defineProperty(this.prototype,e,s)}}static getPropertyDescriptor(e,t,n){return{get(){return this[t]},set(s){const i=this[e];this[t]=s,this.requestUpdate(e,i,n)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)||Tc}static finalize(){if(this.hasOwnProperty("finalized"))return!1;this.finalized=!0;const e=Object.getPrototypeOf(this);if(e.finalize(),this.elementProperties=new Map(e.elementProperties),this.Πm=new Map,this.hasOwnProperty("properties")){const e=this.properties,t=[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)];for(const n of t)this.createProperty(n,e[n])}return this.elementStyles=this.finalizeStyles(this.styles),!0}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const n=new Set(e.flat(1/0).reverse());for(const e of n)t.unshift(_c(e))}else void 0!==e&&t.push(_c(e));return t}static Πp(e,t){const n=t.attribute;return!1===n?void 0:"string"==typeof n?n:"string"==typeof e?e.toLowerCase():void 0}u(){var e;this.Πg=new Promise((e=>this.enableUpdating=e)),this.L=new Map,this.Π_(),this.requestUpdate(),null===(e=this.constructor.v)||void 0===e||e.forEach((e=>e(this)))}addController(e){var t,n;(null!==(t=this.ΠU)&&void 0!==t?t:this.ΠU=[]).push(e),void 0!==this.renderRoot&&this.isConnected&&(null===(n=e.hostConnected)||void 0===n||n.call(e))}removeController(e){var t;null===(t=this.ΠU)||void 0===t||t.splice(this.ΠU.indexOf(e)>>>0,1)}Π_(){this.constructor.elementProperties.forEach(((e,t)=>{this.hasOwnProperty(t)&&(this.Πi.set(t,this[t]),delete this[t])}))}createRenderRoot(){var e;const t=null!==(e=this.shadowRoot)&&void 0!==e?e:this.attachShadow(this.constructor.shadowRootOptions);return((e,t)=>{gc?e.adoptedStyleSheets=t.map((e=>e instanceof CSSStyleSheet?e:e.styleSheet)):t.forEach((t=>{const n=document.createElement("style");n.textContent=t.cssText,e.appendChild(n)}))})(t,this.constructor.elementStyles),t}connectedCallback(){var e;void 0===this.renderRoot&&(this.renderRoot=this.createRenderRoot()),this.enableUpdating(!0),null===(e=this.ΠU)||void 0===e||e.forEach((e=>{var t;return null===(t=e.hostConnected)||void 0===t?void 0:t.call(e)})),this.Πl&&(this.Πl(),this.Πo=this.Πl=void 0)}enableUpdating(e){}disconnectedCallback(){var e;null===(e=this.ΠU)||void 0===e||e.forEach((e=>{var t;return null===(t=e.hostDisconnected)||void 0===t?void 0:t.call(e)})),this.Πo=new Promise((e=>this.Πl=e))}attributeChangedCallback(e,t,n){this.K(e,n)}Πj(e,t,n=Tc){var s,i;const r=this.constructor.Πp(e,n);if(void 0!==r&&!0===n.reflect){const o=(null!==(i=null===(s=n.converter)||void 0===s?void 0:s.toAttribute)&&void 0!==i?i:Ac.toAttribute)(t,n.type);this.Πh=e,null==o?this.removeAttribute(r):this.setAttribute(r,o),this.Πh=null}}K(e,t){var n,s,i;const r=this.constructor,o=r.Πm.get(e);if(void 0!==o&&this.Πh!==o){const e=r.getPropertyOptions(o),a=e.converter,c=null!==(i=null!==(s=null===(n=a)||void 0===n?void 0:n.fromAttribute)&&void 0!==s?s:"function"==typeof a?a:null)&&void 0!==i?i:Ac.fromAttribute;this.Πh=o,this[o]=c(t,e.type),this.Πh=null}}requestUpdate(e,t,n){let s=!0;void 0!==e&&(((n=n||this.constructor.getPropertyOptions(e)).hasChanged||Cc)(this[e],t)?(this.L.has(e)||this.L.set(e,t),!0===n.reflect&&this.Πh!==e&&(void 0===this.Πk&&(this.Πk=new Map),this.Πk.set(e,n))):s=!1),!this.isUpdatePending&&s&&(this.Πg=this.Πq())}async Πq(){this.isUpdatePending=!0;try{for(await this.Πg;this.Πo;)await this.Πo}catch(e){Promise.reject(e)}const e=this.performUpdate();return null!=e&&await e,!this.isUpdatePending}performUpdate(){var e;if(!this.isUpdatePending)return;this.hasUpdated,this.Πi&&(this.Πi.forEach(((e,t)=>this[t]=e)),this.Πi=void 0);let t=!1;const n=this.L;try{t=this.shouldUpdate(n),t?(this.willUpdate(n),null===(e=this.ΠU)||void 0===e||e.forEach((e=>{var t;return null===(t=e.hostUpdate)||void 0===t?void 0:t.call(e)})),this.update(n)):this.Π$()}catch(e){throw t=!1,this.Π$(),e}t&&this.E(n)}willUpdate(e){}E(e){var t;null===(t=this.ΠU)||void 0===t||t.forEach((e=>{var t;return null===(t=e.hostUpdated)||void 0===t?void 0:t.call(e)})),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}Π$(){this.L=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this.Πg}shouldUpdate(e){return!0}update(e){void 0!==this.Πk&&(this.Πk.forEach(((e,t)=>this.Πj(t,this[t],e))),this.Πk=void 0),this.Π$()}updated(e){}firstUpdated(e){}}var jc,Nc,Oc,$c;kc.finalized=!0,kc.elementProperties=new Map,kc.elementStyles=[],kc.shadowRootOptions={mode:"open"},null===(Sc=(wc=globalThis).reactiveElementPlatformSupport)||void 0===Sc||Sc.call(wc,{ReactiveElement:kc}),(null!==(xc=(Ec=globalThis).reactiveElementVersions)&&void 0!==xc?xc:Ec.reactiveElementVersions=[]).push("1.0.0-rc.2");const Ic=globalThis.trustedTypes,Mc=Ic?Ic.createPolicy("lit-html",{createHTML:e=>e}):void 0,Rc=`lit$${(Math.random()+"").slice(9)}$`,Dc="?"+Rc,Lc=`<${Dc}>`,zc=document,Pc=(e="")=>zc.createComment(e),Fc=e=>null===e||"object"!=typeof e&&"function"!=typeof e,Uc=Array.isArray,Bc=e=>{var t;return Uc(e)||"function"==typeof(null===(t=e)||void 0===t?void 0:t[Symbol.iterator])},qc=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Hc=/-->/g,Gc=/>/g,Wc=/>|[ \n \r](?:([^\s"'>=/]+)([ \n \r]*=[ \n \r]*(?:[^ \n \r"'`<>=]|("|')|))|$)/g,Vc=/'/g,Jc=/"/g,Kc=/^(?:script|style|textarea)$/i,Yc=e=>(t,...n)=>({_$litType$:e,strings:t,values:n}),Qc=Yc(1),Xc=(Yc(2),Symbol.for("lit-noChange")),Zc=Symbol.for("lit-nothing"),el=new WeakMap,tl=(e,t,n)=>{var s,i;const r=null!==(s=null==n?void 0:n.renderBefore)&&void 0!==s?s:t;let o=r._$litPart$;if(void 0===o){const e=null!==(i=null==n?void 0:n.renderBefore)&&void 0!==i?i:null;r._$litPart$=o=new al(t.insertBefore(Pc(),e),e,void 0,n)}return o.I(e),o},nl=zc.createTreeWalker(zc,129,null,!1),sl=(e,t)=>{const n=e.length-1,s=[];let i,r=2===t?"":"",o=qc;for(let t=0;t"===c[0]?(o=null!=i?i:qc,l=-1):void 0===c[1]?l=-2:(l=o.lastIndex-c[2].length,a=c[1],o=void 0===c[3]?Wc:'"'===c[3]?Jc:Vc):o===Jc||o===Vc?o=Wc:o===Hc||o===Gc?o=qc:(o=Wc,i=void 0);const u=o===Wc&&e[t+1].startsWith("/>")?" ":"";r+=o===qc?n+Lc:l>=0?(s.push(a),n.slice(0,l)+"$lit$"+n.slice(l)+Rc+u):n+Rc+(-2===l?(s.push(void 0),t):u)}const a=r+(e[n]||"")+(2===t?"":"");return[void 0!==Mc?Mc.createHTML(a):a,s]};class il{constructor({strings:e,_$litType$:t},n){let s;this.parts=[];let i=0,r=0;const o=e.length-1,a=this.parts,[c,l]=sl(e,t);if(this.el=il.createElement(c,n),nl.currentNode=this.el.content,2===t){const e=this.el.content,t=e.firstChild;t.remove(),e.append(...t.childNodes)}for(;null!==(s=nl.nextNode())&&a.length0){s.textContent=Ic?Ic.emptyScript:"";for(let n=0;n2||""!==n[0]||""!==n[1]?(this.H=Array(n.length-1).fill(Zc),this.strings=n):this.H=Zc}get tagName(){return this.element.tagName}I(e,t=this,n,s){const i=this.strings;let r=!1;if(void 0===i)e=rl(this,e,t,0),r=!Fc(e)||e!==this.H&&e!==Xc,r&&(this.H=e);else{const s=e;let o,a;for(e=i[0],o=0;o{const n=new XMLHttpRequest;n.open("GET",va.api.settings.get("credentials_url"),!0),n.setRequestHeader("Accept","application/json, text/javascript"),n.onload=()=>{if(n.status>=200&&n.status<400){const t=JSON.parse(n.responseText);va.setUserJID(t.jid).then((()=>{e({jid:t.jid,password:t.password})}))}else t(new Error(`${n.status}: ${n.responseText}`))},n.onerror=t,n.send()}),e))}function Al(e){if([va.ANONYMOUS,va.EXTERNAL].includes(va.api.settings.get("authentication"))){if(!va.jid)throw new Error("Config Error: when using anonymous login you need to provide the server's domain via the 'jid' option. Either when calling converse.initialize, or when calling _converse.api.user.login.");va.connection.reconnecting||va.connection.reset(),va.connection.connect(va.jid.toLowerCase())}else if(va.api.settings.get("authentication")===va.LOGIN){var t;const n=e?e.password:(null===(t=va.connection)||void 0===t?void 0:t.pass)||va.api.settings.get("password");if(!n){if(va.api.settings.get("auto_login"))throw new Error("autoLogin: If you use auto_login and authentication='login' then you also need to provide a password.");return va.connection.setDisconnectionCause(le.Status.AUTHFAIL,void 0,!0),void va.api.connection.disconnect()}va.connection.reconnecting||va.connection.reset(),va.connection.connect(va.jid,n)}}wa().extend(ya()),le.addNamespace("ACTIVITY","http://jabber.org/protocol/activity"),le.addNamespace("CARBONS","urn:xmpp:carbons:2"),le.addNamespace("CHATSTATES","http://jabber.org/protocol/chatstates"),le.addNamespace("CSI","urn:xmpp:csi:0"),le.addNamespace("DELAY","urn:xmpp:delay"),le.addNamespace("EME","urn:xmpp:eme:0"),le.addNamespace("FASTEN","urn:xmpp:fasten:0"),le.addNamespace("FORWARD","urn:xmpp:forward:0"),le.addNamespace("HINTS","urn:xmpp:hints"),le.addNamespace("HTTPUPLOAD","urn:xmpp:http:upload:0"),le.addNamespace("IDLE","urn:xmpp:idle:1"),le.addNamespace("MAM","urn:xmpp:mam:2"),le.addNamespace("MARKERS","urn:xmpp:chat-markers:0"),le.addNamespace("MENTIONS","urn:xmpp:mmn:0"),le.addNamespace("MESSAGE_CORRECT","urn:xmpp:message-correct:0"),le.addNamespace("MODERATE","urn:xmpp:message-moderate:0"),le.addNamespace("NICK","http://jabber.org/protocol/nick"),le.addNamespace("OMEMO","eu.siacs.conversations.axolotl"),le.addNamespace("OUTOFBAND","jabber:x:oob"),le.addNamespace("PUBSUB","http://jabber.org/protocol/pubsub"),le.addNamespace("RAI","urn:xmpp:rai:0"),le.addNamespace("RECEIPTS","urn:xmpp:receipts"),le.addNamespace("REFERENCE","urn:xmpp:reference:0"),le.addNamespace("REGISTER","jabber:iq:register"),le.addNamespace("RETRACT","urn:xmpp:message-retract:0"),le.addNamespace("ROSTERX","http://jabber.org/protocol/rosterx"),le.addNamespace("RSM","http://jabber.org/protocol/rsm"),le.addNamespace("SID","urn:xmpp:sid:0"),le.addNamespace("SPOILER","urn:xmpp:spoiler:0"),le.addNamespace("STANZAS","urn:ietf:params:xml:ns:xmpp-stanzas"),le.addNamespace("STYLING","urn:xmpp:styling:0"),le.addNamespace("VCARD","vcard-temp"),le.addNamespace("VCARDUPDATE","vcard-temp:x:update"),le.addNamespace("XFORM","jabber:x:data"),le.addNamespace("XHTML","http://www.w3.org/1999/xhtml"),va.VERSION_NAME="v8.0.1dev",Object.assign(va,ks),Ca(va,"_converse","pluggable");const Cl=va.api={connection:{connected(){var e;return(null==va||null===(e=va.connection)||void 0===e?void 0:e.connected)&&!0},disconnect(){va.connection&&va.connection.disconnect()},async reconnect(){var e;const t=va.connfeedback.get("connection_status");if(Cl.settings.get("authentication")===va.ANONYMOUS&&(await Tl(),await kl()),t===le.Status.CONNFAIL?Cl.connection.isType("websocket")&&Cl.settings.get("bosh_service_url")?(await va.setUserJID(va.bare_jid),va.connection._proto._doDisconnect(),va.connection._proto=new le.Bosh(va.connection),va.connection.service=Cl.settings.get("bosh_service_url")):Cl.connection.isType("bosh")&&Cl.settings.get("websocket_url")&&(Cl.settings.get("authentication")===va.ANONYMOUS?await va.setUserJID(Cl.settings.get("jid")):await va.setUserJID(va.bare_jid),va.connection._proto._doDisconnect(),va.connection._proto=new le.Websocket(va.connection),va.connection.service=Cl.settings.get("websocket_url")):t===le.Status.AUTHFAIL&&Cl.settings.get("authentication")===va.ANONYMOUS&&await va.setUserJID(Cl.settings.get("jid")),null===(e=va.connection)||void 0===e||!e.reconnecting)return va.connection.reconnect();va.connection.debouncedReconnect()},isType:e=>va.connection.isType(e)},async trigger(e){if(!va._events)return;const t=Array.from(arguments),n=t.pop();if(n&&n.synchronous){const n=va._events[e]||[],s=t.splice(1);await Promise.all(n.map((e=>e.callback.apply(e.ctx,s))))}else va.trigger.apply(va,arguments);const s=va.promises[e];void 0!==s&&s.resolve()},hook(e,t,n){const s=va._events[e]||[];if(s.length){const e=s.reduce(((e,n)=>e.then((e=>n.callback(t,e)))),Promise.resolve(n));return e.catch((e=>{throw M.error(e),e})),e}return n},user:{jid:()=>va.connection.jid,async login(e,t,n=!1){var s,i;if(e=e||va.jid,(null===(s=va.connection)||void 0===s||!s.jid||e&&!la.isSameDomain(va.connection.jid,e))&&await va.initConnection(),null!==(i=Cl.settings.get("connection_options"))&&void 0!==i&&i.worker&&await va.connection.restoreWorkerSession())return;e&&(e=await va.setUserJID(e));const r=va.pluggable.plugins["converse-bosh"];if(r&&r.enabled()){if(await va.restoreBOSHSession())return;if(Cl.settings.get("authentication")===va.PREBIND&&(!n||Cl.settings.get("auto_login")))return va.startNewPreboundBOSHSession()}t=t||Cl.settings.get("password"),async function(e,t){const{api:n}=va;n.settings.get("authentication")===va.LOGIN?e?Al(e):va.api.settings.get("credentials_url")?Al(await async function(){let e,t=0;for(;!e;){try{e=await El(t)}catch(e){M.error("Could not fetch login credentials"),M.error(e)}t=2e3}return e}()):va.jid&&(va.api.settings.get("password")||va.connection.pass)?Al():!va.isTestEnv()&&"credentials"in navigator?Al(await async function(){try{const e=await navigator.credentials.get({password:!0});if(e&&"password"==e.type&&ta.isValidJID(e.id))return await va.setUserJID(e.id),{jid:e.id,password:e.password}}catch(e){M.error(e)}}()):!va.isTestEnv()&&M.warn("attemptNonPreboundSession: Couldn't find credentials to log in with"):![va.ANONYMOUS,va.EXTERNAL].includes(va.api.settings.get("authentication"))||t&&!va.api.settings.get("auto_login")||Al()}(e&&t?{jid:e,password:t}:null,n)},async logout(){await Cl.trigger("beforeLogout",{synchronous:!0});const e=ji(),t=()=>{Object.keys(va.promises).forEach(oa),delete va.jid,Cl.trigger("logout"),e.resolve()};return va.connection.setDisconnectionCause(va.LOGOUT,void 0,!0),void 0!==va.connection?(Cl.listen.once("disconnected",(()=>t())),va.connection.disconnect()):t(),e},settings:{getModel:()=>ga(),async get(e,t){const n=await ga();return void 0===n.get(e)?t:n.get(e)},set(e,t){if(pe(e))return pa(e,{promise:!0});{const n={};return n[e]=t,pa(n,{promise:!0})}},clear:()=>async function(){return await fa(),da.clear()}()}},settings:Ta,promises:{add(e,t=!0){(e=Array.isArray(e)?e:[e]).forEach((e=>{const n=ji();n.replace=t,va.promises[e]=n}))}},listen:{once:va.once.bind(va),on:va.on.bind(va),not:va.off.bind(va),stanza(e,t,n){ve(t)?(n=t,t={}):t=t||{},va.connection.addHandler(n,t.ns,e,t.type,t.id,t.from,t)}},waitUntil(e){if(ve(e))return la.waitUntil(e);{const t=va.promises[e];return void 0===t?null:t}},send(e){var t;return Cl.connection.connected()?("string"==typeof e?e=la.toStanza(e):null!==(t=e)&&void 0!==t&&t.nodeTree&&(e=e.nodeTree),"iq"===e.tagName?Cl.sendIQ(e):(va.connection.send(e),void Cl.trigger("send",e))):(M.warn("Not sending stanza because we're not connected!"),void M.warn(le.serialize(e)))},sendIQ(e,t=va.STANZA_TIMEOUT,n=!0){var s;let i;return e=(null===(s=e)||void 0===s?void 0:s.nodeTree)??e,["get","set"].includes(e.getAttribute("type"))?(t=t||va.STANZA_TIMEOUT,n?(i=new Promise(((n,s)=>va.connection.sendIQ(e,n,s,t))),i.catch((n=>{if(null===n)throw new ui(`Timeout error after ${t}ms for the following IQ stanza: ${le.serialize(e)}`)}))):i=new Promise((n=>va.connection.sendIQ(e,n,n,t)))):(va.connection.sendIQ(e),i=Promise.resolve()),Cl.trigger("send",e),i}};async function Tl(){return await va.api.trigger("beforeTearDown",{synchronous:!0}),window.removeEventListener("click",va.onUserActivity),window.removeEventListener("focus",va.onUserActivity),window.removeEventListener("keypress",va.onUserActivity),window.removeEventListener("mousemove",va.onUserActivity),window.removeEventListener(va.unloadevent,va.onUserActivity),window.clearInterval(va.everySecondTrigger),va.api.trigger("afterTearDown"),va}function kl(){var e;return null===(e=va.session)||void 0===e||e.destroy(),delete va.session,va.shouldClearCache()&&va.api.user.settings.clear(),va.api.trigger("clearSession",{synchronous:!0})}va.isUniView=function(){return["mobile","fullscreen","embedded"].includes(Cl.settings.get("view_mode"))},va.shouldClearCache=()=>!va.config.get("trusted")||Cl.settings.get("clear_cache_on_logout")||va.isTestEnv(),va.initConnection=function(){const e=va.api;if(!e.settings.get("bosh_service_url")){if(e.settings.get("authentication")===va.PREBIND)throw new Error("authentication is set to 'prebind' but we don't have a BOSH connection");if(!e.settings.get("websocket_url"))throw new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both.")}const t=va.isTestEnv()?fc:mc;if(("WebSocket"in window||"MozWebSocket"in window)&&e.settings.get("websocket_url"))va.connection=new t(e.settings.get("websocket_url"),Object.assign(va.default_connection_options,e.settings.get("connection_options")));else{if(!e.settings.get("bosh_service_url"))throw new Error("initConnection: this browser does not support websockets and bosh_service_url wasn't specified.");va.connection=new t(e.settings.get("bosh_service_url"),Object.assign(va.default_connection_options,e.settings.get("connection_options"),{keepalive:e.settings.get("keepalive")}))}!function(){const e={};e[le.LogLevel.DEBUG]="debug",e[le.LogLevel.INFO]="info",e[le.LogLevel.WARN]="warn",e[le.LogLevel.ERROR]="error",e[le.LogLevel.FATAL]="fatal",le.log=(t,n)=>M.log(n,e[t]),le.error=e=>M.error(e),va.connection.xmlInput=e=>M.debug(e.outerHTML,"color: darkgoldenrod"),va.connection.xmlOutput=e=>M.debug(e.outerHTML,"color: darkcyan")}(),e.trigger("connectionInitialized")},va.setUserJID=async function(e){return await async function(e,t){var n;const s=e.api.settings.get("connection_options").worker,i=le.getBareJidFromJid(t).toLowerCase(),r=`converse.session-${i}`;(null===(n=e.session)||void 0===n?void 0:n.get("id"))!==r?(function(e,t){if("sessionStorage"===e.api.settings.get("persistent_store"))return;if("BrowserExtLocal"===e.api.settings.get("persistent_store"))return po.localForage.defineDriver(wl.Z).then((()=>po.localForage.setDriver("webExtensionLocalStorage"))),void(e.storage.persistent=po.localForage);if("BrowserExtSync"===e.api.settings.get("persistent_store"))return po.localForage.defineDriver(Sl.Z).then((()=>po.localForage.setDriver("webExtensionSyncStorage"))),void(e.storage.persistent=po.localForage);const n={name:e.isTestEnv()?"converse-test-persistent":"converse-persistent",storeName:t};"localStorage"===e.api.settings.get("persistent_store")?(n.description="localStorage instance",n.driver=[po.localForage.LOCALSTORAGE]):"IndexedDB"===e.api.settings.get("persistent_store")&&(n.description="indexedDB instance",n.driver=[po.localForage.INDEXEDDB]),e.storage.persistent=po.localForage.createInstance(n)}(e,i),e.session=new Zo({id:r}),_o(e.session,r,s?"persistent":"session"),await new Promise((t=>e.session.fetch({success:t,error:t}))),!s&&e.session.get("active")&&(e.session.clear(),e.session.save({id:r})),xl(e,t),e.api.trigger("userSessionInitialized")):xl(e,t)}(va,e),va.api.trigger("setUserJID"),e},va.saveWindowState=function(e){let t;const n={focus:"visible",focusin:"visible",pageshow:"visible",blur:"hidden",focusout:"hidden",pagehide:"hidden"};t=(e=e||document.createEvent("Events")).type in n?n[e.type]:document.hidden?"hidden":"visible",va.windowState=t,Cl.trigger("windowStateChanged",{state:t})},va.ConnectionFeedback=Zo.extend({defaults:{connection_status:le.Status.DISCONNECTED,message:""},initialize(){this.on("change",(()=>Cl.trigger("connfeedback",va.connfeedback)))}});const jl=window.converse||{};Object.assign(jl,{CHAT_STATES:["active","composing","gone","inactive","paused"],keycodes:{TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESCAPE:27,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,FORWARD_SLASH:47,AT:50,META:91,META_RIGHT:93},async initialize(e){if(await async function(e){var t;const{api:n}=e;await n.trigger("cleanup",{synchronous:!0}),e.router.history.stop(),function(e){const{api:t}=e;document.removeEventListener("visibilitychange",e.saveWindowState),t.trigger("unregisteredGlobalEventHandlers")}(e),null===(t=e.connection)||void 0===t||t.reset(),e.stopListening(),e.off(),e.promises.initialized.isResolved&&n.promises.add("initialized")}(va),"onpagehide"in window?va.unloadevent="pagehide":"onbeforeunload"in window?va.unloadevent="beforeunload":"onunload"in window&&(va.unloadevent="unload"),function(e){ua=e,ha={};const t=ko(e,Object.keys(ma));Ct(va,ma,t),Ct(ha,ma,t)}(e),va.strict_plugin_dependencies=e.strict_plugin_dependencies,M.setLogLevel(Cl.settings.get("loglevel")),Cl.settings.get("authentication")===va.ANONYMOUS&&Cl.settings.get("auto_login")&&!Cl.settings.get("jid"))throw new Error("Config Error: you need to provide the server's domain via the 'jid' option when using anonymous authentication with auto_login.");var t;va.router.route(/^converse\?loglevel=(debug|info|warn|error|fatal)$/,"loglevel",(e=>M.setLogLevel(e))),va.connfeedback=new va.ConnectionFeedback,va.send_initial_presence=!0,await async function(e){await po.sessionStorageInitialized,e.storage={session:po.localForage.createInstance({name:e.isTestEnv()?"converse-test-session":"converse-session",description:"sessionStorage instance",driver:["sessionStorageWrapper"]})}}(va),await async function(e){const t="converse.client-config";e.config=new Zo({id:t,trusted:!0}),e.config.browserStorage=yo(t,"session"),await new Promise((t=>e.config.fetch({success:t,error:t}))),e.api.trigger("clientConfigInitialized")}(va),await o.initialize(),function(e){e.pluggable.initialized_plugins=[];const t=fe.concat(e.api.settings.get("whitelisted_plugins"));e.api.settings.get("singleton")&&["converse-bookmarks","converse-controlbox","converse-headline","converse-register"].forEach((t=>e.api.settings.get("blacklisted_plugins").push(t))),e.pluggable.initializePlugins({_converse:e},t,e.api.settings.get("blacklisted_plugins")),e.api.trigger("pluginsInitialized")}(va),t=va,document.addEventListener("visibilitychange",t.saveWindowState),t.saveWindowState({type:document.hidden?"blur":"focus"}),t.api.trigger("registeredGlobalEventHandlers");try{!History.started&&va.router.history.start()}catch(e){M.error(e)}Cl.settings.get("idle_presence_timeout")>0&&Cl.listen.on("addClientFeatures",(()=>Cl.disco.own.features.add(le.NS.IDLE)));const n=va.pluggable.plugins;if((Cl.settings.get("auto_login")||Cl.settings.get("keepalive")&&xa(n["converse-bosh"],"enabled"))&&await Cl.user.login(null,null,!0),Cl.trigger("initialized"),va.isTestEnv())return va},plugins:{add(e,t){if(t.__name__=e,void 0!==va.pluggable.plugins[e])throw new TypeError(`Error: plugin with name "${e}" has already been registered!`);va.pluggable.plugins[e]=t}},env:{$build:re,$iq:ae,$msg:oe,$pres:ce,utils:la,Collection:tc,Model:Zo,Promise,Strophe:le,URI:i(),dayjs:wa(),html:Qc,log:M,sizzle:Mo(),sprintf:r.sprintf,u:la}});const Nl=jl.env.utils;function Ol(e,t){Cl.send(oe({to:e.getAttribute("from"),type:"error",id:e.getAttribute("id")}).c("error",{type:"cancel"}).c("not-allowed",{xmlns:"urn:ietf:params:xml:ns:xmpp-stanzas"}).up().c("text",{xmlns:"urn:ietf:params:xml:ns:xmpp-stanzas"}).t(t)),M.warn(`Rejecting message stanza with the following reason: ${t}`),M.warn(e)}function $l(e,t,n,s){const i=oe({from:va.connection.jid,id:Nl.getUniqueId(),to:e,type:s||"chat"}).c(n,{xmlns:le.NS.MARKERS,id:t});Cl.send(i)}function Il(e){try{return e instanceof i()?e:new(i())(e)}catch(e){return M.debug(e),null}}function Ml(e,t){const n=Il(t);if(null===n||!function(e){const t=e.protocol().toLowerCase();return"http:"===window.location.protocol||"https:"===window.location.protocol&&["https","aesgcm"].includes(t)}(n))return!1;const s=n.filename().toLowerCase();return!!e.filter((e=>s.endsWith(e))).length}function Rl(e,t){const n=Il(t),s=n.subdomain(),i=n.domain(),r=`${s?`${s}.`:""}${i}`;return e.includes(i)||e.includes(r)}function Dl(e){const t=Cl.settings.get("embed_audio");if(!Array.isArray(t))return t;try{return Rl(t,e)}catch(e){return M.debug(e),!1}}function Ll(e){const t=Cl.settings.get("embed_videos");if(!Array.isArray(t))return t;try{return Rl(t,e)}catch(e){return M.debug(e),!1}}function zl(e){const t=Cl.settings.get("show_images_inline");if(!Array.isArray(t))return t;try{return Rl(t,e)}catch(e){return M.debug(e),!1}}function Pl(e){return Ml([".jpg",".jpeg",".png",".gif",".bmp",".tiff",".svg"],e)}function Fl(e){return Ml([".gif"],e)}function Ul(e){return Ml([".ogg",".mp3",".m4a"],e)}function Bl(e){return Ml([".mp4",".webm"],e)}function ql(e){const t=Cl.settings.get("image_urls_regex");return(null==t?void 0:t.test(e))||Pl(e)}const{NS:Hl}=le;class Gl extends Error{constructor(e,t){super(e,t),this.name="StanzaParseError",this.stanza=t}}function Wl(e,t){const n={},s=Mo()(`stanza-id[xmlns="${le.NS.SID}"]`,e).reduce(((e,t)=>(e[`stanza_id ${t.getAttribute("by")}`]=t.getAttribute("id"),e)),{});Object.assign(n,s);const i=Mo()(`message > result[xmlns="${le.NS.MAM}"]`,t).pop();i&&(n[`stanza_id ${t.getAttribute("from")||va.bare_jid}`]=i.getAttribute("id"));const r=Mo()(`origin-id[xmlns="${le.NS.SID}"]`,e).pop();return r&&(n.origin_id=r.getAttribute("id")),n}function Vl(e,t){var n;const s=Mo()(`encryption[xmlns="${le.NS.EME}"]`,e).pop(),i=null==s?void 0:s.getAttribute("namespace"),r={};if(i&&(r.is_encrypted=!0,r.encryption_namespace=i,i!==le.NS.OMEMO))return r;const o=Mo()(`encrypted[xmlns="${le.NS.OMEMO}"]`,e).pop();if(s||(r.is_encrypted=!!o),!o||Cl.settings.get("clear_cache_on_logout"))return r;const a=o.querySelector("header");r.encrypted={device_id:a.getAttribute("sid")};const c=null===(n=t.omemo_store)||void 0===n?void 0:n.get("device_id"),l=c&&Mo()(`key[rid="${c}"]`,o).pop();var d;return l&&Object.assign(r.encrypted,{iv:a.querySelector("iv").textContent,key:l.textContent,payload:(null===(d=o.querySelector("payload"))||void 0===d?void 0:d.textContent)||null,prekey:["true","1"].includes(l.getAttribute("prekey"))}),r}function Jl(e,t){const n=Mo()(`> apply-to[xmlns="${le.NS.FASTEN}"]`,e).pop();if(n){const e=n.getAttribute("id");if(Mo()(`> retract[xmlns="${le.NS.RETRACT}"]`,n).pop()){const n=Mo()(`delay[xmlns="${le.NS.DELAY}"]`,t).pop();return{editable:!1,retracted:n?wa()(n.getAttribute("stamp")).toISOString():(new Date).toISOString(),retracted_id:e}}}else{const t=Mo()(`> retracted[xmlns="${le.NS.RETRACT}"]`,e).pop();if(t)return{editable:!1,is_tombstone:!0,retracted:t.getAttribute("stamp")}}return{}}function Kl(e,t){const n=Mo()(`replace[xmlns="${le.NS.MESSAGE_CORRECT}"]`,e).pop();if(n){const e=n.getAttribute("id"),s=e;if(e){const n=Mo()(`delay[xmlns="${le.NS.DELAY}"]`,t).pop();return{msgid:s,replace_id:e,edited:n?wa()(n.getAttribute("stamp")).toISOString():(new Date).toISOString()}}}return{}}function Yl(e){const t=[];if(!e)return{};try{i().withinString(e,((e,n,s)=>(t.push({url:e,start:n,end:s}),e)),ge)}catch(e){M.debug(e)}const n=t.filter((e=>ql(e.url)&&zl(e.url)||Bl(e.url)&&Ll(e.url)||Ul(e.url)&&Dl(e.url))).map((e=>({start:e.start,end:e.end})));return n.length?{media_urls:n}:{}}function Ql(e){const t=Mo()(`spoiler[xmlns="${le.NS.SPOILER}"]`,e).pop();return{is_spoiler:!!t,spoiler_hint:null==t?void 0:t.textContent}}function Xl(e){const t=Mo()(`x[xmlns="${le.NS.OUTOFBAND}"]`,e).pop();var n,s;return t?{oob_url:null===(n=t.querySelector("url"))||void 0===n?void 0:n.textContent,oob_desc:null===(s=t.querySelector("desc"))||void 0===s?void 0:s.textContent}:{}}function Zl(e){if("error"===e.getAttribute("type")){const t=e.querySelector("error"),n=Mo()(`text[xmlns="${le.NS.STANZAS}"]`,t).pop();return{is_error:!0,error_text:null==n?void 0:n.textContent,error_type:t.getAttribute("type"),error_condition:t.firstElementChild.nodeName}}return{}}function ed(e){return Mo()(`reference[xmlns="${le.NS.REFERENCE}"]`,e).map((t=>{var n;const s=t.getAttribute("anchor"),i=null===(n=e.querySelector(s?`#${s}`:"body"))||void 0===n?void 0:n.textContent;if(!i)return M.warn(`Could not find referenced text for ${t}`),null;const r=t.getAttribute("begin"),o=t.getAttribute("end");return{begin:r,end:o,type:t.getAttribute("type"),value:i.slice(r,o),uri:t.getAttribute("uri")}})).filter((e=>e))}function td(e){const t=Mo()(`received[xmlns="${le.NS.RECEIPTS}"]`,e).pop();return null==t?void 0:t.getAttribute("id")}function nd(e){const t=le.NS.CARBONS;return Mo()(`message > received[xmlns="${t}"]`,e).length>0||Mo()(`message > sent[xmlns="${t}"]`,e).length>0}function sd(e){var t;return null===(t=Mo()(`\n composing[xmlns="${Hl.CHATSTATES}"],\n paused[xmlns="${Hl.CHATSTATES}"],\n inactive[xmlns="${Hl.CHATSTATES}"],\n active[xmlns="${Hl.CHATSTATES}"],\n gone[xmlns="${Hl.CHATSTATES}"]`,e).pop())||void 0===t?void 0:t.nodeName}function id(e,t){return"me"!==t.sender&&!t.is_carbon&&!t.is_archived&&Mo()(`request[xmlns="${le.NS.RECEIPTS}"]`,e).length}function rd(e){if(Mo()(`message > forwarded[xmlns="${le.NS.FORWARD}"]`,e).length){Ol(e,"Forwarded messages not part of an encapsulating protocol are not supported");const t=e.getAttribute("from");throw new Gl(`Ignoring unencapsulated forwarded message from ${t}`,e)}}function od(e){return Mo()(`\n acknowledged[xmlns="${le.NS.MARKERS}"],\n displayed[xmlns="${le.NS.MARKERS}"],\n received[xmlns="${le.NS.MARKERS}"]`,e).pop()}function ad(e){return"headline"===e.getAttribute("type")}function cd(e){if(Mo()(`mentions[xmlns="${le.NS.MENTIONS}"]`,e).pop())return!1;const t=e.getAttribute("from");return!("error"===e.getAttribute("type")||!t||t.includes("@"))}function ld(e){return!!Mo()(`message > result[xmlns="${le.NS.MAM}"]`,e).pop()}function dd(e){return e.getAttributeNames().reduce(((t,n)=>(t[n]=le.xmlunescape(e.getAttribute(n)),t)),{})}const{Strophe:ud}=jl.env;let hd,md;ud.addNamespace("ADHOC","http://jabber.org/protocol/commands");const fd={adhoc:{async getCommands(e){let t=[];try{n=await md.disco.items(e,ud.NS.ADHOC),t=Mo()(`query[xmlns="${ud.NS.DISCO_ITEMS}"][node="${ud.NS.ADHOC}"] item`,n).map(dd)}catch(t){null===t?M.error(`Error: timeout while fetching ad-hoc commands for ${e}`):(M.error(`Error while fetching ad-hoc commands for ${e}`),M.error(t))}var n;return t}}};jl.plugins.add("converse-adhoc",{dependencies:["converse-disco"],initialize(){hd=this._converse,md=hd.api,Object.assign(md,fd)}});const gd=Zo.extend({initialize(){this.rosterContactAdded=ji()},async setRosterContact(e){const t=await Cl.contacts.get(e);t&&(this.contact=t,this.set("nickname",t.get("nickname")),this.rosterContactAdded.resolve())}});var pd=n(6755),vd=n.n(pd);const{u:bd}=jl.env;function yd(e){const t=Cl.settings.get("prune_messages_above");if(t&&"number"==typeof t&&e.messages.length>t){const n=e.messages.filter((e=>!bd.isEmptyMessage(e)));if(n.length>t){for(;n.length>t;)n.shift().destroy();Cl.trigger("historyPruned",e)}}}const _d=hc(yd,250),{Strophe:wd,sizzle:Sd}=jl.env;async function xd(e,t){var n,s,i,r,o,a;rd(e);let c=e.getAttribute("to");const l=wd.getResourceFromJid(c);if(Cl.settings.get("filter_by_resource")&&l&&l!==t.resource)return new Gl(`Ignoring incoming message intended for a different resource: ${c}`,e);const d=e;let u=e.getAttribute("from")||t.bare_jid;if(nd(e)){if(u!==t.bare_jid)return Ol(e,"Rejecting carbon from invalid JID"),new Gl(`Rejecting carbon from invalid JID ${c}`,e);{const t=`[xmlns="${wd.NS.CARBONS}"] > forwarded[xmlns="${wd.NS.FORWARD}"] > message`;c=(e=Sd(t,e).pop()).getAttribute("to"),u=e.getAttribute("from")}}const h=ld(e);if(h){if(u!==t.bare_jid)return new Gl(`Invalid Stanza: alleged MAM message from ${e.getAttribute("from")}`,e);{const t=`[xmlns="${wd.NS.MAM}"] > forwarded[xmlns="${wd.NS.FORWARD}"] > message`;c=(e=Sd(t,e).pop()).getAttribute("to"),u=e.getAttribute("from")}}const m=wd.getBareJidFromJid(u),f=m===t.bare_jid;if(f&&null===c)return new Gl(`Don't know how to handle message stanza without 'to' attribute. ${e.outerHTML}`,e);const g=ad(e),p=cd(e);let v,b;if(!g&&!p&&(b=f?wd.getBareJidFromJid(c):m,v=await Cl.contacts.get(b),void 0===v&&!Cl.settings.get("allow_non_roster_messaging")))return M.error(e),new Gl("Blocking messaging with a JID not in our roster because allow_non_roster_messaging is false.",e);const y=Sd(`delay[xmlns="${wd.NS.DELAY}"]`,d).pop(),_=od(e),w=(new Date).toISOString();let S=Object.assign({contact_jid:b,is_archived:h,is_headline:g,is_server_message:p,body:null===(n=e.querySelector("body"))||void 0===n||null===(s=n.textContent)||void 0===s?void 0:s.trim(),chat_state:sd(e),from:wd.getBareJidFromJid(e.getAttribute("from")),is_carbon:nd(d),is_delayed:!!y,is_markable:!!Sd(`markable[xmlns="${wd.NS.MARKERS}"]`,e).length,is_marker:!!_,is_unstyled:!!Sd(`unstyled[xmlns="${wd.NS.STYLING}"]`,e).length,marker_id:_&&_.getAttribute("id"),msgid:e.getAttribute("id")||d.getAttribute("id"),nick:null===(i=v)||void 0===i||null===(r=i.attributes)||void 0===r?void 0:r.nickname,receipt_id:td(e),received:(new Date).toISOString(),references:ed(e),sender:f?"me":"them",subject:null===(o=e.querySelector("subject"))||void 0===o?void 0:o.textContent,thread:null===(a=e.querySelector("thread"))||void 0===a?void 0:a.textContent,time:y?wa()(y.getAttribute("stamp")).toISOString():w,to:e.getAttribute("to"),type:e.getAttribute("type")},Zl(e),Xl(e),Ql(e),Kl(e,d),Wl(e,d),Jl(e,d),Vl(e,t));if(S.is_archived){const n=d.getAttribute("from");if(n&&n!==t.bare_jid)return new Gl(`Invalid Stanza: Forged MAM message from ${n}`,e)}return await Cl.emojis.initialize(),S=Object.assign({message:S.body||S.error,is_only_emojis:!!S.body&&la.isOnlyEmojis(S.body),is_valid_receipt_request:id(e,S)},S),S.id=S.origin_id||S[`stanza_id ${S.from}`]||la.getUniqueId(),S=await Cl.hook("parseMessage",e,S),Object.assign(S,Yl(S.is_encrypted?S.plaintext:S.body))}const{Strophe:Ed,$msg:Ad}=jl.env,Cd=jl.env.utils,Td=gd.extend({defaults(){return{bookmarked:!1,chat_state:void 0,hidden:va.isUniView()&&!Cl.settings.get("singleton"),message_type:"chat",nickname:void 0,num_unread:0,time_opened:this.get("time_opened")||(new Date).getTime(),time_sent:new Date(0).toISOString(),type:va.PRIVATE_CHAT_TYPE,url:""}},async initialize(){this.initialized=ji(),gd.prototype.initialize.apply(this,arguments);const e=this.get("jid");e&&(this.set({box_id:`box-${e}`}),this.initNotifications(),this.initUI(),this.initMessages(),this.get("type")===va.PRIVATE_CHAT_TYPE&&(this.presence=va.presences.findWhere({jid:e})||va.presences.create({jid:e}),await this.setRosterContact(e),this.presence.on("change:show",(e=>this.onPresenceChanged(e)))),this.on("change:chat_state",this.sendChatState,this),this.ui.on("change:scrolled",this.onScrolledChanged,this),await this.fetchMessages(),await Cl.trigger("chatBoxInitialized",this,{Synchronous:!0}),this.initialized.resolve())},getMessagesCollection:()=>new va.Messages,getMessagesCacheKey(){return`converse.messages-${this.get("jid")}-${va.bare_jid}`},initMessages(){this.messages=this.getMessagesCollection(),this.messages.fetched=ji(),this.messages.fetched.then((()=>{this.pruneHistoryWhenScrolledDown(),Cl.trigger("afterMessagesFetched",this)})),this.messages.chatbox=this,_o(this.messages,this.getMessagesCacheKey()),this.listenTo(this.messages,"change:upload",this.onMessageUploadChanged,this),this.listenTo(this.messages,"add",this.onMessageAdded,this)},initUI(){this.ui=new Zo},initNotifications(){this.notifications=new Zo},getNotificationsText(){var e,t,n;const{__:s}=va;return(null===(e=this.notifications)||void 0===e?void 0:e.get("chat_state"))===va.COMPOSING?s("%1$s is typing",this.getDisplayName()):(null===(t=this.notifications)||void 0===t?void 0:t.get("chat_state"))===va.PAUSED?s("%1$s has stopped typing",this.getDisplayName()):(null===(n=this.notifications)||void 0===n?void 0:n.get("chat_state"))===va.GONE?s("%1$s has gone away",this.getDisplayName()):""},afterMessagesFetched(e){this.most_recent_cached_message=e?this.getMostRecentMessage(e):null,Cl.trigger("afterMessagesFetched",this)},fetchMessages(){if(this.messages.fetched_flag)return void M.info(`Not re-fetching messages for ${this.get("jid")}`);this.most_recent_cached_message=null,this.messages.fetched_flag=!0;const e=this.messages.fetched.resolve;return this.messages.fetch({add:!0,success:t=>{this.afterMessagesFetched(t),e()},error:()=>{this.afterMessagesFetched(),e()}}),this.messages.fetched},async handleErrorMessageStanza(e){const{__:t}=va,n=await xd(e,va);if(!await this.shouldShowErrorMessage(n))return;const s=this.getMessageReferencedByError(n);if(s){const e={error:n.error,error_condition:n.error_condition,error_text:n.error_text,error_type:n.error_type,editable:!1};n.msgid===s.get("retraction_id")?(e.retraction_id=void 0,n.error||("forbidden"===n.error_condition?e.error=t("You're not allowed to retract your message."):e.error=t("Sorry, an error occurred while trying to retract your message."))):n.error||("forbidden"===n.error_condition?e.error=t("You're not allowed to send a message."):e.error=t("Sorry, an error occurred while trying to send your message.")),s.save(e)}else this.createMessage(n)},queueMessage(e){return this.msg_chain=(this.msg_chain||this.messages.fetched).then((()=>this.onMessage(e))).catch((e=>M.error(e))),this.msg_chain},async onMessage(e){if(e=await e,Cd.isErrorObject(e))return e.stanza&&M.error(e.stanza),M.error(e.message);const t=this.getDuplicateMessage(e);if(t)this.updateMessage(t,e);else if(!this.handleReceipt(e)&&!this.handleChatMarker(e)&&!await this.handleRetraction(e)&&(this.setEditable(e,e.time),e.chat_state&&"them"===e.sender&&this.notifications.set("chat_state",e.chat_state),Cd.shouldCreateMessage(e))){const t=this.handleCorrection(e)||await this.createMessage(e);this.notifications.set({chat_state:null}),this.handleUnreadMessage(t)}},async onMessageUploadChanged(e){if(e.get("upload")===va.SUCCESS){const t={body:e.get("message"),spoiler_hint:e.get("spoiler_hint"),oob_url:e.get("oob_url")};await this.sendMessage(t),e.destroy()}},onMessageAdded(e){!Cl.settings.get("prune_messages_above")||"scrolled"!==Cl.settings.get("pruning_behavior")&&this.ui.get("scrolled")||Cd.isEmptyMessage(e)||_d(this)},async clearMessages(){try{await this.messages.clearStore()}catch(e){this.messages.trigger("reset"),M.error(e)}finally{delete this.msg_chain,delete this.messages.fetched_flag,this.messages.fetched=ji()}},async close(){Cl.connection.connected()&&(this.setChatState(va.INACTIVE),this.sendChatState());try{await new Promise(((e,t)=>this.destroy({success:e,error:(e,n)=>t(n)})))}catch(e){M.error(e)}finally{Cl.settings.get("clear_messages_on_reconnection")&&await this.clearMessages()}Cl.trigger("chatBoxClosed",this)},announceReconnection(){Cl.trigger("chatReconnected",this)},async onReconnection(){Cl.settings.get("clear_messages_on_reconnection")&&await this.clearMessages(),this.announceReconnection()},onPresenceChanged(e){const{__:t}=va,n=e.get("show"),s=this.getDisplayName();let i;"offline"===n?i=t("%1$s has gone offline",s):"away"===n?i=t("%1$s has gone away",s):"dnd"===n?i=t("%1$s is busy",s):"online"===n&&(i=t("%1$s is online",s)),i&&this.createMessage({message:i,type:"info"})},onScrolledChanged(){this.ui.get("scrolled")||(this.clearUnreadMsgCounter(),this.pruneHistoryWhenScrolledDown())},pruneHistoryWhenScrolledDown(){Cl.settings.get("prune_messages_above")&&"unscrolled"===Cl.settings.get("pruning_behavior")&&!this.ui.get("scrolled")&&yd(this)},validate(e){if(!e.jid)return"Ignored ChatBox without JID";const t=Cl.settings.get("auto_join_rooms").map((e=>pe(e)?e.jid:e)),n=Cl.settings.get("auto_join_private_chats").concat(t);if(Cl.settings.get("singleton")&&!n.includes(e.jid)&&!Cl.settings.get("auto_join_on_invite")){const t=`${e.jid} is not allowed because singleton is true and it's not being auto_joined`;return M.warn(t),t}},getDisplayName(){return this.contact?this.contact.getDisplayName():this.vcard?this.vcard.getDisplayName():this.get("jid")},async createMessageFromError(e){e instanceof va.TimeoutError&&((await this.createMessage({type:"error",message:e.message,retry_event_id:e.retry_event_id})).error=e)},editEarlierMessage(){let e,t=this.messages.findLastIndex("correcting");if(t>=0)for(this.messages.at(t).save("correcting",!1);t>0;){t-=1;const n=this.messages.at(t);if(n.get("editable")){e=n;break}}e=e||this.messages.filter({sender:"me"}).reverse().find((e=>e.get("editable"))),e&&e.save("correcting",!0)},editLaterMessage(){let e,t=this.messages.findLastIndex("correcting");if(t>=0)for(this.messages.at(t).save("correcting",!1);t=0;t--){const n=e.at(t);if(n.get("type")===this.get("message_type"))return n}},getUpdatedMessageAttributes:(e,t)=>(({is_archived:e})=>({is_archived:e}))(t),updateMessage(e,t){const n=this.getUpdatedMessageAttributes(e,t);n&&e.save(n)},setChatState(e,t){return void 0!==this.chat_state_timeout&&(window.clearTimeout(this.chat_state_timeout),delete this.chat_state_timeout),e===va.COMPOSING?this.chat_state_timeout=window.setTimeout(this.setChatState.bind(this),va.TIMEOUTS.PAUSED,va.PAUSED):e===va.PAUSED&&(this.chat_state_timeout=window.setTimeout(this.setChatState.bind(this),va.TIMEOUTS.INACTIVE,va.INACTIVE)),this.set("chat_state",e,t),this},getMessageReferencedByError(e){const t=e.msgid;return t&&this.messages.models.find((e=>[e.get("msgid"),e.get("retraction_id")].includes(t)))},shouldShowErrorMessage(e){if(this.getMessageReferencedByError(e)||e.body)return!0},isSameUser:(e,t)=>Cd.isSameBareJID(e,t),findDanglingRetraction(e){if(!e.origin_id||!this.messages.length)return null;if(this.messages.last().get("time")>e.time){const t=Array.from(this.messages.models);return t.reverse(),t.find((({attributes:t})=>t.retracted_id===e.origin_id&&t.from===e.from&&!t.moderated_by))}},async handleRetraction(e){const t=["retracted","retracted_id","editable"];if(e.retracted){if(e.is_tombstone)return!1;const n=this.messages.findWhere({origin_id:e.retracted_id,from:e.from});return n?(n.save(ko(e,t)),!0):(e.dangling_retraction=!0,await this.createMessage(e),!0)}{const n=this.findDanglingRetraction(e);if(n){const s=ko(n.attributes,t),i=Object.assign({dangling_retraction:!1},e,s);return delete i.id,n.save(i),!0}}return!1},handleCorrection(e){if(!e.replace_id||!e.from)return;const t=this.messages.findWhere({msgid:e.replace_id,from:e.from});if(!t)return;const n=t.get("older_versions")||{};return e.timee));return this.messages.models.find((e=>t.reduce(((t,n)=>t||function(e,t){return e===t||In(e,t,Rn(t))}(e.attributes,n)),!1)))},getOriginIdQueryAttrs:e=>e.origin_id&&{origin_id:e.origin_id,from:e.from},getStanzaIdQueryAttrs:e=>Object.keys(e).filter((e=>e.startsWith("stanza_id "))).map((t=>{const n={};return n[`stanza_id ${t.replace(/^stanza_id /,"")}`]=e[t],n})),getMessageBodyQueryAttrs(e){if(e.message&&e.msgid){const t={from:e.from,msgid:e.msgid};return e.is_encrypted||(t.message=e.message),t}},retractOwnMessage(e){this.sendRetractionMessage(e),e.save({retracted:(new Date).toISOString(),retracted_id:e.get("origin_id"),retraction_id:e.get("id"),is_ephemeral:!0,editable:!1})},sendRetractionMessage(e){const t=e.get("origin_id");if(!t)throw new Error("Can't retract message without a XEP-0359 Origin ID");const n=Ad({id:Cd.getUniqueId(),to:this.get("jid"),type:"chat"}).c("store",{xmlns:Ed.NS.HINTS}).up().c("apply-to",{id:t,xmlns:Ed.NS.FASTEN}).c("retract",{xmlns:Ed.NS.RETRACT});return va.connection.send(n)},sendMarkerForLastMessage(e="displayed",t=!1){const n=Array.from(this.messages.models);n.reverse();const s=n.find((e=>"them"===e.get("sender")&&(t||e.get("is_markable"))));s&&this.sendMarkerForMessage(s,e,t)},sendMarkerForMessage(e,t="displayed",n=!1){e&&Cl.settings.get("send_chat_markers").includes(t)&&(null!=e&&e.get("is_markable")||n)&&$l(Ed.getBareJidFromJid(e.get("from")),e.get("msgid"),t,e.get("type"))},handleChatMarker(e){if(Ed.getBareJidFromJid(e.to)!==va.bare_jid)return!1;if(e.is_markable)return!this.contact||e.is_archived||e.is_carbon||$l(e.from,e.msgid,"received"),!1;if(e.marker_id){const t=this.messages.findWhere({msgid:e.marker_id}),n=`marker_${e.marker}`;return t&&!t.get(n)&&t.save({field_name:(new Date).toISOString()}),!0}},sendReceiptStanza(e,t){const n=Ad({from:va.connection.jid,id:Cd.getUniqueId(),to:e,type:"chat"}).c("received",{xmlns:Ed.NS.RECEIPTS,id:t}).up().c("store",{xmlns:Ed.NS.HINTS}).up();Cl.send(n)},handleReceipt(e){if("them"===e.sender)if(e.is_valid_receipt_request)this.sendReceiptStanza(e.from,e.msgid);else if(e.receipt_id){const t=this.messages.findWhere({msgid:e.receipt_id});return t&&!t.get("received")&&t.save({received:(new Date).toISOString()}),!0}return!1},createMessageStanza(e){const t=Ad({from:va.connection.jid,to:this.get("jid"),type:this.get("message_type"),id:e.get("edited")&&Cd.getUniqueId()||e.get("msgid")}).c("body").t(e.get("message")).up().c(va.ACTIVE,{xmlns:Ed.NS.CHATSTATES}).root();return"chat"===e.get("type")&&t.c("request",{xmlns:Ed.NS.RECEIPTS}).root(),e.get("is_spoiler")&&(e.get("spoiler_hint")?t.c("spoiler",{xmlns:Ed.NS.SPOILER},e.get("spoiler_hint")).root():t.c("spoiler",{xmlns:Ed.NS.SPOILER}).root()),(e.get("references")||[]).forEach((e=>{const n={xmlns:Ed.NS.REFERENCE,begin:e.begin,end:e.end,type:e.type};e.uri&&(n.uri=e.uri),t.c("reference",n).root()})),e.get("oob_url")&&t.c("x",{xmlns:Ed.NS.OUTOFBAND}).c("url").t(e.get("oob_url")).root(),e.get("edited")&&t.c("replace",{xmlns:Ed.NS.MESSAGE_CORRECT,id:e.get("msgid")}).root(),e.get("origin_id")&&t.c("origin-id",{xmlns:Ed.NS.SID,id:e.get("origin_id")}).root(),t},getOutgoingMessageAttributes(e){const t=!!this.get("composing_spoiler"),n=Cd.getUniqueId(),s=null==e?void 0:e.body,i=s?Cd.httpToGeoUri(Cd.shortnamesToUnicode(s),va):void 0;return Object.assign({},e,{from:va.bare_jid,fullname:va.xmppstatus.get("fullname"),id:n,is_only_emojis:!!s&&Cd.isOnlyEmojis(s),jid:this.get("jid"),message:i,msgid:n,nickname:this.get("nickname"),sender:"me",time:(new Date).toISOString(),type:this.get("message_type"),body:i,is_spoiler:t,origin_id:n},Yl(s))},setEditable(e,t){if(!e.is_headline&&!Cd.isEmptyMessage(e)&&"me"===e.sender)if("all"===Cl.settings.get("allow_message_corrections"))e.editable=!(e.file||e.retracted||"oob_url"in e);else if("last"===Cl.settings.get("allow_message_corrections")&&t>this.get("time_sent")){this.set({time_sent:t});const n=this.messages.findWhere({editable:!0});n&&n.save({editable:!1}),e.editable=!(e.file||e.retracted||"oob_url"in e)}},async createMessage(e,t){return e.time=e.time||(new Date).toISOString(),await this.messages.fetched,this.messages.create(e,t)},async sendMessage(e){e=this.getOutgoingMessageAttributes(e);let t=this.messages.findWhere("correcting");if(t){const n=t.get("older_versions")||{};n[t.get("time")]=t.get("message"),t.save({correcting:!1,edited:(new Date).toISOString(),message:e.message,older_versions:n,references:e.references,is_only_emojis:e.is_only_emojis,origin_id:Cd.getUniqueId(),received:void 0})}else this.setEditable(e,(new Date).toISOString()),t=await this.createMessage(e);return Cl.send(this.createMessageStanza(t)),Cl.trigger("sendMessage",{chatbox:this,message:t}),t},sendChatState(){if(Cl.settings.get("send_chat_state_notifications")&&this.get("chat_state")){const e=Cl.settings.get("send_chat_state_notifications");if(Array.isArray(e)&&!e.includes(this.get("chat_state")))return;Cl.send(Ad({id:Cd.getUniqueId(),to:this.get("jid"),type:"chat"}).c(this.get("chat_state"),{xmlns:Ed.NS.CHATSTATES}).up().c("no-store",{xmlns:Ed.NS.HINTS}).up().c("no-permanent-store",{xmlns:Ed.NS.HINTS}))}},async sendFiles(e){var t;const{__:n}=va,s=(await Cl.disco.features.get(Ed.NS.HTTPUPLOAD,va.domain)).pop();if(!s)return void this.createMessage({message:n("Sorry, looks like file upload is not supported by your server."),type:"error",is_ephemeral:!0});const i=s.dataforms.where({FORM_TYPE:{value:Ed.NS.HTTPUPLOAD,type:"hidden"}}).pop(),r=window.parseInt(null===(t=((null==i?void 0:i.attributes)||{})["max-file-size"])||void 0===t?void 0:t.value),o=null==s?void 0:s.id;o?Array.from(e).forEach((async e=>{if(e=await Cl.hook("beforeFileUpload",this,e),!window.isNaN(r)&&window.parseInt(e.size)>r)return this.createMessage({message:n("The size of your file, %1$s, exceeds the maximum allowed by your server, which is %2$s.",e.name,vd()(r)),type:"error",is_ephemeral:!0});{const t=Object.assign(this.getOutgoingMessageAttributes(),{file:!0,progress:0,slot_request_url:o});this.setEditable(t,(new Date).toISOString());const n=await this.createMessage(t,{silent:!0});n.file=e,this.messages.trigger("add",n),n.getRequestSlotURL()}})):this.createMessage({message:n("Sorry, looks like file upload is not supported by your server."),type:"error",is_ephemeral:!0})},maybeShow(e){if(!va.isUniView())return Cd.safeSave(this,{hidden:!1}),this.trigger("show"),this;{const t=e=>!e.get("hidden")&&e.get("jid")!==this.get("jid")&&"controlbox"!==e.get("id"),n=va.chatboxes.filter(t);(e||0===n.length)&&(n.forEach((e=>Cd.safeSave(e,{hidden:!0}))),Cd.safeSave(this,{hidden:!1}))}},isHidden(){return this.get("hidden")||this.isScrolledUp()||"hidden"===va.windowState},handleUnreadMessage(e){null!=e&&e.get("body")&&Cd.isNewMessage(e)&&("me"===e.get("sender")?this.ui.set("scrolled",!1):this.isHidden()?this.incrementUnreadMsgsCounter(e):this.sendMarkerForMessage(e))},incrementUnreadMsgsCounter(e){const t={num_unread:this.get("num_unread")+1};0===this.get("num_unread")&&(t.first_unread_id=e.get("id")),this.save(t)},clearUnreadMsgCounter(){this.get("num_unread")>0&&this.sendMarkerForMessage(this.messages.last()),Cd.safeSave(this,{num_unread:0})},isScrolledUp(){return this.ui.get("scrolled")}}),kd=jl.env.utils,{Strophe:jd}=jl.env,Nd={defaults:()=>({msgid:kd.getUniqueId(),time:(new Date).toISOString(),is_ephemeral:!1}),async initialize(){this.checkValidity()&&(this.initialized=ji(),"chat"===this.get("type")&&(gd.prototype.initialize.apply(this,arguments),this.setRosterContact(jd.getBareJidFromJid(this.get("from")))),this.get("file")&&this.on("change:put",this.uploadFile,this),this.setTimerForEphemeralMessage(),await Cl.trigger("messageInitialized",this,{Synchronous:!0}),this.initialized.resolve())},setTimerForEphemeralMessage(){const e=()=>{this.ephemeral_timer=window.setTimeout(this.safeDestroy.bind(this),1e4)};return this.isEphemeral()?(e(),!0):(this.on("change:is_ephemeral",(()=>this.isEphemeral()?e():clearTimeout(this.ephemeral_timer))),!1)},checkValidity(){return 3!==Object.keys(this.attributes).length||(this.validationError="Empty message",this.safeDestroy(),!1)},mayBeRetracted(){const e="me"===this.get("sender"),t="cancel"!==this.get("error_type");return e&&t&&["all","own"].includes(Cl.settings.get("allow_message_retraction"))},safeDestroy(){try{this.destroy()}catch(e){M.error(e)}},isEphemeral(){return this.get("is_ephemeral")},isMeCommand(){const e=this.getMessageText();return!!e&&e.startsWith("/me ")},isFollowup(){const e=this.collection.models,t=e.indexOf(this),n=t?e[t-1]:null;if(null===n)return!1;const s=wa()(this.get("time"));return this.get("from")===n.get("from")&&!this.isMeCommand()&&!n.isMeCommand()&&"info"!==this.get("type")&&"info"!==n.get("type")&&s.isBefore(wa()(n.get("time")).add(10,"minutes"))&&!!this.get("is_encrypted")==!!n.get("is_encrypted")},getDisplayName(){return"groupchat"===this.get("type")?this.get("nick"):this.contact?this.contact.getDisplayName():this.vcard?this.vcard.getDisplayName():this.get("from")},getMessageText(){const{__:e}=va;return this.get("is_encrypted")?this.get("plaintext")||this.get("body")||e("Undecryptable OMEMO message"):this.get("message")},sendSlotRequestStanza(){if(!this.file)return Promise.reject(new Error("file is undefined"));const e=jl.env.$iq({from:va.jid,to:this.get("slot_request_url"),type:"get"}).c("request",{xmlns:jd.NS.HTTPUPLOAD,filename:this.file.name,size:this.file.size,"content-type":this.file.type});return Cl.sendIQ(e)},async getRequestSlotURL(){const{__:e}=va;let t;try{t=await this.sendSlotRequestStanza()}catch(t){return M.error(t),this.save({type:"error",message:e("Sorry, could not determine upload URL."),is_ephemeral:!0})}const n=t.querySelector("slot");if(!n)return this.save({type:"error",message:e("Sorry, could not determine file upload URL."),is_ephemeral:!0});this.save({get:n.querySelector("get").getAttribute("url"),put:n.querySelector("put").getAttribute("url")})},uploadFile(){const e=new XMLHttpRequest;e.onreadystatechange=async()=>{if(e.readyState===XMLHttpRequest.DONE)if(M.info("Status: "+e.status),200===e.status||201===e.status){let e={upload:va.SUCCESS,oob_url:this.get("get"),message:this.get("get"),body:this.get("get")};e=await Cl.hook("afterFileUploaded",this,e),this.save(e)}else e.onerror()},e.upload.addEventListener("progress",(e=>{e.lengthComputable&&this.set("progress",e.loaded/e.total)}),!1),e.onerror=()=>{const{__:t}=va;let n;n=e.responseText?t('Sorry, could not succesfully upload your file. Your server’s response: "%1$s"',e.responseText):t("Sorry, could not succesfully upload your file."),this.save({type:"error",upload:va.FAILURE,message:n,is_ephemeral:!0})},e.open("PUT",this.get("put"),!0),e.setRequestHeader("Content-type",this.file.type),e.send(this.file)}},Od={chats:{async create(e,t){if("string"==typeof e){if(t&&(null==t||!t.fullname)){var n;const s=await Cl.contacts.get(e);t.fullname=null==s||null===(n=s.attributes)||void 0===n?void 0:n.fullname}return Cl.chats.get(e,t,!0)||void M.error("Could not open chatbox for JID: "+e)}return Array.isArray(e)?Promise.all(e.forEach((async n=>{var s;const i=await Cl.contacts.get(e);return t.fullname=null==i||null===(s=i.attributes)||void 0===s?void 0:s.fullname,Cl.chats.get(n,t,!0).maybeShow()}))):(M.error("chats.create: You need to provide at least one JID"),null)},async open(e,t,n){if("string"==typeof e){const s=await Cl.chats.get(e,t,!0);return s?s.maybeShow(n):s}if(Array.isArray(e))return Promise.all(e.map((e=>Cl.chats.get(e,t,!0).then((e=>e&&e.maybeShow(n))))).filter((e=>e)));const s="chats.open: You need to provide at least one JID";throw M.error(s),new Error(s)},async get(e,t={},n=!1){async function s(e){let s=await Cl.chatboxes.get(e);return!s&&n?s=await Cl.chatboxes.create(e,t,va.ChatBox):(s=s&&s.get("type")===va.PRIVATE_CHAT_TYPE?s:null,s&&Object.keys(t).length&&s.save(t)),s}return await Cl.waitUntil("chatBoxesFetched"),void 0===e?(await Cl.chatboxes.get()).filter((e=>e.get("type")===va.PRIVATE_CHAT_TYPE)):"string"==typeof e?s(e):Promise.all(e.map((e=>s(e))))}}},{Strophe:$d,sizzle:Id,u:Md}=jl.env;function Rd(e){if(!Md.isValidJID(e))return M.warn(`Invalid JID "${e}" provided in URL fragment`);Cl.chats.open(e)}async function Dd(){if(va.shouldClearCache()){await Promise.all(va.chatboxes.map((e=>e.messages&&e.messages.clearStore({silent:!0}))));const e=e=>e.get("type")!==va.CONTROLBOX_TYPE;va.chatboxes.clearStore({silent:!0},e)}}function Ld(){Cl.settings.get("auto_join_private_chats").forEach((e=>{va.chatboxes.where({jid:e}).length||("string"==typeof e?Cl.chats.open(e):M.error('Invalid jid criteria specified for "auto_join_private_chats"'))})),Cl.trigger("privateChatsAutoJoined")}function zd(){va.connection.addHandler((e=>Id(`message > result[xmlns="${$d.NS.MAM}"]`,e).pop()?(M.warn('Received a MAM message with type "chat".'),!0):(va.handleMessageStanza(e),!0)),null,"message","chat"),va.connection.addHandler((e=>(null!==e.getAttribute("type")||va.handleMessageStanza(e),!0)),$d.NS.RECEIPTS,"message"),va.connection.addHandler((e=>(async function(e){const t=$d.getBareJidFromJid(e.getAttribute("from"));if(Md.isSameBareJID(t,va.bare_jid))return;const n=await Cl.chatboxes.get(t);n.get("type")===va.PRIVATE_CHAT_TYPE&&(null==n||n.handleErrorMessageStanza(e))}(e),!0)),null,"message","error")}async function Pd(e){if(cd(e)){const t=e.getAttribute("from");return M.info(`handleMessageStanza: Ignoring incoming server message from JID: ${t}`)}const t=await xd(e,va);if(Md.isErrorObject(t))return t.stanza&&M.error(t.stanza),M.error(t.message);const n=!!Id(`body, encrypted[xmlns="${$d.NS.OMEMO}"]`,e).length,s=await Cl.chats.get(t.contact_jid,{nickname:t.nick},n);await(null==s?void 0:s.queueMessage(t));const i={stanza:e,attrs:t,chatbox:s};Cl.trigger("message",i)}jl.plugins.add("converse-chat",{dependencies:["converse-chatboxes","converse-disco"],initialize(){Cl.settings.extend({allow_message_corrections:"all",allow_message_retraction:"all",allow_message_styling:!0,auto_join_private_chats:[],clear_messages_on_reconnection:!1,filter_by_resource:!1,prune_messages_above:void 0,pruning_behavior:"unscrolled",send_chat_markers:["received","displayed","acknowledged"],send_chat_state_notifications:!0}),va.Message=gd.extend(Nd),va.Messages=tc.extend({model:va.Message,comparator:"time"}),Object.assign(va,{ChatBox:Td,handleMessageStanza:Pd}),Object.assign(Cl,Od),va.router.route("converse/chat?jid=:jid",Rd),Cl.listen.on("chatBoxesFetched",Ld),Cl.listen.on("presencesInitialized",zd),Cl.listen.on("clearSession",Dd)}});const{Strophe:Fd}=jl.env,Ud=Zo.extend({idAttribute:"jid",initialize(e,t){this.waitUntilFeaturesDiscovered=ji(),this.dataforms=new tc;let n=`converse.dataforms-${this.get("jid")}`;this.dataforms.browserStorage=va.createStore(n,"session"),this.features=new tc,n=`converse.features-${this.get("jid")}`,this.features.browserStorage=va.createStore(n,"session"),this.listenTo(this.features,"add",this.onFeatureAdded),this.fields=new tc,n=`converse.fields-${this.get("jid")}`,this.fields.browserStorage=va.createStore(n,"session"),this.listenTo(this.fields,"add",this.onFieldAdded),this.identities=new tc,n=`converse.identities-${this.get("jid")}`,this.identities.browserStorage=va.createStore(n,"session"),this.fetchFeatures(t),this.items=new va.DiscoEntities,n=`converse.disco-items-${this.get("jid")}`,this.items.browserStorage=va.createStore(n,"session"),this.items.fetch()},async getIdentity(e,t){return await this.waitUntilFeaturesDiscovered,this.identities.findWhere({category:e,type:t})},async hasFeature(e){if(await this.waitUntilFeaturesDiscovered,this.features.findWhere({var:e}))return this},onFeatureAdded(e){e.entity=this,Cl.trigger("serviceDiscovered",e)},onFieldAdded(e){e.entity=this,Cl.trigger("discoExtensionFieldDiscovered",e)},async fetchFeatures(e){if(e.ignore_cache)this.queryInfo();else{const e=this.features.browserStorage.name,t=await this.features.browserStorage.store.getItem(e);t&&0===t.length||null===t?this.queryInfo():(this.features.fetch({add:!0,success:()=>{this.waitUntilFeaturesDiscovered.resolve(this),this.trigger("featuresDiscovered")}}),this.identities.fetch({add:!0}))}},async queryInfo(){let e;try{e=await Cl.disco.info(this.get("jid"),null)}catch(e){return null===e?M.error(`Timeout for disco#info query for ${this.get("jid")}`):M.error(e),void this.waitUntilFeaturesDiscovered.resolve(this)}this.onInfo(e)},onDiscoItems(e){Mo()(`query[xmlns="${Fd.NS.DISCO_ITEMS}"] item`,e).forEach((e=>{if(e.getAttribute("node"))return;const t=e.getAttribute("jid");if(void 0===this.items.get(t)){const e=va.disco_entities.get(t);e?this.items.add(e):this.items.create({jid:t})}}))},async queryForItems(){if(0===this.identities.where({category:"server"}).length)return;const e=await Cl.disco.items(this.get("jid"));this.onDiscoItems(e)},onInfo(e){Array.from(e.querySelectorAll("identity")).forEach((e=>{this.identities.create({category:e.getAttribute("category"),type:e.getAttribute("type"),name:e.getAttribute("name")})})),Mo()(`x[type="result"][xmlns="${Fd.NS.XFORM}"]`,e).forEach((e=>{const t={};Mo()("field",e).forEach((e=>{var n;t[e.getAttribute("var")]={value:null===(n=e.querySelector("value"))||void 0===n?void 0:n.textContent,type:e.getAttribute("type")}})),this.dataforms.create(t)})),e.querySelector(`feature[var="${Fd.NS.DISCO_ITEMS}"]`)&&this.queryForItems(),Array.from(e.querySelectorAll("feature")).forEach((t=>{this.features.create({var:t.getAttribute("var"),from:e.getAttribute("from")})})),Mo()('x[type="result"][xmlns="jabber:x:data"] field',e).forEach((t=>{var n;this.fields.create({var:t.getAttribute("var"),value:null===(n=t.querySelector("value"))||void 0===n?void 0:n.textContent,from:e.getAttribute("from")})})),this.waitUntilFeaturesDiscovered.resolve(this),this.trigger("featuresDiscovered")}}),Bd=tc.extend({model:Ud,fetchEntities(){return new Promise(((e,t)=>{this.fetch({add:!0,success:e,error(e,n){M.error(n),t(new Error("Could not fetch disco entities"))}})}))}}),{Strophe:qd,$iq:Hd}=jl.env;async function Gd(){Cl.disco.own.identities.add("client","web","Converse"),Cl.disco.own.features.add(qd.NS.CHATSTATES),Cl.disco.own.features.add(qd.NS.DISCO_INFO),Cl.disco.own.features.add(qd.NS.ROSTERX),Cl.settings.get("message_carbons")&&Cl.disco.own.features.add(qd.NS.CARBONS),Cl.trigger("addClientFeatures"),va.connection.addHandler((e=>function(e){const t=e.getElementsByTagName("query")[0].getAttribute("node"),n={xmlns:qd.NS.DISCO_INFO};t&&(n.node=t);const s=Hd({type:"result",id:e.getAttribute("id")}),i=e.getAttribute("from");return null!==i&&s.attrs({to:i}),s.c("query",n),va.disco._identities.forEach((e=>{const t={category:e.category,type:e.type};e.name&&(t.name=e.name),e.lang&&(t["xml:lang"]=e.lang),s.c("identity",t).up()})),va.disco._features.forEach((e=>s.c("feature",{var:e}).up())),Cl.send(s.tree()),!0}(e)),qd.NS.DISCO_INFO,"iq","get",null,null),va.disco_entities=new va.DiscoEntities;const e=`converse.disco-entities-${va.bare_jid}`;va.disco_entities.browserStorage=va.createStore(e,"session");const t=await va.disco_entities.fetchEntities();0!==t.length&&t.get(va.domain)||va.disco_entities.create({jid:va.domain}),Cl.trigger("discoInitialized")}function Wd(){if(!va.stream_features){const e=`converse.stream-features-${qd.getBareJidFromJid(va.jid)}`;Cl.promises.add("streamFeaturesAdded"),va.stream_features=new tc,va.stream_features.browserStorage=va.createStore(e,"session")}}function Vd(){Cl.trigger("streamFeaturesAdded")}function Jd(){Wd(),Array.from(va.connection.features.childNodes).forEach((e=>{va.stream_features.create({name:e.nodeName,xmlns:e.getAttribute("xmlns")})})),Vd()}function Kd(){var e,t,n,s,i;null===(e=va.disco_entities)||void 0===e||e.forEach((e=>e.features.clearStore())),null===(t=va.disco_entities)||void 0===t||t.forEach((e=>e.identities.clearStore())),null===(n=va.disco_entities)||void 0===n||n.forEach((e=>e.dataforms.clearStore())),null===(s=va.disco_entities)||void 0===s||s.forEach((e=>e.fields.clearStore())),null===(i=va.disco_entities)||void 0===i||i.clearStore(),delete va.disco_entities}const{Strophe:Yd,$iq:Qd}=jl.env,Xd={disco:{stream:{async getFeature(e,t){if(await Cl.waitUntil("streamFeaturesAdded"),!e||!t)throw new Error("name and xmlns need to be provided when calling disco.stream.getFeature");if(void 0!==va.stream_features||Cl.connection.connected())return va.stream_features.findWhere({name:e,xmlns:t});{const n=`Tried to get feature ${e} ${t} but _converse.stream_features has been torn down`;M.warn(n)}}},own:{identities:{add(e,t,n,s){for(var i=0;iva.disco._identities},features:{add(e){for(var t=0;tva.disco._features}},info(e,t){const n={xmlns:Yd.NS.DISCO_INFO};t&&(n.node=t);const s=Qd({from:va.connection.jid,to:e,type:"get"}).c("query",n);return Cl.sendIQ(s)},items(e,t){const n={xmlns:Yd.NS.DISCO_ITEMS};return t&&(n.node=t),Cl.sendIQ(Qd({from:va.connection.jid,to:e,type:"get"}).c("query",n))},entities:{async get(e,t=!1){if(await Cl.waitUntil("discoInitialized"),!e)return va.disco_entities;if(void 0===va.disco_entities&&!Cl.connection.connected()){const t=`Tried to look up entity ${e} but _converse.disco_entities has been torn down`;return void M.warn(t)}const n=va.disco_entities.get(e);return n||!t?n:Cl.disco.entities.create(e)},create:(e,t)=>va.disco_entities.create({jid:e},t)},features:{async get(e,t){if(!t)throw new TypeError("You need to provide an entity JID");await Cl.waitUntil("discoInitialized");let n=await Cl.disco.entities.get(t,!0);if(void 0===va.disco_entities&&!Cl.connection.connected()){const n=`Tried to get feature ${e} for ${t} but _converse.disco_entities has been torn down`;return void M.warn(n)}n=await n.waitUntilFeaturesDiscovered;const s=[...n.items.map((t=>t.hasFeature(e))),n.hasFeature(e)];return(await Promise.all(s)).filter(pe)}},supports:async(e,t)=>(await Cl.disco.features.get(e,t)||[]).length>0,async refresh(e){if(!e)throw new TypeError("api.disco.refresh: You need to provide an entity JID");await Cl.waitUntil("discoInitialized");let t=await Cl.disco.entities.get(e);return t?(t.features.reset(),t.fields.reset(),t.identities.reset(),t.waitUntilFeaturesDiscovered.isPending||(t.waitUntilFeaturesDiscovered=ji()),t.queryInfo()):t=await Cl.disco.entities.create(e,{ignore_cache:!0}),t.waitUntilFeaturesDiscovered},refreshFeatures:e=>Cl.refresh(e),async getFeatures(e){if(!e)throw new TypeError("api.disco.getFeatures: You need to provide an entity JID");await Cl.waitUntil("discoInitialized");let t=await Cl.disco.entities.get(e,!0);return t=await t.waitUntilFeaturesDiscovered,t.features},async getFields(e){if(!e)throw new TypeError("api.disco.getFields: You need to provide an entity JID");await Cl.waitUntil("discoInitialized");let t=await Cl.disco.entities.get(e,!0);return t=await t.waitUntilFeaturesDiscovered,t.fields},async getIdentity(e,t,n){const s=await Cl.disco.entities.get(n,!0);if(void 0!==s||Cl.connection.connected())return s.getIdentity(e,t);{const t=`Tried to look up category ${e} for ${n} but _converse.disco_entities has been torn down`;M.warn(t)}}}},{Strophe:Zd}=jl.env;jl.plugins.add("converse-disco",{initialize(){Object.assign(Cl,Xd),Cl.promises.add("discoInitialized"),Cl.promises.add("streamFeaturesAdded"),va.DiscoEntity=Ud,va.DiscoEntities=Bd,va.disco={_identities:[],_features:[]},Cl.listen.on("userSessionInitialized",(async()=>{Wd(),va.connfeedback.get("connection_status")===Zd.Status.ATTACHED&&(await new Promise(((e,t)=>va.stream_features.fetch({success:e,error:t}))),Vd())})),Cl.listen.on("beforeResourceBinding",Jd),Cl.listen.on("reconnected",Gd),Cl.listen.on("connected",Gd),Cl.listen.on("beforeTearDown",(async()=>{Cl.promises.add("streamFeaturesAdded"),va.stream_features&&(await va.stream_features.clearStore(),delete va.stream_features)})),Cl.listen.on("will-reconnect",Kd),Cl.listen.on("clearSession",Kd)}});const eu=new RegExp("]*>.*?
    |]*>.*?|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|((\\s|^)(\\*\\\\0\\/\\*|\\*\\\\O\\/\\*|\\-___\\-|\\:'\\-\\)|'\\:\\-\\)|'\\:\\-D|\\>\\:\\-\\)|>\\:\\-\\)|'\\:\\-\\(|\\>\\:\\-\\(|>\\:\\-\\(|\\:'\\-\\(|O\\:\\-\\)|0\\:\\-3|0\\:\\-\\)|0;\\^\\)|O;\\-\\)|0;\\-\\)|O\\:\\-3|\\-__\\-|\\:\\-Þ|\\:\\-Þ|\\<\\/3|<\\/3|\\:'\\)|\\:\\-D|'\\:\\)|'\\=\\)|'\\:D|'\\=D|\\>\\:\\)|>\\:\\)|\\>;\\)|>;\\)|\\>\\=\\)|>\\=\\)|;\\-\\)|\\*\\-\\)|;\\-\\]|;\\^\\)|'\\:\\(|'\\=\\(|\\:\\-\\*|\\:\\^\\*|\\>\\:P|>\\:P|X\\-P|\\>\\:\\[|>\\:\\[|\\:\\-\\(|\\:\\-\\[|\\>\\:\\(|>\\:\\(|\\:'\\(|;\\-\\(|\\>\\.\\<|>\\.<|#\\-\\)|%\\-\\)|X\\-\\)|\\\\0\\/|\\\\O\\/|0\\:3|0\\:\\)|O\\:\\)|O\\=\\)|O\\:3|B\\-\\)|8\\-\\)|B\\-D|8\\-D|\\-_\\-|\\>\\:\\\\|>\\:\\\\|\\>\\:\\/|>\\:\\/|\\:\\-\\/|\\:\\-\\.|\\:\\-P|\\:Þ|\\:Þ|\\:\\-b|\\:\\-O|O_O|\\>\\:O|>\\:O|\\:\\-X|\\:\\-#|\\:\\-\\)|\\(y\\)|\\<3|<3|\\:D|\\=D|;\\)|\\*\\)|;\\]|;D|\\:\\*|\\=\\*|\\:\\(|\\:\\[|\\=\\(|\\:@|;\\(|D\\:|\\:\\$|\\=\\$|#\\)|%\\)|X\\)|B\\)|8\\)|\\:\\/|\\:\\\\|\\=\\/|\\=\\\\|\\:L|\\=L|\\:P|\\=P|\\:b|\\:O|\\:X|\\:#|\\=X|\\=#|\\:\\)|\\=\\]|\\=\\)|\\:\\])(?=\\s|$|[!,.?]))","gi"),tu=/(?:\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5\udeeb\udeec\udef4-\udefa\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd71\udd73-\udd76\udd7a-\udda2\udda5-\uddaa\uddae-\uddb4\uddb7\uddba\uddbc-\uddca\uddd0\uddde-\uddff\ude70-\ude73\ude78-\ude7a\ude80-\ude82\ude90-\ude95]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,nu=jl.env.utils;jl.emojis={initialized:!1,initialized_promise:ji()};const su={"*\\0/*":"1f646","*\\O/*":"1f646","-___-":"1f611",":'-)":"1f602","':-)":"1f605","':-D":"1f605",">:-)":"1f606","':-(":"1f613",">:-(":"1f620",":'-(":"1f622","O:-)":"1f607","0:-3":"1f607","0:-)":"1f607","0;^)":"1f607","O;-)":"1f607","0;-)":"1f607","O:-3":"1f607","-__-":"1f611",":-Þ":"1f61b",":)":"1f606",">;)":"1f606",">=)":"1f606",";-)":"1f609","*-)":"1f609",";-]":"1f609",";^)":"1f609","':(":"1f613","'=(":"1f613",":-*":"1f618",":^*":"1f618",">:P":"1f61c","X-P":"1f61c",">:[":"1f61e",":-(":"1f61e",":-[":"1f61e",">:(":"1f620",":'(":"1f622",";-(":"1f622",">.<":"1f623","#-)":"1f635","%-)":"1f635","X-)":"1f635","\\0/":"1f646","\\O/":"1f646","0:3":"1f607","0:)":"1f607","O:)":"1f607","O=)":"1f607","O:3":"1f607","B-)":"1f60e","8-)":"1f60e","B-D":"1f60e","8-D":"1f60e","-_-":"1f611",">:\\":"1f615",">:/":"1f615",":-/":"1f615",":-.":"1f615",":-P":"1f61b",":Þ":"1f61b",":-b":"1f61b",":-O":"1f62e",O_O:"1f62e",">:O":"1f62e",":-X":"1f636",":-#":"1f636",":-)":"1f642","(y)":"1f44d","<3":"2764",":D":"1f603","=D":"1f603",";)":"1f609","*)":"1f609",";]":"1f609",";D":"1f609",":*":"1f618","=*":"1f618",":(":"1f61e",":[":"1f61e","=(":"1f61e",":@":"1f620",";(":"1f622","D:":"1f628",":$":"1f633","=$":"1f633","#)":"1f635","%)":"1f635","X)":"1f635","B)":"1f60e","8)":"1f60e",":/":"1f615",":\\":"1f615","=/":"1f615","=\\":"1f615",":L":"1f615","=L":"1f615",":P":"1f61b","=P":"1f61b",":b":"1f61b",":O":"1f62e",":X":"1f636",":#":"1f636","=X":"1f636","=#":"1f636",":)":"1f642","=]":"1f642","=)":"1f642",":]":"1f642"};function iu(e){if(e.indexOf("-")>-1){const t=[],n=e.split("-");for(let e=0;e=65536&&s<=1114111){const e=Math.floor((s-65536)/1024)+55296,t=(s-65536)%1024+56320;s=String.fromCharCode(e)+String.fromCharCode(t)}else s=String.fromCharCode(s);t.push(s)}return t.join("")}return function(e){let t="string"==typeof e?parseInt(e,16):e;return t<65536?String.fromCharCode(t):(t-=65536,String.fromCharCode(55296+(t>>10),56320+(1023&t)))}(e)}function ru(e){return e.replace(eu,((e,t,n,s)=>void 0!==s&&""!==s&&nu.unescapeHTML(s)in su?(s=nu.unescapeHTML(s),n+iu(su[s].toUpperCase())):e))}function ou(e,t={unicode_only:!1,add_title_wrapper:!1}){const n=e.emoji,s=e.shortname;if(n){if(t.unicode_only)return n;if(Cl.settings.get("use_system_emojis"))return t.add_title_wrapper&&s?Qc`${n}`:n;{const t=Cl.settings.get("emoji_image_path");return Qc`{var e,t,n,s,i={4567:(e,t,n)=>{"use strict";const s=n(4095),i=n(257);e.exports={atob:s,btoa:i}},4095:e=>{"use strict";function t(e){const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(e);return t<0?void 0:t}e.exports=function(e){if((e=(e=`${e}`).replace(/[ \t\n\f\r]/g,"")).length%4==0&&(e=e.replace(/==?$/,"")),e.length%4==1||/[^+/0-9A-Za-z]/.test(e))return null;let n="",s=0,i=0;for(let r=0;r>16),n+=String.fromCharCode((65280&s)>>8),n+=String.fromCharCode(255&s),s=i=0);return 12===i?(s>>=4,n+=String.fromCharCode(s)):18===i&&(s>>=2,n+=String.fromCharCode((65280&s)>>8),n+=String.fromCharCode(255&s)),n}},257:e=>{"use strict";function t(e){if(e>=0&&e<64)return"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e]}e.exports=function(e){let n;for(e=`${e}`,n=0;n255)return null;let s="";for(n=0;n>2,i[1]=(3&e.charCodeAt(n))<<4,e.length>n+1&&(i[1]|=e.charCodeAt(n+1)>>4,i[2]=(15&e.charCodeAt(n+1))<<2),e.length>n+2&&(i[2]|=e.charCodeAt(n+2)>>6,i[3]=63&e.charCodeAt(n+2));for(let e=0;e{e.exports={default:n(1966),__esModule:!0}},5460:(e,t,n)=>{e.exports={default:n(4064),__esModule:!0}},9251:(e,t,n)=>{e.exports={default:n(9791),__esModule:!0}},1683:(e,t,n)=>{"use strict";t.__esModule=!0;var s,i=(s=n(9251))&&s.__esModule?s:{default:s};t.default=function(e){return function(){var t=e.apply(this,arguments);return new i.default((function(e,n){return function s(r,o){try{var a=t[r](o),c=a.value}catch(e){return void n(e)}if(!a.done)return i.default.resolve(c).then((function(e){s("next",e)}),(function(e){s("throw",e)}));e(c)}("next")}))}}},8339:(e,t,n)=>{"use strict";t.__esModule=!0;var s,i=(s=n(6561))&&s.__esModule?s:{default:s};t.default=function(e,t,n){return t in e?(0,i.default)(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},342:(e,t,n)=>{var s=function(){return this}()||Function("return this")(),i=s.regeneratorRuntime&&Object.getOwnPropertyNames(s).indexOf("regeneratorRuntime")>=0,r=i&&s.regeneratorRuntime;if(s.regeneratorRuntime=void 0,e.exports=n(5987),i)s.regeneratorRuntime=r;else try{delete s.regeneratorRuntime}catch(e){s.regeneratorRuntime=void 0}},5987:e=>{!function(t){"use strict";var n,s=Object.prototype,i=s.hasOwnProperty,r="function"==typeof Symbol?Symbol:{},o=r.iterator||"@@iterator",a=r.asyncIterator||"@@asyncIterator",c=r.toStringTag||"@@toStringTag",l=t.regeneratorRuntime;if(l)e.exports=l;else{(l=t.regeneratorRuntime=e.exports).wrap=b;var d="suspendedStart",u="suspendedYield",h="executing",f="completed",m={},g={};g[o]=function(){return this};var p=Object.getPrototypeOf,v=p&&p(p(N([])));v&&v!==s&&i.call(v,o)&&(g=v);var y=x.prototype=w.prototype=Object.create(g);S.prototype=y.constructor=x,x.constructor=S,x[c]=S.displayName="GeneratorFunction",l.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===S||"GeneratorFunction"===(t.displayName||t.name))},l.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,x):(e.__proto__=x,c in e||(e[c]="GeneratorFunction")),e.prototype=Object.create(y),e},l.awrap=function(e){return{__await:e}},E(A.prototype),A.prototype[a]=function(){return this},l.AsyncIterator=A,l.async=function(e,t,n,s){var i=new A(b(e,t,n,s));return l.isGeneratorFunction(t)?i:i.next().then((function(e){return e.done?e.value:i.next()}))},E(y),y[c]="Generator",y[o]=function(){return this},y.toString=function(){return"[object Generator]"},l.keys=function(e){var t=[];for(var n in e)t.push(n);return t.reverse(),function n(){for(;t.length;){var s=t.pop();if(s in e)return n.value=s,n.done=!1,n}return n.done=!0,n}},l.values=N,j.prototype={constructor:j,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=n,this.done=!1,this.delegate=null,this.method="next",this.arg=n,this.tryEntries.forEach(k),!e)for(var t in this)"t"===t.charAt(0)&&i.call(this,t)&&!isNaN(+t.slice(1))&&(this[t]=n)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var t=this;function s(s,i){return a.type="throw",a.arg=e,t.next=s,i&&(t.method="next",t.arg=n),!!i}for(var r=this.tryEntries.length-1;r>=0;--r){var o=this.tryEntries[r],a=o.completion;if("root"===o.tryLoc)return s("end");if(o.tryLoc<=this.prev){var c=i.call(o,"catchLoc"),l=i.call(o,"finallyLoc");if(c&&l){if(this.prev=0;--n){var s=this.tryEntries[n];if(s.tryLoc<=this.prev&&i.call(s,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),k(n),m}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var s=n.completion;if("throw"===s.type){var i=s.arg;k(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,s){return this.delegate={iterator:N(e),resultName:t,nextLoc:s},"next"===this.method&&(this.arg=n),m}}}function b(e,t,n,s){var i=t&&t.prototype instanceof w?t:w,r=Object.create(i.prototype),o=new j(s||[]);return r._invoke=function(e,t,n){var s=d;return function(i,r){if(s===h)throw new Error("Generator is already running");if(s===f){if("throw"===i)throw r;return O()}for(n.method=i,n.arg=r;;){var o=n.delegate;if(o){var a=C(o,n);if(a){if(a===m)continue;return a}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(s===d)throw s=f,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);s=h;var c=_(e,t,n);if("normal"===c.type){if(s=n.done?f:u,c.arg===m)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(s=f,n.method="throw",n.arg=c.arg)}}}(e,n,o),r}function _(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}function w(){}function S(){}function x(){}function E(e){["next","throw","return"].forEach((function(t){e[t]=function(e){return this._invoke(t,e)}}))}function A(e){function t(n,s,r,o){var a=_(e[n],e,s);if("throw"!==a.type){var c=a.arg,l=c.value;return l&&"object"==typeof l&&i.call(l,"__await")?Promise.resolve(l.__await).then((function(e){t("next",e,r,o)}),(function(e){t("throw",e,r,o)})):Promise.resolve(l).then((function(e){c.value=e,r(c)}),o)}o(a.arg)}var n;this._invoke=function(e,s){function i(){return new Promise((function(n,i){t(e,s,n,i)}))}return n=n?n.then(i,i):i()}}function C(e,t){var s=e.iterator[t.method];if(s===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=n,C(e,t),"throw"===t.method))return m;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return m}var i=_(s,e.iterator,t.arg);if("throw"===i.type)return t.method="throw",t.arg=i.arg,t.delegate=null,m;var r=i.arg;return r?r.done?(t[e.resultName]=r.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=n),t.delegate=null,m):r:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,m)}function T(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function k(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function j(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(T,this),this.reset(!0)}function N(e){if(e){var t=e[o];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var s=-1,r=function t(){for(;++s{e.exports=n(342)},1505:function(e,t,n){var s,i;void 0===(i="function"==typeof(s=function(){"use strict";var e=void 0!==n.g?n.g:this||window,t=document,s=t.documentElement,i=e.BSN={},r=i.supports=[],o="data-toggle",a="data-dismiss",c="Alert",l="Button",d="Collapse",u="Dropdown",h="Modal",f="Popover",m="Tab",g="data-backdrop",p="data-target",v="data-title",y="aria-expanded",b="aria-hidden",_="aria-selected",w="click",S="focus",x="hover",E="keydown",A="keyup",C="resize",T="onmouseleave"in t?["mouseenter","mouseleave"]:["mouseover","mouseout"],k="show",j="shown",N="hide",O="hidden",$="change",I="getAttribute",M="Transition",R="Duration",D="Webkit",L="tabindex",z="active",P="show",F="collapsing",U="left",B="right",q="top",H="bottom",G=/\b(top|bottom|left|right)+/,W=0,V="fixed-top",J="fixed-bottom",Q=D+M in s.style||M.toLowerCase()in s.style,Z=D+M in s.style?D.toLowerCase()+M+"End":M.toLowerCase()+"end",K=D+R in s.style?D.toLowerCase()+M+R:M.toLowerCase()+R,Y=function(e){e.focus?e.focus():e.setActive()},X=function(e,t){e.classList.add(t)},ee=function(e,t){e.classList.remove(t)},te=function(e,t){return e.classList.contains(t)},ne=function(e,t){return[].slice.call(e.getElementsByClassName(t))},se=function(e,n){return"object"==typeof e?e:(n||t).querySelector(e)},ie=function(e,n){var s=n.charAt(0),i=n.substr(1);if("."===s){for(;e&&e!==t;e=e.parentNode)if(null!==se(n,e.parentNode)&&te(e,i))return e}else if("#"===s)for(;e&&e!==t;e=e.parentNode)if(e.id===i)return e;return!1},re=function(e,t,n,s){s=s||!1,e.addEventListener(t,n,s)},oe=function(e,t,n,s){s=s||!1,e.removeEventListener(t,n,s)},ae=function(e,t,n,s){re(e,t,(function i(r){n(r),oe(e,t,i,s)}),s)},ce=!!function(){var t=!1;try{var n=Object.defineProperty({},"passive",{get:function(){t=!0}});ae(e,"testPassive",null,n)}catch(e){}return t}()&&{passive:!0},le=function(t){var n=Q?e.getComputedStyle(t)[K]:0;return"number"!=typeof(n=parseFloat(n))||isNaN(n)?0:1e3*n},de=function(e,t){var n=0;le(e)?ae(e,Z,(function(e){!n&&t(e),n=1})):setTimeout((function(){!n&&t(),n=1}),17)},ue=function(e,t,n){var s=new CustomEvent(e+".bs."+t);s.relatedTarget=n,this.dispatchEvent(s)},he=function(n,i,r,o){var a,c,l,d,u,h,f=i.offsetWidth,m=i.offsetHeight,g=s.clientWidth||t.body.clientWidth,p=s.clientHeight||t.body.clientHeight,v=n.getBoundingClientRect(),y=o===t.body?{y:e.pageYOffset||s.scrollTop,x:e.pageXOffset||s.scrollLeft}:{x:o.offsetLeft+o.scrollLeft,y:o.offsetTop+o.scrollTop},b=v.right-v.left,_=v.bottom-v.top,w=te(i,"popover"),S=se(".arrow",i),x=v.top+_/2-m/2<0,E=v.left+b/2-f/2<0,A=v.left+f/2+b/2>=g,C=v.top+m/2+_/2>=p,T=v.top-m<0,k=v.left-f<0,j=v.top+m+_>=p,N=v.left+f+b>=g;r=(r=(r=(r=(r=(r===U||r===B)&&k&&N?q:r)===q&&T?H:r)===H&&j?q:r)===U&&k?B:r)===B&&N?U:r,-1===i.className.indexOf(r)&&(i.className=i.className.replace(G,r)),u=S.offsetWidth,h=S.offsetHeight,r===U||r===B?(c=r===U?v.left+y.x-f-(w?u:0):v.left+y.x+b,x?(a=v.top+y.y,l=_/2-u):C?(a=v.top+y.y-m+_,l=m-_/2-u):(a=v.top+y.y-m/2+_/2,l=m/2-(w?.9*h:h/2))):r!==q&&r!==H||(a=r===q?v.top+y.y-m-(w?h:0):v.top+y.y+_,E?(c=0,d=v.left+b/2-u):A?(c=g-1.01*f,d=f-(g-v.left)+b/2-u/2):(c=v.left+y.x-f/2+b/2,d=f/2-(w?u:u/2))),i.style.top=a+"px",i.style.left=c+"px",l&&(S.style.top=l+"px"),d&&(S.style.left=d+"px")};i.version="2.0.27";var fe=function(e){e=se(e);var t=this,n="alert",s=ie(e,".alert"),i=function(n){s=ie(n.target,".alert"),(e=se('[data-dismiss="alert"]',s))&&s&&(e===n.target||e.contains(n.target))&&t.close()},r=function(){ue.call(s,"closed",n),oe(e,w,i),s.parentNode.removeChild(s)};this.close=function(){s&&e&&te(s,P)&&(ue.call(s,"close",n),ee(s,P),s&&(te(s,"fade")?de(s,r):r()))},c in e||re(e,w,i),e.Alert=t};r.push([c,fe,'[data-dismiss="alert"]']);var me=function(e){e=se(e);var n=!1,s="button",i="checked",r="LABEL",o="INPUT",a=function(t){var a=t.target.tagName===r?t.target:t.target.parentNode.tagName===r?t.target.parentNode:null;if(a){var c=ne(a.parentNode,"btn"),l=a.getElementsByTagName(o)[0];if(l){if("checkbox"===l.type&&(l.checked?(ee(a,z),l.getAttribute(i),l.removeAttribute(i),l.checked=!1):(X(a,z),l.getAttribute(i),l.setAttribute(i,i),l.checked=!0),n||(n=!0,ue.call(l,$,s),ue.call(e,$,s))),"radio"===l.type&&!n&&(!l.checked||0===t.screenX&&0==t.screenY)){X(a,z),X(a,S),l.setAttribute(i,i),l.checked=!0,ue.call(l,$,s),ue.call(e,$,s),n=!0;for(var d=0,u=c.length;d1?o-1:0:40===i&&o×',y=se(s.container),b=se(l),_=ie(n,".modal"),S=ie(n,".fixed-top"),E=ie(n,".fixed-bottom");this.template=s.template?s.template:null,this.trigger=s.trigger?s.trigger:i||x,this.animation=s.animation&&s.animation!==m?s.animation:r||m,this.placement=s.placement?s.placement:o||q,this.delay=parseInt(s.delay||c)||200,this.dismissible=!(!s.dismissible&&"true"!==a),this.container=y||b||S||E||_||t.body;var A=this,$=s.title||n.getAttribute(v)||null,I=s.content||n.getAttribute(g)||null;if(I||this.template){var M=null,R=0,D=this.placement,L=function(e){null!==M&&e.target===se(".close",M)&&A.hide()},z=function(s){w!=A.trigger&&"focus"!=A.trigger||!A.dismissible&&s(n,"blur",A.hide),A.dismissible&&s(t,w,L),s(e,C,A.hide,ce)},F=function(){z(re),ue.call(n,j,d)},U=function(){z(oe),A.container.removeChild(M),R=null,M=null,ue.call(n,O,d)};this.toggle=function(){null===M?A.show():A.hide()},this.show=function(){clearTimeout(R),R=setTimeout((function(){null===M&&(D=A.placement,function(){$=s.title||n.getAttribute(v),I=(I=s.content||n.getAttribute(g))?I.trim():null,M=t.createElement(h);var e=t.createElement(h);if(e.setAttribute(u,"arrow"),M.appendChild(e),null!==I&&null===A.template){if(M.setAttribute("role","tooltip"),null!==$){var i=t.createElement("h3");i.setAttribute(u,"popover-header"),i.innerHTML=A.dismissible?$+p:$,M.appendChild(i)}var r=t.createElement(h);r.setAttribute(u,"popover-body"),r.innerHTML=A.dismissible&&null===$?I+p:I,M.appendChild(r)}else{var o=t.createElement(h);A.template=A.template.trim(),o.innerHTML=A.template,M.innerHTML=o.firstChild.innerHTML}A.container.appendChild(M),M.style.display="block",M.setAttribute(u,"popover bs-popover-"+D+" "+A.animation)}(),he(n,M,D,A.container),!te(M,P)&&X(M,P),ue.call(n,k,d),A.animation?de(M,F):F())}),20)},this.hide=function(){clearTimeout(R),R=setTimeout((function(){M&&null!==M&&te(M,P)&&(ue.call(n,N,d),ee(M,P),A.animation?de(M,U):U())}),A.delay)},f in n||(A.trigger===x?(re(n,T[0],A.show),A.dismissible||re(n,T[1],A.hide)):w!=A.trigger&&"focus"!=A.trigger||re(n,A.trigger,A.toggle)),n.Popover=A}};r.push([f,ye,'[data-toggle="popover"]']);var be=function(e,t){var n=(e=se(e)).getAttribute("data-height"),s="tab";t=t||{},this.height=!!Q&&(t.height||"true"===n);var i,r,o,a,c,l,d,u=this,h=ie(e,".nav"),f=!1,g=h&&se(".dropdown-toggle",h),p=function(){f.style.height="",ee(f,F),h.isAnimating=!1},v=function(){f?l?p():setTimeout((function(){f.style.height=d+"px",f.offsetWidth,de(f,p)}),50):h.isAnimating=!1,ue.call(i,j,s,r)},y=function(){f&&(o.style.float=U,a.style.float=U,c=o.scrollHeight),X(a,z),ue.call(i,k,s,r),ee(o,z),ue.call(r,O,s,i),f&&(d=a.scrollHeight,l=d===c,X(f,F),f.style.height=c+"px",f.offsetHeight,o.style.float="",a.style.float=""),te(a,"fade")?setTimeout((function(){X(a,P),de(a,v)}),20):v()};if(h){h.isAnimating=!1;var b=function(){var e,t=ne(h,z);return 1!==t.length||te(t[0].parentNode,"dropdown")?t.length>1&&(e=t[t.length-1]):e=t[0],e},S=function(){return se(b().getAttribute("href"))};this.show=function(){a=se((i=i||e).getAttribute("href")),r=b(),o=S(),h.isAnimating=!0,ee(r,z),r.setAttribute(_,"false"),X(i,z),i.setAttribute(_,"true"),g&&(te(e.parentNode,"dropdown-menu")?te(g,z)||X(g,z):te(g,z)&&ee(g,z)),ue.call(r,N,s,i),te(o,"fade")?(ee(o,P),de(o,y)):y()},m in e||re(e,w,(function(e){e.preventDefault(),i=e.currentTarget,!h.isAnimating&&!te(i,z)&&u.show()})),u.height&&(f=S().parentNode),e.Tab=u}};r.push([m,be,'[data-toggle="tab"]']);var _e=function(e,t){for(var n=0,s=t.length;n{window,e.exports=function(e){var t={};function n(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,s){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:s})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.loadImageElement=function(e,t){return new Promise((function(n,s){e.addEventListener("load",(function(){n(e)}),!1),e.addEventListener("error",(function(e){s(e)}),!1),e.src=t}))},t.resize=function(e,t,n,s){if(!n&&!s)return{currentWidth:e,currentHeight:t};var i=e/t,r=void 0,o=void 0;return i>n/s?o=(r=Math.min(e,n))/i:r=(o=Math.min(t,s))*i,{width:r,height:o}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.base64ToFile=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"image/jpeg",n=window.atob(e),s=[],i=0;i8)return r.drawImage(e,0,0,i.width,i.height),i;switch(s>4&&(i.width=n,i.height=t),s){case 2:r.translate(t,0),r.scale(-1,1);break;case 3:r.translate(t,n),r.rotate(Math.PI);break;case 4:r.translate(0,n),r.scale(1,-1);break;case 5:r.rotate(.5*Math.PI),r.scale(1,-1);break;case 6:r.rotate(.5*Math.PI),r.translate(0,-n);break;case 7:r.rotate(.5*Math.PI),r.translate(t,-n),r.scale(-1,1);break;case 8:r.rotate(-.5*Math.PI),r.translate(-t,0)}return s>4?r.drawImage(e,0,0,i.height,i.width):r.drawImage(e,0,0,i.width,i.height),i},t.canvasToBlob=function(e,t){return new Promise((function(n,s){e.toBlob((function(e){n(e)}),"image/jpeg",t)}))},t.size=function(e){return{kB:.001*e,MB:1e-6*e}},t.blobToBase64=function(e){return new Promise((function(t,n){var s=new window.FileReader;s.addEventListener("load",(function(e){t(e.target.result)}),!1),s.addEventListener("error",(function(e){n(e)}),!1),s.readAsDataURL(e)}))}},function(e,t,n){e.exports=n(6)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.extractOrientation=function(e){return new Promise((function(t,n){var s=new window.FileReader;s.onload=function(e){var n=new DataView(e.target.result);65496!==n.getUint16(0,!1)&&t(-2);for(var s=n.byteLength,i=2;i=0;--r){var o=this.tryEntries[r],a=o.completion;if("root"===o.tryLoc)return s("end");if(o.tryLoc<=this.prev){var c=i.call(o,"catchLoc"),l=i.call(o,"finallyLoc");if(c&&l){if(this.prev=0;--n){var s=this.tryEntries[n];if(s.tryLoc<=this.prev&&i.call(s,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),j(n),g}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var s=n.completion;if("throw"===s.type){var i=s.arg;j(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,s){return this.delegate={iterator:O(e),resultName:t,nextLoc:s},"next"===this.method&&(this.arg=n),g}}}function _(e,t,n,s){var i=t&&t.prototype instanceof S?t:S,r=Object.create(i.prototype),o=new N(s||[]);return r._invoke=function(e,t,n){var s=u;return function(i,r){if(s===f)throw new Error("Generator is already running");if(s===m){if("throw"===i)throw r;return $()}for(n.method=i,n.arg=r;;){var o=n.delegate;if(o){var a=T(o,n);if(a){if(a===g)continue;return a}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(s===u)throw s=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);s=f;var c=w(e,t,n);if("normal"===c.type){if(s=n.done?m:h,c.arg===g)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(s=m,n.method="throw",n.arg=c.arg)}}}(e,n,o),r}function w(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}function S(){}function x(){}function E(){}function A(e){["next","throw","return"].forEach((function(t){e[t]=function(e){return this._invoke(t,e)}}))}function C(e){var t;this._invoke=function(n,s){function r(){return new Promise((function(t,r){!function t(n,s,r,o){var a=w(e[n],e,s);if("throw"!==a.type){var c=a.arg,l=c.value;return l&&"object"==typeof l&&i.call(l,"__await")?Promise.resolve(l.__await).then((function(e){t("next",e,r,o)}),(function(e){t("throw",e,r,o)})):Promise.resolve(l).then((function(e){c.value=e,r(c)}),o)}o(a.arg)}(n,s,t,r)}))}return t=t?t.then(r,r):r()}}function T(e,t){var s=e.iterator[t.method];if(s===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=n,T(e,t),"throw"===t.method))return g;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return g}var i=w(s,e.iterator,t.arg);if("throw"===i.type)return t.method="throw",t.arg=i.arg,t.delegate=null,g;var r=i.arg;return r?r.done?(t[e.resultName]=r.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=n),t.delegate=null,g):r:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,g)}function k(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function j(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function N(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(k,this),this.reset(!0)}function O(e){if(e){var t=e[o];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var s=-1,r=function t(){for(;++s=0,r=i&&s.regeneratorRuntime;if(s.regeneratorRuntime=void 0,e.exports=n(5),i)s.regeneratorRuntime=r;else try{delete s.regeneratorRuntime}catch(e){s.regeneratorRuntime=void 0}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var s=c(n(2)),i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.setOptions(t)}return i(e,[{key:"setOptions",value:function(e){var t={targetSize:1/0,quality:.75,minQuality:.5,qualityStepSize:.1,maxWidth:1920,maxHeight:1920,resize:!0,throwIfSizeNotReached:!1,autoRotate:!0},n=new Proxy(e,{get:function(e,n){return n in e?e[n]:t[n]}});this.options=n}},{key:"_compressFile",value:function(){var e=l(s.default.mark((function e(t){var n,i;return s.default.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=new a.default(t),(i={}).start=window.performance.now(),i.quality=this.options.quality,i.startType=n.type,e.next=7,n.load();case 7:return e.next=9,this._compressImage(n,i);case 9:return e.abrupt("return",e.sent);case 10:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}()},{key:"_compressImage",value:function(){var e=l(s.default.mark((function e(t,n){var i,a,c,l,d;return s.default.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n.startWidth=t.width,n.startHeight=t.height,i=void 0,a=void 0,this.options.resize?(c=(0,o.resize)(t.width,t.height,this.options.maxWidth,this.options.maxHeight),i=c.width,a=c.height):(i=t.width,a=t.height),n.endWidth=i,n.endHeight=a,l=this.doAutoRotation?void 0:1,d=t.getCanvas(i,a,l),n.iterations=0,n.startSizeMB=r.size(t.size).MB,e.next=12,this._loopCompression(d,t,n);case 12:return n.endSizeMB=r.size(t.size).MB,n.sizeReducedInPercent=(n.startSizeMB-n.endSizeMB)/n.startSizeMB*100,n.end=window.performance.now(),n.elapsedTimeInSeconds=(n.end-n.start)/1e3,n.endType=t.type,e.abrupt("return",{photo:t,info:n});case 18:case"end":return e.stop()}}),e,this)})));return function(t,n){return e.apply(this,arguments)}}()},{key:"_loopCompression",value:function(){var e=l(s.default.mark((function e(t,n,i){var o;return s.default.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return i.iterations++,e.t0=n,e.next=4,r.canvasToBlob(t,i.quality);case 4:if(e.t1=e.sent,e.t0.setData.call(e.t0,e.t1),1==i.iterations&&(n.width=i.endWidth,n.height=i.endHeight),!(r.size(n.size).MB>this.options.targetSize)){e.next=24;break}if(!(i.quality.toFixed(10)-.1{n(7252);var s=n(6356).Object;e.exports=function(e,t,n){return s.defineProperty(e,t,n)}},4064:(e,t,n)=>{n(4304),e.exports=n(6356).Object.keys},9791:(e,t,n)=>{n(5693),n(5758),n(4291),n(9870),n(814),n(955),e.exports=n(6356).Promise},8640:e=>{e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},5678:e=>{e.exports=function(){}},1241:e=>{e.exports=function(e,t,n,s){if(!(e instanceof t)||void 0!==s&&s in e)throw TypeError(n+": incorrect invocation!");return e}},2854:(e,t,n)=>{var s=n(9773);e.exports=function(e){if(!s(e))throw TypeError(e+" is not an object!");return e}},7343:(e,t,n)=>{var s=n(1520),i=n(5836),r=n(9271);e.exports=function(e){return function(t,n,o){var a,c=s(t),l=i(c.length),d=r(o,l);if(e&&n!=n){for(;l>d;)if((a=c[d++])!=a)return!0}else for(;l>d;d++)if((e||d in c)&&c[d]===n)return e||d||0;return!e&&-1}}},2791:(e,t,n)=>{var s=n(103),i=n(3309)("toStringTag"),r="Arguments"==s(function(){return arguments}());e.exports=function(e){var t,n,o;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),i))?n:r?s(t):"Object"==(o=s(t))&&"function"==typeof t.callee?"Arguments":o}},103:e=>{var t={}.toString;e.exports=function(e){return t.call(e).slice(8,-1)}},6356:e=>{var t=e.exports={version:"2.6.12"};"number"==typeof __e&&(__e=t)},2389:(e,t,n)=>{var s=n(8640);e.exports=function(e,t,n){if(s(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,s){return e.call(t,n,s)};case 3:return function(n,s,i){return e.call(t,n,s,i)}}return function(){return e.apply(t,arguments)}}},7009:e=>{e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},6033:(e,t,n)=>{e.exports=!n(2889)((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},3640:(e,t,n)=>{var s=n(9773),i=n(8942).document,r=s(i)&&s(i.createElement);e.exports=function(e){return r?i.createElement(e):{}}},1159:e=>{e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},3948:(e,t,n)=>{var s=n(8942),i=n(6356),r=n(2389),o=n(7270),a=n(9638),c=function(e,t,n){var l,d,u,h=e&c.F,f=e&c.G,m=e&c.S,g=e&c.P,p=e&c.B,v=e&c.W,y=f?i:i[t]||(i[t]={}),b=y.prototype,_=f?s:m?s[t]:(s[t]||{}).prototype;for(l in f&&(n=t),n)(d=!h&&_&&void 0!==_[l])&&a(y,l)||(u=d?_[l]:n[l],y[l]=f&&"function"!=typeof _[l]?n[l]:p&&d?r(u,s):v&&_[l]==u?function(e){var t=function(t,n,s){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,s)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(u):g&&"function"==typeof u?r(Function.call,u):u,g&&((y.virtual||(y.virtual={}))[l]=u,e&c.R&&b&&!b[l]&&o(b,l,u)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},2889:e=>{e.exports=function(e){try{return!!e()}catch(e){return!0}}},5766:(e,t,n)=>{var s=n(2389),i=n(281),r=n(692),o=n(2854),a=n(5836),c=n(4492),l={},d={},u=e.exports=function(e,t,n,u,h){var f,m,g,p,v=h?function(){return e}:c(e),y=s(n,u,t?2:1),b=0;if("function"!=typeof v)throw TypeError(e+" is not iterable!");if(r(v)){for(f=a(e.length);f>b;b++)if((p=t?y(o(m=e[b])[0],m[1]):y(e[b]))===l||p===d)return p}else for(g=v.call(e);!(m=g.next()).done;)if((p=i(g,y,m.value,t))===l||p===d)return p};u.BREAK=l,u.RETURN=d},8942:e=>{var t=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},9638:e=>{var t={}.hasOwnProperty;e.exports=function(e,n){return t.call(e,n)}},7270:(e,t,n)=>{var s=n(8397),i=n(4785);e.exports=n(6033)?function(e,t,n){return s.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},4455:(e,t,n)=>{var s=n(8942).document;e.exports=s&&s.documentElement},2375:(e,t,n)=>{e.exports=!n(6033)&&!n(2889)((function(){return 7!=Object.defineProperty(n(3640)("div"),"a",{get:function(){return 7}}).a}))},2240:e=>{e.exports=function(e,t,n){var s=void 0===n;switch(t.length){case 0:return s?e():e.call(n);case 1:return s?e(t[0]):e.call(n,t[0]);case 2:return s?e(t[0],t[1]):e.call(n,t[0],t[1]);case 3:return s?e(t[0],t[1],t[2]):e.call(n,t[0],t[1],t[2]);case 4:return s?e(t[0],t[1],t[2],t[3]):e.call(n,t[0],t[1],t[2],t[3])}return e.apply(n,t)}},4083:(e,t,n)=>{var s=n(103);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==s(e)?e.split(""):Object(e)}},692:(e,t,n)=>{var s=n(4098),i=n(3309)("iterator"),r=Array.prototype;e.exports=function(e){return void 0!==e&&(s.Array===e||r[i]===e)}},9773:e=>{e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},281:(e,t,n)=>{var s=n(2854);e.exports=function(e,t,n,i){try{return i?t(s(n)[0],n[1]):t(n)}catch(t){var r=e.return;throw void 0!==r&&s(r.call(e)),t}}},3463:(e,t,n)=>{"use strict";var s=n(8910),i=n(4785),r=n(8200),o={};n(7270)(o,n(3309)("iterator"),(function(){return this})),e.exports=function(e,t,n){e.prototype=s(o,{next:i(1,n)}),r(e,t+" Iterator")}},8534:(e,t,n)=>{"use strict";var s=n(7757),i=n(3948),r=n(9858),o=n(7270),a=n(4098),c=n(3463),l=n(8200),d=n(7471),u=n(3309)("iterator"),h=!([].keys&&"next"in[].keys()),f="keys",m="values",g=function(){return this};e.exports=function(e,t,n,p,v,y,b){c(n,t,p);var _,w,S,x=function(e){if(!h&&e in T)return T[e];switch(e){case f:case m:return function(){return new n(this,e)}}return function(){return new n(this,e)}},E=t+" Iterator",A=v==m,C=!1,T=e.prototype,k=T[u]||T["@@iterator"]||v&&T[v],j=k||x(v),N=v?A?x("entries"):j:void 0,O="Array"==t&&T.entries||k;if(O&&(S=d(O.call(new e)))!==Object.prototype&&S.next&&(l(S,E,!0),s||"function"==typeof S[u]||o(S,u,g)),A&&k&&k.name!==m&&(C=!0,j=function(){return k.call(this)}),s&&!b||!h&&!C&&T[u]||o(T,u,j),a[t]=j,a[E]=g,v)if(_={values:A?j:x(m),keys:y?j:x(f),entries:N},b)for(w in _)w in T||r(T,w,_[w]);else i(i.P+i.F*(h||C),t,_);return _}},4589:(e,t,n)=>{var s=n(3309)("iterator"),i=!1;try{var r=[7][s]();r.return=function(){i=!0},Array.from(r,(function(){throw 2}))}catch(e){}e.exports=function(e,t){if(!t&&!i)return!1;var n=!1;try{var r=[7],o=r[s]();o.next=function(){return{done:n=!0}},r[s]=function(){return o},e(r)}catch(e){}return n}},3434:e=>{e.exports=function(e,t){return{value:t,done:!!e}}},4098:e=>{e.exports={}},7757:e=>{e.exports=!0},7189:(e,t,n)=>{var s=n(8942),i=n(6673).set,r=s.MutationObserver||s.WebKitMutationObserver,o=s.process,a=s.Promise,c="process"==n(103)(o);e.exports=function(){var e,t,n,l=function(){var s,i;for(c&&(s=o.domain)&&s.exit();e;){i=e.fn,e=e.next;try{i()}catch(s){throw e?n():t=void 0,s}}t=void 0,s&&s.enter()};if(c)n=function(){o.nextTick(l)};else if(!r||s.navigator&&s.navigator.standalone)if(a&&a.resolve){var d=a.resolve(void 0);n=function(){d.then(l)}}else n=function(){i.call(s,l)};else{var u=!0,h=document.createTextNode("");new r(l).observe(h,{characterData:!0}),n=function(){h.data=u=!u}}return function(s){var i={fn:s,next:void 0};t&&(t.next=i),e||(e=i,n()),t=i}}},8278:(e,t,n)=>{"use strict";var s=n(8640);function i(e){var t,n;this.promise=new e((function(e,s){if(void 0!==t||void 0!==n)throw TypeError("Bad Promise constructor");t=e,n=s})),this.resolve=s(t),this.reject=s(n)}e.exports.f=function(e){return new i(e)}},8910:(e,t,n)=>{var s=n(2854),i=n(5244),r=n(1159),o=n(6962)("IE_PROTO"),a=function(){},c=function(){var e,t=n(3640)("iframe"),s=r.length;for(t.style.display="none",n(4455).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("