chat.js 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952
  1. var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  2. slice = [].slice,
  3. extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  4. hasProp = {}.hasOwnProperty;
  5. (function($, window) {
  6. var Base, Io, Log, Timeout, ZammadChat, myScript, scriptHost, scripts;
  7. scripts = document.getElementsByTagName('script');
  8. myScript = scripts[scripts.length - 1];
  9. scriptHost = myScript.src.match('.*://([^:/]*).*')[1];
  10. Base = (function() {
  11. Base.prototype.defaults = {
  12. debug: false
  13. };
  14. function Base(options) {
  15. this.options = $.extend({}, this.defaults, options);
  16. this.log = new Log({
  17. debug: this.options.debug,
  18. logPrefix: this.options.logPrefix || this.logPrefix
  19. });
  20. }
  21. return Base;
  22. })();
  23. Log = (function() {
  24. Log.prototype.defaults = {
  25. debug: false
  26. };
  27. function Log(options) {
  28. this.log = bind(this.log, this);
  29. this.error = bind(this.error, this);
  30. this.notice = bind(this.notice, this);
  31. this.debug = bind(this.debug, this);
  32. this.options = $.extend({}, this.defaults, options);
  33. }
  34. Log.prototype.debug = function() {
  35. var items;
  36. items = 1 <= arguments.length ? slice.call(arguments, 0) : [];
  37. if (!this.options.debug) {
  38. return;
  39. }
  40. return this.log('debug', items);
  41. };
  42. Log.prototype.notice = function() {
  43. var items;
  44. items = 1 <= arguments.length ? slice.call(arguments, 0) : [];
  45. return this.log('notice', items);
  46. };
  47. Log.prototype.error = function() {
  48. var items;
  49. items = 1 <= arguments.length ? slice.call(arguments, 0) : [];
  50. return this.log('error', items);
  51. };
  52. Log.prototype.log = function(level, items) {
  53. var i, item, len, logString;
  54. items.unshift('||');
  55. items.unshift(level);
  56. items.unshift(this.options.logPrefix);
  57. console.log.apply(console, items);
  58. if (!this.options.debug) {
  59. return;
  60. }
  61. logString = '';
  62. for (i = 0, len = items.length; i < len; i++) {
  63. item = items[i];
  64. logString += ' ';
  65. if (typeof item === 'object') {
  66. logString += JSON.stringify(item);
  67. } else if (item && item.toString) {
  68. logString += item.toString();
  69. } else {
  70. logString += item;
  71. }
  72. }
  73. return $('.js-chatLogDisplay').prepend('<div>' + logString + '</div>');
  74. };
  75. return Log;
  76. })();
  77. Timeout = (function(superClass) {
  78. extend(Timeout, superClass);
  79. Timeout.prototype.timeoutStartedAt = null;
  80. Timeout.prototype.logPrefix = 'timeout';
  81. Timeout.prototype.defaults = {
  82. debug: false,
  83. timeout: 4,
  84. timeoutIntervallCheck: 0.5
  85. };
  86. function Timeout(options) {
  87. this.stop = bind(this.stop, this);
  88. this.start = bind(this.start, this);
  89. Timeout.__super__.constructor.call(this, options);
  90. }
  91. Timeout.prototype.start = function() {
  92. var check, timeoutStartedAt;
  93. this.stop();
  94. timeoutStartedAt = new Date;
  95. check = (function(_this) {
  96. return function() {
  97. var timeLeft;
  98. timeLeft = new Date - new Date(timeoutStartedAt.getTime() + _this.options.timeout * 1000 * 60);
  99. _this.log.debug("Timeout check for " + _this.options.timeout + " minutes (left " + (timeLeft / 1000) + " sec.)");
  100. if (timeLeft < 0) {
  101. return;
  102. }
  103. _this.stop();
  104. return _this.options.callback();
  105. };
  106. })(this);
  107. this.log.debug("Start timeout in " + this.options.timeout + " minutes");
  108. return this.intervallId = setInterval(check, this.options.timeoutIntervallCheck * 1000 * 60);
  109. };
  110. Timeout.prototype.stop = function() {
  111. if (!this.intervallId) {
  112. return;
  113. }
  114. this.log.debug("Stop timeout of " + this.options.timeout + " minutes");
  115. return clearInterval(this.intervallId);
  116. };
  117. return Timeout;
  118. })(Base);
  119. Io = (function(superClass) {
  120. extend(Io, superClass);
  121. Io.prototype.logPrefix = 'io';
  122. function Io(options) {
  123. this.ping = bind(this.ping, this);
  124. this.send = bind(this.send, this);
  125. this.reconnect = bind(this.reconnect, this);
  126. this.close = bind(this.close, this);
  127. this.connect = bind(this.connect, this);
  128. this.set = bind(this.set, this);
  129. Io.__super__.constructor.call(this, options);
  130. }
  131. Io.prototype.set = function(params) {
  132. var key, results, value;
  133. results = [];
  134. for (key in params) {
  135. value = params[key];
  136. results.push(this.options[key] = value);
  137. }
  138. return results;
  139. };
  140. Io.prototype.connect = function() {
  141. this.log.debug("Connecting to " + this.options.host);
  142. this.ws = new window.WebSocket("" + this.options.host);
  143. this.ws.onopen = (function(_this) {
  144. return function(e) {
  145. _this.log.debug('onOpen', e);
  146. _this.options.onOpen(e);
  147. return _this.ping();
  148. };
  149. })(this);
  150. this.ws.onmessage = (function(_this) {
  151. return function(e) {
  152. var i, len, pipe, pipes;
  153. pipes = JSON.parse(e.data);
  154. _this.log.debug('onMessage', e.data);
  155. for (i = 0, len = pipes.length; i < len; i++) {
  156. pipe = pipes[i];
  157. if (pipe.event === 'pong') {
  158. _this.ping();
  159. }
  160. }
  161. if (_this.options.onMessage) {
  162. return _this.options.onMessage(pipes);
  163. }
  164. };
  165. })(this);
  166. this.ws.onclose = (function(_this) {
  167. return function(e) {
  168. _this.log.debug('close websocket connection', e);
  169. if (_this.pingDelayId) {
  170. clearTimeout(_this.pingDelayId);
  171. }
  172. if (_this.manualClose) {
  173. _this.log.debug('manual close, onClose callback');
  174. _this.manualClose = false;
  175. if (_this.options.onClose) {
  176. return _this.options.onClose(e);
  177. }
  178. } else {
  179. _this.log.debug('error close, onError callback');
  180. if (_this.options.onError) {
  181. return _this.options.onError('Connection lost...');
  182. }
  183. }
  184. };
  185. })(this);
  186. return this.ws.onerror = (function(_this) {
  187. return function(e) {
  188. _this.log.debug('onError', e);
  189. if (_this.options.onError) {
  190. return _this.options.onError(e);
  191. }
  192. };
  193. })(this);
  194. };
  195. Io.prototype.close = function() {
  196. this.log.debug('close websocket manually');
  197. this.manualClose = true;
  198. return this.ws.close();
  199. };
  200. Io.prototype.reconnect = function() {
  201. this.log.debug('reconnect');
  202. this.close();
  203. return this.connect();
  204. };
  205. Io.prototype.send = function(event, data) {
  206. var msg;
  207. if (data == null) {
  208. data = {};
  209. }
  210. this.log.debug('send', event, data);
  211. msg = JSON.stringify({
  212. event: event,
  213. data: data
  214. });
  215. return this.ws.send(msg);
  216. };
  217. Io.prototype.ping = function() {
  218. var localPing;
  219. localPing = (function(_this) {
  220. return function() {
  221. return _this.send('ping');
  222. };
  223. })(this);
  224. return this.pingDelayId = setTimeout(localPing, 29000);
  225. };
  226. return Io;
  227. })(Base);
  228. ZammadChat = (function(superClass) {
  229. extend(ZammadChat, superClass);
  230. ZammadChat.prototype.defaults = {
  231. chatId: void 0,
  232. show: true,
  233. target: $('body'),
  234. host: '',
  235. debug: false,
  236. flat: false,
  237. lang: void 0,
  238. cssAutoload: true,
  239. cssUrl: void 0,
  240. fontSize: void 0,
  241. buttonClass: 'open-zammad-chat',
  242. inactiveClass: 'is-inactive',
  243. title: '<strong>Chat</strong> with us!',
  244. idleTimeout: 6,
  245. idleTimeoutIntervallCheck: 0.5,
  246. inactiveTimeout: 8,
  247. inactiveTimeoutIntervallCheck: 0.5,
  248. waitingListTimeout: 4,
  249. waitingListTimeoutIntervallCheck: 0.5
  250. };
  251. ZammadChat.prototype.logPrefix = 'chat';
  252. ZammadChat.prototype._messageCount = 0;
  253. ZammadChat.prototype.isOpen = false;
  254. ZammadChat.prototype.blinkOnlineInterval = null;
  255. ZammadChat.prototype.stopBlinOnlineStateTimeout = null;
  256. ZammadChat.prototype.showTimeEveryXMinutes = 2;
  257. ZammadChat.prototype.lastTimestamp = null;
  258. ZammadChat.prototype.lastAddedType = null;
  259. ZammadChat.prototype.inputTimeout = null;
  260. ZammadChat.prototype.isTyping = false;
  261. ZammadChat.prototype.state = 'offline';
  262. ZammadChat.prototype.initialQueueDelay = 10000;
  263. ZammadChat.prototype.translations = {
  264. de: {
  265. '<strong>Chat</strong> with us!': '<strong>Chatte</strong> mit uns!',
  266. 'Online': 'Online',
  267. 'Online': 'Online',
  268. 'Offline': 'Offline',
  269. 'Connecting': 'Verbinden',
  270. 'Connection re-established': 'Verbindung wiederhergestellt',
  271. 'Today': 'Heute',
  272. 'Send': 'Senden',
  273. 'Compose your message...': 'Ihre Nachricht...',
  274. 'All colleagues are busy.': 'Alle Kollegen sind belegt.',
  275. 'You are on waiting list position <strong>%s</strong>.': 'Sie sind in der Warteliste an der Position <strong>%s</strong>.',
  276. 'Start new conversation': 'Neue Konversation starten',
  277. 'Since you didn\'t respond in the last %s minutes your conversation with <strong>%s</strong> got closed.': 'Da Sie in den letzten %s Minuten nichts geschrieben haben wurde Ihre Konversation mit <strong>%s</strong> geschlossen.',
  278. 'Since you didn\'t respond in the last %s minutes your conversation got closed.': 'Da Sie in den letzten %s Minuten nichts geschrieben haben wurde Ihre Konversation geschlossen.'
  279. }
  280. };
  281. ZammadChat.prototype.sessionId = void 0;
  282. ZammadChat.prototype.T = function() {
  283. var i, item, items, len, string, translations;
  284. string = arguments[0], items = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  285. if (this.options.lang && this.options.lang !== 'en') {
  286. if (!this.translations[this.options.lang]) {
  287. this.log.notice("Translation '" + this.options.lang + "' needed!");
  288. } else {
  289. translations = this.translations[this.options.lang];
  290. if (!translations[string]) {
  291. this.log.notice("Translation needed for '" + string + "'");
  292. }
  293. string = translations[string] || string;
  294. }
  295. }
  296. if (items) {
  297. for (i = 0, len = items.length; i < len; i++) {
  298. item = items[i];
  299. string = string.replace(/%s/, item);
  300. }
  301. }
  302. return string;
  303. };
  304. ZammadChat.prototype.view = function(name) {
  305. return (function(_this) {
  306. return function(options) {
  307. if (!options) {
  308. options = {};
  309. }
  310. options.T = _this.T;
  311. options.background = _this.options.background;
  312. options.flat = _this.options.flat;
  313. options.fontSize = _this.options.fontSize;
  314. return window.zammadChatTemplates[name](options);
  315. };
  316. })(this);
  317. };
  318. function ZammadChat(options) {
  319. this.startTimeoutObservers = bind(this.startTimeoutObservers, this);
  320. this.onCssLoaded = bind(this.onCssLoaded, this);
  321. this.setAgentOnlineState = bind(this.setAgentOnlineState, this);
  322. this.onConnectionEstablished = bind(this.onConnectionEstablished, this);
  323. this.setSessionId = bind(this.setSessionId, this);
  324. this.onConnectionReestablished = bind(this.onConnectionReestablished, this);
  325. this.reconnect = bind(this.reconnect, this);
  326. this.destroy = bind(this.destroy, this);
  327. this.onLeaveTemporary = bind(this.onLeaveTemporary, this);
  328. this.onAgentTypingEnd = bind(this.onAgentTypingEnd, this);
  329. this.onAgentTypingStart = bind(this.onAgentTypingStart, this);
  330. this.onQueue = bind(this.onQueue, this);
  331. this.onQueueScreen = bind(this.onQueueScreen, this);
  332. this.onWebSocketClose = bind(this.onWebSocketClose, this);
  333. this.onCloseAnimationEnd = bind(this.onCloseAnimationEnd, this);
  334. this.close = bind(this.close, this);
  335. this.toggle = bind(this.toggle, this);
  336. this.sessionClose = bind(this.sessionClose, this);
  337. this.onOpenAnimationEnd = bind(this.onOpenAnimationEnd, this);
  338. this.open = bind(this.open, this);
  339. this.renderMessage = bind(this.renderMessage, this);
  340. this.receiveMessage = bind(this.receiveMessage, this);
  341. this.onSubmit = bind(this.onSubmit, this);
  342. this.onFocus = bind(this.onFocus, this);
  343. this.onInput = bind(this.onInput, this);
  344. this.onReopenSession = bind(this.onReopenSession, this);
  345. this.onError = bind(this.onError, this);
  346. this.onWebSocketMessage = bind(this.onWebSocketMessage, this);
  347. this.send = bind(this.send, this);
  348. this.checkForEnter = bind(this.checkForEnter, this);
  349. this.render = bind(this.render, this);
  350. this.view = bind(this.view, this);
  351. this.T = bind(this.T, this);
  352. this.options = $.extend({}, this.defaults, options);
  353. ZammadChat.__super__.constructor.call(this, this.options);
  354. this.isFullscreen = window.matchMedia && window.matchMedia('(max-width: 768px)').matches;
  355. this.scrollRoot = $(this.getScrollRoot());
  356. if (!$) {
  357. this.state = 'unsupported';
  358. this.log.notice('Chat: no jquery found!');
  359. return;
  360. }
  361. if (!window.WebSocket || !sessionStorage) {
  362. this.state = 'unsupported';
  363. this.log.notice('Chat: Browser not supported!');
  364. return;
  365. }
  366. if (!this.options.chatId) {
  367. this.state = 'unsupported';
  368. this.log.error('Chat: need chatId as option!');
  369. return;
  370. }
  371. if (!this.options.lang) {
  372. this.options.lang = $('html').attr('lang');
  373. }
  374. if (this.options.lang) {
  375. this.options.lang = this.options.lang.replace(/-.+?$/, '');
  376. this.log.debug("lang: " + this.options.lang);
  377. }
  378. if (!this.options.host) {
  379. this.detectHost();
  380. }
  381. this.loadCss();
  382. this.io = new Io(this.options);
  383. this.io.set({
  384. onOpen: this.render,
  385. onClose: this.onWebSocketClose,
  386. onMessage: this.onWebSocketMessage,
  387. onError: this.onError
  388. });
  389. this.io.connect();
  390. }
  391. ZammadChat.prototype.getScrollRoot = function() {
  392. var end, html, start;
  393. if ('scrollingElement' in document) {
  394. return document.scrollingElement;
  395. }
  396. html = document.documentElement;
  397. start = html.scrollTop;
  398. html.scrollTop = start + 1;
  399. end = html.scrollTop;
  400. html.scrollTop = start;
  401. if (end > start) {
  402. return html;
  403. } else {
  404. return document.body;
  405. }
  406. };
  407. ZammadChat.prototype.render = function() {
  408. if (!this.el || !$('.zammad-chat').get(0)) {
  409. this.renderBase();
  410. }
  411. $("." + this.options.buttonClass).addClass(this.inactiveClass);
  412. this.setAgentOnlineState('online');
  413. this.log.debug('widget rendered');
  414. this.startTimeoutObservers();
  415. this.idleTimeout.start();
  416. this.sessionId = sessionStorage.getItem('sessionId');
  417. return this.send('chat_status_customer', {
  418. session_id: this.sessionId,
  419. url: window.location.href
  420. });
  421. };
  422. ZammadChat.prototype.renderBase = function() {
  423. this.el = $(this.view('chat')({
  424. title: this.options.title
  425. }));
  426. this.options.target.append(this.el);
  427. this.input = this.el.find('.zammad-chat-input');
  428. this.el.find('.js-chat-open').click(this.open);
  429. this.el.find('.js-chat-toggle').click(this.toggle);
  430. this.el.find('.zammad-chat-controls').on('submit', this.onSubmit);
  431. this.input.on({
  432. keydown: this.checkForEnter,
  433. input: this.onInput
  434. });
  435. $(window).on('beforeunload', (function(_this) {
  436. return function() {
  437. return _this.onLeaveTemporary();
  438. };
  439. })(this));
  440. $(window).bind('hashchange', (function(_this) {
  441. return function() {
  442. if (_this.isOpen) {
  443. if (_this.sessionId) {
  444. _this.send('chat_session_notice', {
  445. session_id: _this.sessionId,
  446. message: window.location.href
  447. });
  448. }
  449. return;
  450. }
  451. return _this.idleTimeout.start();
  452. };
  453. })(this));
  454. if (this.isFullscreen) {
  455. return this.input.on({
  456. focus: this.onFocus,
  457. focusout: this.onFocusOut
  458. });
  459. }
  460. };
  461. ZammadChat.prototype.checkForEnter = function(event) {
  462. if (!event.shiftKey && event.keyCode === 13) {
  463. event.preventDefault();
  464. return this.sendMessage();
  465. }
  466. };
  467. ZammadChat.prototype.send = function(event, data) {
  468. if (data == null) {
  469. data = {};
  470. }
  471. data.chat_id = this.options.chatId;
  472. return this.io.send(event, data);
  473. };
  474. ZammadChat.prototype.onWebSocketMessage = function(pipes) {
  475. var i, len, pipe;
  476. for (i = 0, len = pipes.length; i < len; i++) {
  477. pipe = pipes[i];
  478. this.log.debug('ws:onmessage', pipe);
  479. switch (pipe.event) {
  480. case 'chat_error':
  481. this.log.notice(pipe.data);
  482. if (pipe.data && pipe.data.state === 'chat_disabled') {
  483. this.destroy({
  484. remove: true
  485. });
  486. }
  487. break;
  488. case 'chat_session_message':
  489. if (pipe.data.self_written) {
  490. return;
  491. }
  492. this.receiveMessage(pipe.data);
  493. break;
  494. case 'chat_session_typing':
  495. if (pipe.data.self_written) {
  496. return;
  497. }
  498. this.onAgentTypingStart();
  499. break;
  500. case 'chat_session_start':
  501. this.onConnectionEstablished(pipe.data);
  502. break;
  503. case 'chat_session_queue':
  504. this.onQueueScreen(pipe.data);
  505. break;
  506. case 'chat_session_closed':
  507. this.onSessionClosed(pipe.data);
  508. break;
  509. case 'chat_session_left':
  510. this.onSessionClosed(pipe.data);
  511. break;
  512. case 'chat_status_customer':
  513. switch (pipe.data.state) {
  514. case 'online':
  515. this.sessionId = void 0;
  516. if (!this.options.cssAutoload || this.cssLoaded) {
  517. this.onReady();
  518. } else {
  519. this.socketReady = true;
  520. }
  521. break;
  522. case 'offline':
  523. this.onError('Zammad Chat: No agent online');
  524. break;
  525. case 'chat_disabled':
  526. this.onError('Zammad Chat: Chat is disabled');
  527. break;
  528. case 'no_seats_available':
  529. this.onError("Zammad Chat: Too many clients in queue. Clients in queue: " + pipe.data.queue);
  530. break;
  531. case 'reconnect':
  532. this.onReopenSession(pipe.data);
  533. }
  534. }
  535. }
  536. };
  537. ZammadChat.prototype.onReady = function() {
  538. this.log.debug('widget ready for use');
  539. $("." + this.options.buttonClass).click(this.open).removeClass(this.inactiveClass);
  540. if (this.options.show) {
  541. return this.show();
  542. }
  543. };
  544. ZammadChat.prototype.onError = function(message) {
  545. this.log.debug(message);
  546. this.addStatus(message);
  547. $("." + this.options.buttonClass).hide();
  548. if (this.isOpen) {
  549. this.disableInput();
  550. return this.destroy({
  551. remove: false
  552. });
  553. } else {
  554. return this.destroy({
  555. remove: true
  556. });
  557. }
  558. };
  559. ZammadChat.prototype.onReopenSession = function(data) {
  560. var i, len, message, ref, unfinishedMessage;
  561. this.log.debug('old messages', data.session);
  562. this.inactiveTimeout.start();
  563. unfinishedMessage = sessionStorage.getItem('unfinished_message');
  564. if (data.agent) {
  565. this.onConnectionEstablished(data);
  566. ref = data.session;
  567. for (i = 0, len = ref.length; i < len; i++) {
  568. message = ref[i];
  569. this.renderMessage({
  570. message: message.content,
  571. id: message.id,
  572. from: message.created_by_id ? 'agent' : 'customer'
  573. });
  574. }
  575. if (unfinishedMessage) {
  576. this.input.val(unfinishedMessage);
  577. }
  578. }
  579. if (data.position) {
  580. this.onQueue(data);
  581. }
  582. this.show();
  583. this.open();
  584. this.scrollToBottom();
  585. if (unfinishedMessage) {
  586. return this.input.focus();
  587. }
  588. };
  589. ZammadChat.prototype.onInput = function() {
  590. this.el.find('.zammad-chat-message--unread').removeClass('zammad-chat-message--unread');
  591. sessionStorage.setItem('unfinished_message', this.input.val());
  592. return this.onTyping();
  593. };
  594. ZammadChat.prototype.onFocus = function() {
  595. var keyboardShown;
  596. $(window).scrollTop(10);
  597. keyboardShown = $(window).scrollTop() > 0;
  598. $(window).scrollTop(0);
  599. if (keyboardShown) {
  600. return this.log.notice('virtual keyboard shown');
  601. }
  602. };
  603. ZammadChat.prototype.onFocusOut = function() {};
  604. ZammadChat.prototype.onTyping = function() {
  605. if (this.isTyping && this.isTyping > new Date(new Date().getTime() - 1500)) {
  606. return;
  607. }
  608. this.isTyping = new Date();
  609. this.send('chat_session_typing', {
  610. session_id: this.sessionId
  611. });
  612. return this.inactiveTimeout.start();
  613. };
  614. ZammadChat.prototype.onSubmit = function(event) {
  615. event.preventDefault();
  616. return this.sendMessage();
  617. };
  618. ZammadChat.prototype.sendMessage = function() {
  619. var message, messageElement;
  620. message = this.input.val();
  621. if (!message) {
  622. return;
  623. }
  624. this.inactiveTimeout.start();
  625. sessionStorage.removeItem('unfinished_message');
  626. messageElement = this.view('message')({
  627. message: message,
  628. from: 'customer',
  629. id: this._messageCount++,
  630. unreadClass: ''
  631. });
  632. this.maybeAddTimestamp();
  633. if (this.el.find('.zammad-chat-message--typing').size()) {
  634. this.lastAddedType = 'typing-placeholder';
  635. this.el.find('.zammad-chat-message--typing').before(messageElement);
  636. } else {
  637. this.lastAddedType = 'message--customer';
  638. this.el.find('.zammad-chat-body').append(messageElement);
  639. }
  640. this.input.val('');
  641. this.scrollToBottom();
  642. return this.send('chat_session_message', {
  643. content: message,
  644. id: this._messageCount,
  645. session_id: this.sessionId
  646. });
  647. };
  648. ZammadChat.prototype.receiveMessage = function(data) {
  649. this.inactiveTimeout.start();
  650. this.onAgentTypingEnd();
  651. this.maybeAddTimestamp();
  652. return this.renderMessage({
  653. message: data.message.content,
  654. id: data.id,
  655. from: 'agent'
  656. });
  657. };
  658. ZammadChat.prototype.renderMessage = function(data) {
  659. this.lastAddedType = "message--" + data.from;
  660. data.unreadClass = document.hidden ? ' zammad-chat-message--unread' : '';
  661. this.el.find('.zammad-chat-body').append(this.view('message')(data));
  662. return this.scrollToBottom();
  663. };
  664. ZammadChat.prototype.open = function() {
  665. var remainerHeight;
  666. if (this.isOpen) {
  667. this.log.debug('widget already open, block');
  668. return;
  669. }
  670. this.isOpen = true;
  671. this.log.debug('open widget');
  672. if (!this.sessionId) {
  673. this.showLoader();
  674. }
  675. this.el.addClass('zammad-chat-is-open');
  676. if (!this.inputInitialized) {
  677. this.inputInitialized = true;
  678. this.input.autoGrow({
  679. extraLine: false
  680. });
  681. }
  682. remainerHeight = this.el.height() - this.el.find('.zammad-chat-header').outerHeight();
  683. this.el.css('bottom', -remainerHeight);
  684. if (!this.sessionId) {
  685. this.el.animate({
  686. bottom: 0
  687. }, 500, this.onOpenAnimationEnd);
  688. return this.send('chat_session_init', {
  689. url: window.location.href
  690. });
  691. } else {
  692. this.el.css('bottom', 0);
  693. return this.onOpenAnimationEnd();
  694. }
  695. };
  696. ZammadChat.prototype.onOpenAnimationEnd = function() {
  697. this.idleTimeout.stop();
  698. if (this.isFullscreen) {
  699. return this.disableScrollOnRoot();
  700. }
  701. };
  702. ZammadChat.prototype.sessionClose = function() {
  703. this.send('chat_session_close', {
  704. session_id: this.sessionId
  705. });
  706. this.inactiveTimeout.stop();
  707. this.waitingListTimeout.stop();
  708. sessionStorage.removeItem('unfinished_message');
  709. if (this.onInitialQueueDelayId) {
  710. clearTimeout(this.onInitialQueueDelayId);
  711. }
  712. return this.setSessionId(void 0);
  713. };
  714. ZammadChat.prototype.toggle = function(event) {
  715. if (this.isOpen) {
  716. return this.close(event);
  717. } else {
  718. return this.open(event);
  719. }
  720. };
  721. ZammadChat.prototype.close = function(event) {
  722. var remainerHeight;
  723. if (!this.isOpen) {
  724. this.log.debug('can\'t close widget, it\'s not open');
  725. return;
  726. }
  727. if (this.initDelayId) {
  728. clearTimeout(this.initDelayId);
  729. }
  730. if (!this.sessionId) {
  731. this.log.debug('can\'t close widget without sessionId');
  732. return;
  733. }
  734. this.log.debug('close widget');
  735. if (event) {
  736. event.stopPropagation();
  737. }
  738. this.sessionClose();
  739. if (this.isFullscreen) {
  740. this.enableScrollOnRoot();
  741. }
  742. remainerHeight = this.el.height() - this.el.find('.zammad-chat-header').outerHeight();
  743. return this.el.animate({
  744. bottom: -remainerHeight
  745. }, 500, this.onCloseAnimationEnd);
  746. };
  747. ZammadChat.prototype.onCloseAnimationEnd = function() {
  748. this.el.css('bottom', '');
  749. this.el.removeClass('zammad-chat-is-open');
  750. this.showLoader();
  751. this.el.find('.zammad-chat-welcome').removeClass('zammad-chat-is-hidden');
  752. this.el.find('.zammad-chat-agent').addClass('zammad-chat-is-hidden');
  753. this.el.find('.zammad-chat-agent-status').addClass('zammad-chat-is-hidden');
  754. this.isOpen = false;
  755. return this.io.reconnect();
  756. };
  757. ZammadChat.prototype.onWebSocketClose = function() {
  758. if (this.isOpen) {
  759. return;
  760. }
  761. if (this.el) {
  762. this.el.removeClass('zammad-chat-is-shown');
  763. return this.el.removeClass('zammad-chat-is-loaded');
  764. }
  765. };
  766. ZammadChat.prototype.show = function() {
  767. if (this.state === 'offline') {
  768. return;
  769. }
  770. this.el.addClass('zammad-chat-is-loaded');
  771. return this.el.addClass('zammad-chat-is-shown');
  772. };
  773. ZammadChat.prototype.disableInput = function() {
  774. this.input.prop('disabled', true);
  775. return this.el.find('.zammad-chat-send').prop('disabled', true);
  776. };
  777. ZammadChat.prototype.enableInput = function() {
  778. this.input.prop('disabled', false);
  779. return this.el.find('.zammad-chat-send').prop('disabled', false);
  780. };
  781. ZammadChat.prototype.hideModal = function() {
  782. return this.el.find('.zammad-chat-modal').html('');
  783. };
  784. ZammadChat.prototype.onQueueScreen = function(data) {
  785. var show;
  786. this.setSessionId(data.session_id);
  787. show = (function(_this) {
  788. return function() {
  789. _this.onQueue(data);
  790. return _this.waitingListTimeout.start();
  791. };
  792. })(this);
  793. if (this.initialQueueDelay && !this.onInitialQueueDelayId) {
  794. this.onInitialQueueDelayId = setTimeout(show, this.initialQueueDelay);
  795. return;
  796. }
  797. if (this.onInitialQueueDelayId) {
  798. clearTimeout(this.onInitialQueueDelayId);
  799. }
  800. return show();
  801. };
  802. ZammadChat.prototype.onQueue = function(data) {
  803. this.log.notice('onQueue', data.position);
  804. this.inQueue = true;
  805. return this.el.find('.zammad-chat-modal').html(this.view('waiting')({
  806. position: data.position
  807. }));
  808. };
  809. ZammadChat.prototype.onAgentTypingStart = function() {
  810. if (this.stopTypingId) {
  811. clearTimeout(this.stopTypingId);
  812. }
  813. this.stopTypingId = setTimeout(this.onAgentTypingEnd, 3000);
  814. if (this.el.find('.zammad-chat-message--typing').size()) {
  815. return;
  816. }
  817. this.maybeAddTimestamp();
  818. this.el.find('.zammad-chat-body').append(this.view('typingIndicator')());
  819. if (!this.isVisible(this.el.find('.zammad-chat-message--typing'), true)) {
  820. return;
  821. }
  822. return this.scrollToBottom();
  823. };
  824. ZammadChat.prototype.onAgentTypingEnd = function() {
  825. return this.el.find('.zammad-chat-message--typing').remove();
  826. };
  827. ZammadChat.prototype.onLeaveTemporary = function() {
  828. if (!this.sessionId) {
  829. return;
  830. }
  831. return this.send('chat_session_leave_temporary', {
  832. session_id: this.sessionId
  833. });
  834. };
  835. ZammadChat.prototype.maybeAddTimestamp = function() {
  836. var label, time, timestamp;
  837. timestamp = Date.now();
  838. if (!this.lastTimestamp || (timestamp - this.lastTimestamp) > this.showTimeEveryXMinutes * 60000) {
  839. label = this.T('Today');
  840. time = new Date().toTimeString().substr(0, 5);
  841. if (this.lastAddedType === 'timestamp') {
  842. this.updateLastTimestamp(label, time);
  843. return this.lastTimestamp = timestamp;
  844. } else {
  845. this.el.find('.zammad-chat-body').append(this.view('timestamp')({
  846. label: label,
  847. time: time
  848. }));
  849. this.lastTimestamp = timestamp;
  850. this.lastAddedType = 'timestamp';
  851. return this.scrollToBottom();
  852. }
  853. }
  854. };
  855. ZammadChat.prototype.updateLastTimestamp = function(label, time) {
  856. if (!this.el) {
  857. return;
  858. }
  859. return this.el.find('.zammad-chat-body').find('.zammad-chat-timestamp').last().replaceWith(this.view('timestamp')({
  860. label: label,
  861. time: time
  862. }));
  863. };
  864. ZammadChat.prototype.addStatus = function(status) {
  865. if (!this.el) {
  866. return;
  867. }
  868. this.maybeAddTimestamp();
  869. this.el.find('.zammad-chat-body').append(this.view('status')({
  870. status: status
  871. }));
  872. return this.scrollToBottom();
  873. };
  874. ZammadChat.prototype.scrollToBottom = function() {
  875. return this.el.find('.zammad-chat-body').scrollTop($('.zammad-chat-body').prop('scrollHeight'));
  876. };
  877. ZammadChat.prototype.destroy = function(params) {
  878. if (params == null) {
  879. params = {};
  880. }
  881. this.log.debug('destroy widget', params);
  882. this.setAgentOnlineState('offline');
  883. if (params.remove && this.el) {
  884. this.el.remove();
  885. }
  886. if (this.waitingListTimeout) {
  887. this.waitingListTimeout.stop();
  888. }
  889. if (this.inactiveTimeout) {
  890. this.inactiveTimeout.stop();
  891. }
  892. if (this.idleTimeout) {
  893. this.idleTimeout.stop();
  894. }
  895. return this.io.close();
  896. };
  897. ZammadChat.prototype.reconnect = function() {
  898. this.log.notice('reconnecting');
  899. this.disableInput();
  900. this.lastAddedType = 'status';
  901. this.setAgentOnlineState('connecting');
  902. return this.addStatus(this.T('Connection lost'));
  903. };
  904. ZammadChat.prototype.onConnectionReestablished = function() {
  905. this.lastAddedType = 'status';
  906. this.setAgentOnlineState('online');
  907. return this.addStatus(this.T('Connection re-established'));
  908. };
  909. ZammadChat.prototype.onSessionClosed = function(data) {
  910. this.addStatus(this.T('Chat closed by %s', data.realname));
  911. this.disableInput();
  912. this.setAgentOnlineState('offline');
  913. return this.inactiveTimeout.stop();
  914. };
  915. ZammadChat.prototype.setSessionId = function(id) {
  916. this.sessionId = id;
  917. if (id === void 0) {
  918. return sessionStorage.removeItem('sessionId');
  919. } else {
  920. return sessionStorage.setItem('sessionId', id);
  921. }
  922. };
  923. ZammadChat.prototype.onConnectionEstablished = function(data) {
  924. if (this.onInitialQueueDelayId) {
  925. clearTimeout(this.onInitialQueueDelayId);
  926. }
  927. this.inQueue = false;
  928. if (data.agent) {
  929. this.agent = data.agent;
  930. }
  931. if (data.session_id) {
  932. this.setSessionId(data.session_id);
  933. }
  934. this.el.find('.zammad-chat-body').html('');
  935. this.el.find('.zammad-chat-agent').html(this.view('agent')({
  936. agent: this.agent
  937. }));
  938. this.enableInput();
  939. this.hideModal();
  940. this.el.find('.zammad-chat-welcome').addClass('zammad-chat-is-hidden');
  941. this.el.find('.zammad-chat-agent').removeClass('zammad-chat-is-hidden');
  942. this.el.find('.zammad-chat-agent-status').removeClass('zammad-chat-is-hidden');
  943. if (!this.isFullscreen) {
  944. this.input.focus();
  945. }
  946. this.setAgentOnlineState('online');
  947. this.waitingListTimeout.stop();
  948. this.idleTimeout.stop();
  949. return this.inactiveTimeout.start();
  950. };
  951. ZammadChat.prototype.showCustomerTimeout = function() {
  952. var reload;
  953. this.el.find('.zammad-chat-modal').html(this.view('customer_timeout')({
  954. agent: this.agent.name,
  955. delay: this.options.inactiveTimeout
  956. }));
  957. reload = function() {
  958. return location.reload();
  959. };
  960. this.el.find('.js-restart').click(reload);
  961. return this.sessionClose();
  962. };
  963. ZammadChat.prototype.showWaitingListTimeout = function() {
  964. var reload;
  965. this.el.find('.zammad-chat-modal').html(this.view('waiting_list_timeout')({
  966. delay: this.options.watingListTimeout
  967. }));
  968. reload = function() {
  969. return location.reload();
  970. };
  971. this.el.find('.js-restart').click(reload);
  972. return this.sessionClose();
  973. };
  974. ZammadChat.prototype.showLoader = function() {
  975. return this.el.find('.zammad-chat-modal').html(this.view('loader')());
  976. };
  977. ZammadChat.prototype.setAgentOnlineState = function(state) {
  978. var capitalizedState;
  979. this.state = state;
  980. if (!this.el) {
  981. return;
  982. }
  983. capitalizedState = state.charAt(0).toUpperCase() + state.slice(1);
  984. return this.el.find('.zammad-chat-agent-status').attr('data-status', state).text(this.T(capitalizedState));
  985. };
  986. ZammadChat.prototype.detectHost = function() {
  987. var protocol;
  988. protocol = 'ws://';
  989. if (window.location.protocol === 'https:') {
  990. protocol = 'wss://';
  991. }
  992. return this.options.host = "" + protocol + scriptHost + "/ws";
  993. };
  994. ZammadChat.prototype.loadCss = function() {
  995. var newSS, styles, url;
  996. if (!this.options.cssAutoload) {
  997. return;
  998. }
  999. url = this.options.cssUrl;
  1000. if (!url) {
  1001. url = this.options.host.replace(/^wss/i, 'https').replace(/^ws/i, 'http').replace(/\/ws/i, '');
  1002. url += '/assets/chat/chat.css';
  1003. }
  1004. this.log.debug("load css from '" + url + "'");
  1005. styles = "@import url('" + url + "');";
  1006. newSS = document.createElement('link');
  1007. newSS.onload = this.onCssLoaded;
  1008. newSS.rel = 'stylesheet';
  1009. newSS.href = 'data:text/css,' + escape(styles);
  1010. return document.getElementsByTagName('head')[0].appendChild(newSS);
  1011. };
  1012. ZammadChat.prototype.onCssLoaded = function() {
  1013. if (this.socketReady) {
  1014. return this.onReady();
  1015. } else {
  1016. return this.cssLoaded = true;
  1017. }
  1018. };
  1019. ZammadChat.prototype.startTimeoutObservers = function() {
  1020. this.idleTimeout = new Timeout({
  1021. logPrefix: 'idleTimeout',
  1022. debug: this.options.debug,
  1023. timeout: this.options.idleTimeout,
  1024. timeoutIntervallCheck: this.options.idleTimeoutIntervallCheck,
  1025. callback: (function(_this) {
  1026. return function() {
  1027. _this.log.debug('Idle timeout reached, hide widget', new Date);
  1028. return _this.destroy({
  1029. remove: true
  1030. });
  1031. };
  1032. })(this)
  1033. });
  1034. this.inactiveTimeout = new Timeout({
  1035. logPrefix: 'inactiveTimeout',
  1036. debug: this.options.debug,
  1037. timeout: this.options.inactiveTimeout,
  1038. timeoutIntervallCheck: this.options.inactiveTimeoutIntervallCheck,
  1039. callback: (function(_this) {
  1040. return function() {
  1041. _this.log.debug('Inactive timeout reached, show timeout screen.', new Date);
  1042. _this.showCustomerTimeout();
  1043. return _this.destroy({
  1044. remove: false
  1045. });
  1046. };
  1047. })(this)
  1048. });
  1049. return this.waitingListTimeout = new Timeout({
  1050. logPrefix: 'waitingListTimeout',
  1051. debug: this.options.debug,
  1052. timeout: this.options.waitingListTimeout,
  1053. timeoutIntervallCheck: this.options.waitingListTimeoutIntervallCheck,
  1054. callback: (function(_this) {
  1055. return function() {
  1056. _this.log.debug('Waiting list timeout reached, show timeout screen.', new Date);
  1057. _this.showWaitingListTimeout();
  1058. return _this.destroy({
  1059. remove: false
  1060. });
  1061. };
  1062. })(this)
  1063. });
  1064. };
  1065. ZammadChat.prototype.disableScrollOnRoot = function() {
  1066. this.rootScrollOffset = this.scrollRoot.scrollTop();
  1067. return this.scrollRoot.css({
  1068. overflow: 'hidden',
  1069. position: 'fixed'
  1070. });
  1071. };
  1072. ZammadChat.prototype.enableScrollOnRoot = function() {
  1073. this.scrollRoot.scrollTop(this.rootScrollOffset);
  1074. return this.scrollRoot.css({
  1075. overflow: '',
  1076. position: ''
  1077. });
  1078. };
  1079. ZammadChat.prototype.isVisible = function(el, partial, hidden, direction) {
  1080. var $t, $w, _bottom, _left, _right, _top, bViz, clientSize, compareBottom, compareLeft, compareRight, compareTop, hVisible, lViz, offset, rViz, rec, t, tViz, vVisible, viewBottom, viewLeft, viewRight, viewTop, vpHeight, vpWidth;
  1081. if (el.length < 1) {
  1082. return;
  1083. }
  1084. $w = $(window);
  1085. $t = el.length > 1 ? el.eq(0) : el;
  1086. t = $t.get(0);
  1087. vpWidth = $w.width();
  1088. vpHeight = $w.height();
  1089. direction = direction ? direction : 'both';
  1090. clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;
  1091. if (typeof t.getBoundingClientRect === 'function') {
  1092. rec = t.getBoundingClientRect();
  1093. tViz = rec.top >= 0 && rec.top < vpHeight;
  1094. bViz = rec.bottom > 0 && rec.bottom <= vpHeight;
  1095. lViz = rec.left >= 0 && rec.left < vpWidth;
  1096. rViz = rec.right > 0 && rec.right <= vpWidth;
  1097. vVisible = partial ? tViz || bViz : tViz && bViz;
  1098. hVisible = partial ? lViz || rViz : lViz && rViz;
  1099. if (direction === 'both') {
  1100. return clientSize && vVisible && hVisible;
  1101. } else if (direction === 'vertical') {
  1102. return clientSize && vVisible;
  1103. } else if (direction === 'horizontal') {
  1104. return clientSize && hVisible;
  1105. }
  1106. } else {
  1107. viewTop = $w.scrollTop();
  1108. viewBottom = viewTop + vpHeight;
  1109. viewLeft = $w.scrollLeft();
  1110. viewRight = viewLeft + vpWidth;
  1111. offset = $t.offset();
  1112. _top = offset.top;
  1113. _bottom = _top + $t.height();
  1114. _left = offset.left;
  1115. _right = _left + $t.width();
  1116. compareTop = partial === true ? _bottom : _top;
  1117. compareBottom = partial === true ? _top : _bottom;
  1118. compareLeft = partial === true ? _right : _left;
  1119. compareRight = partial === true ? _left : _right;
  1120. if (direction === 'both') {
  1121. return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
  1122. } else if (direction === 'vertical') {
  1123. return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
  1124. } else if (direction === 'horizontal') {
  1125. return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
  1126. }
  1127. }
  1128. };
  1129. return ZammadChat;
  1130. })(Base);
  1131. return window.ZammadChat = ZammadChat;
  1132. })(window.jQuery, window);
  1133. if (!window.zammadChatTemplates) {
  1134. window.zammadChatTemplates = {};
  1135. }
  1136. window.zammadChatTemplates["agent"] = function (__obj) {
  1137. if (!__obj) __obj = {};
  1138. var __out = [], __capture = function(callback) {
  1139. var out = __out, result;
  1140. __out = [];
  1141. callback.call(this);
  1142. result = __out.join('');
  1143. __out = out;
  1144. return __safe(result);
  1145. }, __sanitize = function(value) {
  1146. if (value && value.ecoSafe) {
  1147. return value;
  1148. } else if (typeof value !== 'undefined' && value != null) {
  1149. return __escape(value);
  1150. } else {
  1151. return '';
  1152. }
  1153. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1154. __safe = __obj.safe = function(value) {
  1155. if (value && value.ecoSafe) {
  1156. return value;
  1157. } else {
  1158. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1159. var result = new String(value);
  1160. result.ecoSafe = true;
  1161. return result;
  1162. }
  1163. };
  1164. if (!__escape) {
  1165. __escape = __obj.escape = function(value) {
  1166. return ('' + value)
  1167. .replace(/&/g, '&amp;')
  1168. .replace(/</g, '&lt;')
  1169. .replace(/>/g, '&gt;')
  1170. .replace(/"/g, '&quot;');
  1171. };
  1172. }
  1173. (function() {
  1174. (function() {
  1175. if (this.agent.avatar) {
  1176. __out.push('\n<img class="zammad-chat-agent-avatar" src="');
  1177. __out.push(__sanitize(this.agent.avatar));
  1178. __out.push('">\n');
  1179. }
  1180. __out.push('\n<span class="zammad-chat-agent-sentence">\n <span class="zammad-chat-agent-name">');
  1181. __out.push(__sanitize(this.agent.name));
  1182. __out.push('</span>\n</span>');
  1183. }).call(this);
  1184. }).call(__obj);
  1185. __obj.safe = __objSafe, __obj.escape = __escape;
  1186. return __out.join('');
  1187. };
  1188. /*!
  1189. * ----------------------------------------------------------------------------
  1190. * "THE BEER-WARE LICENSE" (Revision 42):
  1191. * <jevin9@gmail.com> wrote this file. As long as you retain this notice you
  1192. * can do whatever you want with this stuff. If we meet some day, and you think
  1193. * this stuff is worth it, you can buy me a beer in return. Jevin O. Sewaruth
  1194. * ----------------------------------------------------------------------------
  1195. *
  1196. * Autogrow Textarea Plugin Version v3.0
  1197. * http://www.technoreply.com/autogrow-textarea-plugin-3-0
  1198. *
  1199. * THIS PLUGIN IS DELIVERD ON A PAY WHAT YOU WHANT BASIS. IF THE PLUGIN WAS USEFUL TO YOU, PLEASE CONSIDER BUYING THE PLUGIN HERE :
  1200. * https://sites.fastspring.com/technoreply/instant/autogrowtextareaplugin
  1201. *
  1202. * Date: October 15, 2012
  1203. *
  1204. * Zammad modification: remove overflow:hidden when maximum height is reached
  1205. *
  1206. */
  1207. jQuery.fn.autoGrow = function(options) {
  1208. return this.each(function() {
  1209. var settings = jQuery.extend({
  1210. extraLine: true,
  1211. }, options);
  1212. var createMirror = function(textarea) {
  1213. jQuery(textarea).after('<div class="autogrow-textarea-mirror"></div>');
  1214. return jQuery(textarea).next('.autogrow-textarea-mirror')[0];
  1215. }
  1216. var sendContentToMirror = function (textarea) {
  1217. mirror.innerHTML = String(textarea.value)
  1218. .replace(/&/g, '&amp;')
  1219. .replace(/"/g, '&quot;')
  1220. .replace(/'/g, '&#39;')
  1221. .replace(/</g, '&lt;')
  1222. .replace(/>/g, '&gt;')
  1223. .replace(/ /g, '&nbsp;')
  1224. .replace(/\n/g, '<br />') +
  1225. (settings.extraLine? '.<br/>.' : '')
  1226. ;
  1227. if (jQuery(textarea).height() != jQuery(mirror).height()) {
  1228. jQuery(textarea).height(jQuery(mirror).height());
  1229. var maxHeight = parseInt(jQuery(textarea).css('max-height'), 10);
  1230. var overflow = jQuery(mirror).height() > maxHeight ? '' : 'hidden'
  1231. jQuery(textarea).css('overflow', overflow);
  1232. }
  1233. }
  1234. var growTextarea = function () {
  1235. sendContentToMirror(this);
  1236. }
  1237. // Create a mirror
  1238. var mirror = createMirror(this);
  1239. // Style the mirror
  1240. mirror.style.display = 'none';
  1241. mirror.style.wordWrap = 'break-word';
  1242. mirror.style.whiteSpace = 'normal';
  1243. mirror.style.padding = jQuery(this).css('paddingTop') + ' ' +
  1244. jQuery(this).css('paddingRight') + ' ' +
  1245. jQuery(this).css('paddingBottom') + ' ' +
  1246. jQuery(this).css('paddingLeft');
  1247. mirror.style.width = jQuery(this).css('width');
  1248. mirror.style.fontFamily = jQuery(this).css('font-family');
  1249. mirror.style.fontSize = jQuery(this).css('font-size');
  1250. mirror.style.lineHeight = jQuery(this).css('line-height');
  1251. // Style the textarea
  1252. this.style.overflow = "hidden";
  1253. this.style.minHeight = this.rows+"em";
  1254. // Bind the textarea's event
  1255. this.onkeyup = growTextarea;
  1256. // Fire the event for text already present
  1257. sendContentToMirror(this);
  1258. });
  1259. };
  1260. if (!window.zammadChatTemplates) {
  1261. window.zammadChatTemplates = {};
  1262. }
  1263. window.zammadChatTemplates["chat"] = function (__obj) {
  1264. if (!__obj) __obj = {};
  1265. var __out = [], __capture = function(callback) {
  1266. var out = __out, result;
  1267. __out = [];
  1268. callback.call(this);
  1269. result = __out.join('');
  1270. __out = out;
  1271. return __safe(result);
  1272. }, __sanitize = function(value) {
  1273. if (value && value.ecoSafe) {
  1274. return value;
  1275. } else if (typeof value !== 'undefined' && value != null) {
  1276. return __escape(value);
  1277. } else {
  1278. return '';
  1279. }
  1280. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1281. __safe = __obj.safe = function(value) {
  1282. if (value && value.ecoSafe) {
  1283. return value;
  1284. } else {
  1285. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1286. var result = new String(value);
  1287. result.ecoSafe = true;
  1288. return result;
  1289. }
  1290. };
  1291. if (!__escape) {
  1292. __escape = __obj.escape = function(value) {
  1293. return ('' + value)
  1294. .replace(/&/g, '&amp;')
  1295. .replace(/</g, '&lt;')
  1296. .replace(/>/g, '&gt;')
  1297. .replace(/"/g, '&quot;');
  1298. };
  1299. }
  1300. (function() {
  1301. (function() {
  1302. __out.push('<div class="zammad-chat');
  1303. if (this.flat) {
  1304. __out.push(__sanitize(' zammad-chat--flat'));
  1305. }
  1306. __out.push('"');
  1307. if (this.fontSize) {
  1308. __out.push(__sanitize(" style='font-size: " + this.fontSize + "'"));
  1309. }
  1310. __out.push('>\n <div class="zammad-chat-header js-chat-open"');
  1311. if (this.background) {
  1312. __out.push(__sanitize(" style='background: " + this.background + "'"));
  1313. }
  1314. __out.push('>\n <div class="zammad-chat-header-controls js-chat-toggle">\n <span class="zammad-chat-agent-status zammad-chat-is-hidden" data-status="online"></span>\n <span class="zammad-chat-header-icon">\n <svg class="zammad-chat-header-icon-open" width="13" height="7" viewBox="0 0 13 7"><path d="M10.807 7l1.4-1.428-5-4.9L6.5-.02l-.7.7-4.9 4.9 1.414 1.413L6.5 2.886 10.807 7z" fill-rule="evenodd"/></svg>\n <svg class="zammad-chat-header-icon-close" width="13" height="13" viewBox="0 0 13 13"><path d="m2.241.12l-2.121 2.121 4.243 4.243-4.243 4.243 2.121 2.121 4.243-4.243 4.243 4.243 2.121-2.121-4.243-4.243 4.243-4.243-2.121-2.121-4.243 4.243-4.243-4.243" fill-rule="evenodd"/></svg>\n </span>\n </div>\n <div class="zammad-chat-agent zammad-chat-is-hidden">\n </div>\n <div class="zammad-chat-welcome">\n <svg class="zammad-chat-icon" viewBox="0 0 24 24" width="24" height="24"><path d="M2 5C2 4 3 3 4 3h16c1 0 2 1 2 2v10C22 16 21 17 20 17H4C3 17 2 16 2 15V5zM12 17l6 4v-4h-6z"/></svg>\n <span class="zammad-chat-welcome-text">');
  1315. __out.push(this.T(this.title));
  1316. __out.push('</span>\n </div>\n </div>\n <div class="zammad-chat-modal"></div>\n <div class="zammad-chat-body"></div>\n <form class="zammad-chat-controls">\n <textarea class="zammad-chat-input" rows="1" placeholder="');
  1317. __out.push(this.T('Compose your message...'));
  1318. __out.push('"></textarea>\n <button type="submit" class="zammad-chat-button zammad-chat-send"');
  1319. if (this.background) {
  1320. __out.push(__sanitize(" style='background: " + this.background + "'"));
  1321. }
  1322. __out.push('>');
  1323. __out.push(this.T('Send'));
  1324. __out.push('</button>\n </form>\n</div>');
  1325. }).call(this);
  1326. }).call(__obj);
  1327. __obj.safe = __objSafe, __obj.escape = __escape;
  1328. return __out.join('');
  1329. };
  1330. if (!window.zammadChatTemplates) {
  1331. window.zammadChatTemplates = {};
  1332. }
  1333. window.zammadChatTemplates["customer_timeout"] = function (__obj) {
  1334. if (!__obj) __obj = {};
  1335. var __out = [], __capture = function(callback) {
  1336. var out = __out, result;
  1337. __out = [];
  1338. callback.call(this);
  1339. result = __out.join('');
  1340. __out = out;
  1341. return __safe(result);
  1342. }, __sanitize = function(value) {
  1343. if (value && value.ecoSafe) {
  1344. return value;
  1345. } else if (typeof value !== 'undefined' && value != null) {
  1346. return __escape(value);
  1347. } else {
  1348. return '';
  1349. }
  1350. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1351. __safe = __obj.safe = function(value) {
  1352. if (value && value.ecoSafe) {
  1353. return value;
  1354. } else {
  1355. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1356. var result = new String(value);
  1357. result.ecoSafe = true;
  1358. return result;
  1359. }
  1360. };
  1361. if (!__escape) {
  1362. __escape = __obj.escape = function(value) {
  1363. return ('' + value)
  1364. .replace(/&/g, '&amp;')
  1365. .replace(/</g, '&lt;')
  1366. .replace(/>/g, '&gt;')
  1367. .replace(/"/g, '&quot;');
  1368. };
  1369. }
  1370. (function() {
  1371. (function() {
  1372. __out.push('<div class="zammad-chat-modal-text">\n ');
  1373. if (this.agent) {
  1374. __out.push('\n ');
  1375. __out.push(this.T('Since you didn\'t respond in the last %s minutes your conversation with <strong>%s</strong> got closed.', this.delay, this.agent));
  1376. __out.push('\n ');
  1377. } else {
  1378. __out.push('\n ');
  1379. __out.push(this.T('Since you didn\'t respond in the last %s minutes your conversation got closed.', this.delay));
  1380. __out.push('\n ');
  1381. }
  1382. __out.push('\n <br>\n <div class="zammad-chat-button js-restart"');
  1383. if (this.background) {
  1384. __out.push(__sanitize(" style='background: " + this.background + "'"));
  1385. }
  1386. __out.push('>');
  1387. __out.push(this.T('Start new conversation'));
  1388. __out.push('</div>\n</div>');
  1389. }).call(this);
  1390. }).call(__obj);
  1391. __obj.safe = __objSafe, __obj.escape = __escape;
  1392. return __out.join('');
  1393. };
  1394. if (!window.zammadChatTemplates) {
  1395. window.zammadChatTemplates = {};
  1396. }
  1397. window.zammadChatTemplates["loader"] = function (__obj) {
  1398. if (!__obj) __obj = {};
  1399. var __out = [], __capture = function(callback) {
  1400. var out = __out, result;
  1401. __out = [];
  1402. callback.call(this);
  1403. result = __out.join('');
  1404. __out = out;
  1405. return __safe(result);
  1406. }, __sanitize = function(value) {
  1407. if (value && value.ecoSafe) {
  1408. return value;
  1409. } else if (typeof value !== 'undefined' && value != null) {
  1410. return __escape(value);
  1411. } else {
  1412. return '';
  1413. }
  1414. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1415. __safe = __obj.safe = function(value) {
  1416. if (value && value.ecoSafe) {
  1417. return value;
  1418. } else {
  1419. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1420. var result = new String(value);
  1421. result.ecoSafe = true;
  1422. return result;
  1423. }
  1424. };
  1425. if (!__escape) {
  1426. __escape = __obj.escape = function(value) {
  1427. return ('' + value)
  1428. .replace(/&/g, '&amp;')
  1429. .replace(/</g, '&lt;')
  1430. .replace(/>/g, '&gt;')
  1431. .replace(/"/g, '&quot;');
  1432. };
  1433. }
  1434. (function() {
  1435. (function() {
  1436. __out.push('<span class="zammad-chat-loading-animation">\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n</span>\n<span class="zammad-chat-modal-text">');
  1437. __out.push(this.T('Connecting'));
  1438. __out.push('</span>');
  1439. }).call(this);
  1440. }).call(__obj);
  1441. __obj.safe = __objSafe, __obj.escape = __escape;
  1442. return __out.join('');
  1443. };
  1444. if (!window.zammadChatTemplates) {
  1445. window.zammadChatTemplates = {};
  1446. }
  1447. window.zammadChatTemplates["message"] = function (__obj) {
  1448. if (!__obj) __obj = {};
  1449. var __out = [], __capture = function(callback) {
  1450. var out = __out, result;
  1451. __out = [];
  1452. callback.call(this);
  1453. result = __out.join('');
  1454. __out = out;
  1455. return __safe(result);
  1456. }, __sanitize = function(value) {
  1457. if (value && value.ecoSafe) {
  1458. return value;
  1459. } else if (typeof value !== 'undefined' && value != null) {
  1460. return __escape(value);
  1461. } else {
  1462. return '';
  1463. }
  1464. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1465. __safe = __obj.safe = function(value) {
  1466. if (value && value.ecoSafe) {
  1467. return value;
  1468. } else {
  1469. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1470. var result = new String(value);
  1471. result.ecoSafe = true;
  1472. return result;
  1473. }
  1474. };
  1475. if (!__escape) {
  1476. __escape = __obj.escape = function(value) {
  1477. return ('' + value)
  1478. .replace(/&/g, '&amp;')
  1479. .replace(/</g, '&lt;')
  1480. .replace(/>/g, '&gt;')
  1481. .replace(/"/g, '&quot;');
  1482. };
  1483. }
  1484. (function() {
  1485. (function() {
  1486. __out.push('<div class="zammad-chat-message zammad-chat-message--');
  1487. __out.push(__sanitize(this.from));
  1488. __out.push(__sanitize(this.unreadClass));
  1489. __out.push('">\n <span class="zammad-chat-message-body"');
  1490. if (this.background && this.from === 'customer') {
  1491. __out.push(__sanitize(" style='background: " + this.background + "'"));
  1492. }
  1493. __out.push('>');
  1494. __out.push(this.message);
  1495. __out.push('</span>\n</div>');
  1496. }).call(this);
  1497. }).call(__obj);
  1498. __obj.safe = __objSafe, __obj.escape = __escape;
  1499. return __out.join('');
  1500. };
  1501. if (!window.zammadChatTemplates) {
  1502. window.zammadChatTemplates = {};
  1503. }
  1504. window.zammadChatTemplates["status"] = function (__obj) {
  1505. if (!__obj) __obj = {};
  1506. var __out = [], __capture = function(callback) {
  1507. var out = __out, result;
  1508. __out = [];
  1509. callback.call(this);
  1510. result = __out.join('');
  1511. __out = out;
  1512. return __safe(result);
  1513. }, __sanitize = function(value) {
  1514. if (value && value.ecoSafe) {
  1515. return value;
  1516. } else if (typeof value !== 'undefined' && value != null) {
  1517. return __escape(value);
  1518. } else {
  1519. return '';
  1520. }
  1521. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1522. __safe = __obj.safe = function(value) {
  1523. if (value && value.ecoSafe) {
  1524. return value;
  1525. } else {
  1526. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1527. var result = new String(value);
  1528. result.ecoSafe = true;
  1529. return result;
  1530. }
  1531. };
  1532. if (!__escape) {
  1533. __escape = __obj.escape = function(value) {
  1534. return ('' + value)
  1535. .replace(/&/g, '&amp;')
  1536. .replace(/</g, '&lt;')
  1537. .replace(/>/g, '&gt;')
  1538. .replace(/"/g, '&quot;');
  1539. };
  1540. }
  1541. (function() {
  1542. (function() {
  1543. __out.push('<div class="zammad-chat-status">\n <div class="zammad-chat-status-inner">\n ');
  1544. __out.push(this.status);
  1545. __out.push('\n </div>\n</div>');
  1546. }).call(this);
  1547. }).call(__obj);
  1548. __obj.safe = __objSafe, __obj.escape = __escape;
  1549. return __out.join('');
  1550. };
  1551. if (!window.zammadChatTemplates) {
  1552. window.zammadChatTemplates = {};
  1553. }
  1554. window.zammadChatTemplates["timestamp"] = function (__obj) {
  1555. if (!__obj) __obj = {};
  1556. var __out = [], __capture = function(callback) {
  1557. var out = __out, result;
  1558. __out = [];
  1559. callback.call(this);
  1560. result = __out.join('');
  1561. __out = out;
  1562. return __safe(result);
  1563. }, __sanitize = function(value) {
  1564. if (value && value.ecoSafe) {
  1565. return value;
  1566. } else if (typeof value !== 'undefined' && value != null) {
  1567. return __escape(value);
  1568. } else {
  1569. return '';
  1570. }
  1571. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1572. __safe = __obj.safe = function(value) {
  1573. if (value && value.ecoSafe) {
  1574. return value;
  1575. } else {
  1576. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1577. var result = new String(value);
  1578. result.ecoSafe = true;
  1579. return result;
  1580. }
  1581. };
  1582. if (!__escape) {
  1583. __escape = __obj.escape = function(value) {
  1584. return ('' + value)
  1585. .replace(/&/g, '&amp;')
  1586. .replace(/</g, '&lt;')
  1587. .replace(/>/g, '&gt;')
  1588. .replace(/"/g, '&quot;');
  1589. };
  1590. }
  1591. (function() {
  1592. (function() {
  1593. __out.push('<div class="zammad-chat-timestamp"><strong>');
  1594. __out.push(__sanitize(this.label));
  1595. __out.push('</strong> ');
  1596. __out.push(__sanitize(this.time));
  1597. __out.push('</div>');
  1598. }).call(this);
  1599. }).call(__obj);
  1600. __obj.safe = __objSafe, __obj.escape = __escape;
  1601. return __out.join('');
  1602. };
  1603. if (!window.zammadChatTemplates) {
  1604. window.zammadChatTemplates = {};
  1605. }
  1606. window.zammadChatTemplates["typingIndicator"] = function (__obj) {
  1607. if (!__obj) __obj = {};
  1608. var __out = [], __capture = function(callback) {
  1609. var out = __out, result;
  1610. __out = [];
  1611. callback.call(this);
  1612. result = __out.join('');
  1613. __out = out;
  1614. return __safe(result);
  1615. }, __sanitize = function(value) {
  1616. if (value && value.ecoSafe) {
  1617. return value;
  1618. } else if (typeof value !== 'undefined' && value != null) {
  1619. return __escape(value);
  1620. } else {
  1621. return '';
  1622. }
  1623. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1624. __safe = __obj.safe = function(value) {
  1625. if (value && value.ecoSafe) {
  1626. return value;
  1627. } else {
  1628. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1629. var result = new String(value);
  1630. result.ecoSafe = true;
  1631. return result;
  1632. }
  1633. };
  1634. if (!__escape) {
  1635. __escape = __obj.escape = function(value) {
  1636. return ('' + value)
  1637. .replace(/&/g, '&amp;')
  1638. .replace(/</g, '&lt;')
  1639. .replace(/>/g, '&gt;')
  1640. .replace(/"/g, '&quot;');
  1641. };
  1642. }
  1643. (function() {
  1644. (function() {
  1645. __out.push('<div class="zammad-chat-message zammad-chat-message--typing zammad-chat-message--agent">\n <span class="zammad-chat-message-body">\n <span class="zammad-chat-loading-animation">\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n </span>\n </span>\n</div>');
  1646. }).call(this);
  1647. }).call(__obj);
  1648. __obj.safe = __objSafe, __obj.escape = __escape;
  1649. return __out.join('');
  1650. };
  1651. if (!window.zammadChatTemplates) {
  1652. window.zammadChatTemplates = {};
  1653. }
  1654. window.zammadChatTemplates["waiting"] = function (__obj) {
  1655. if (!__obj) __obj = {};
  1656. var __out = [], __capture = function(callback) {
  1657. var out = __out, result;
  1658. __out = [];
  1659. callback.call(this);
  1660. result = __out.join('');
  1661. __out = out;
  1662. return __safe(result);
  1663. }, __sanitize = function(value) {
  1664. if (value && value.ecoSafe) {
  1665. return value;
  1666. } else if (typeof value !== 'undefined' && value != null) {
  1667. return __escape(value);
  1668. } else {
  1669. return '';
  1670. }
  1671. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1672. __safe = __obj.safe = function(value) {
  1673. if (value && value.ecoSafe) {
  1674. return value;
  1675. } else {
  1676. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1677. var result = new String(value);
  1678. result.ecoSafe = true;
  1679. return result;
  1680. }
  1681. };
  1682. if (!__escape) {
  1683. __escape = __obj.escape = function(value) {
  1684. return ('' + value)
  1685. .replace(/&/g, '&amp;')
  1686. .replace(/</g, '&lt;')
  1687. .replace(/>/g, '&gt;')
  1688. .replace(/"/g, '&quot;');
  1689. };
  1690. }
  1691. (function() {
  1692. (function() {
  1693. __out.push('<div class="zammad-chat-modal-text">\n <span class="zammad-chat-loading-animation">\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n </span>\n ');
  1694. __out.push(this.T('All colleagues are busy.'));
  1695. __out.push('<br>\n ');
  1696. __out.push(this.T('You are on waiting list position <strong>%s</strong>.', this.position));
  1697. __out.push('\n</div>');
  1698. }).call(this);
  1699. }).call(__obj);
  1700. __obj.safe = __objSafe, __obj.escape = __escape;
  1701. return __out.join('');
  1702. };
  1703. if (!window.zammadChatTemplates) {
  1704. window.zammadChatTemplates = {};
  1705. }
  1706. window.zammadChatTemplates["waiting_list_timeout"] = function (__obj) {
  1707. if (!__obj) __obj = {};
  1708. var __out = [], __capture = function(callback) {
  1709. var out = __out, result;
  1710. __out = [];
  1711. callback.call(this);
  1712. result = __out.join('');
  1713. __out = out;
  1714. return __safe(result);
  1715. }, __sanitize = function(value) {
  1716. if (value && value.ecoSafe) {
  1717. return value;
  1718. } else if (typeof value !== 'undefined' && value != null) {
  1719. return __escape(value);
  1720. } else {
  1721. return '';
  1722. }
  1723. }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
  1724. __safe = __obj.safe = function(value) {
  1725. if (value && value.ecoSafe) {
  1726. return value;
  1727. } else {
  1728. if (!(typeof value !== 'undefined' && value != null)) value = '';
  1729. var result = new String(value);
  1730. result.ecoSafe = true;
  1731. return result;
  1732. }
  1733. };
  1734. if (!__escape) {
  1735. __escape = __obj.escape = function(value) {
  1736. return ('' + value)
  1737. .replace(/&/g, '&amp;')
  1738. .replace(/</g, '&lt;')
  1739. .replace(/>/g, '&gt;')
  1740. .replace(/"/g, '&quot;');
  1741. };
  1742. }
  1743. (function() {
  1744. (function() {
  1745. __out.push('<div class="zammad-chat-modal-text">\n ');
  1746. __out.push(this.T('We are sorry, it takes longer as expected to get an empty slot. Please try again later or send us an email. Thank you!'));
  1747. __out.push('\n <br>\n <div class="zammad-chat-button js-restart"');
  1748. if (this.background) {
  1749. __out.push(__sanitize(" style='background: " + this.background + "'"));
  1750. }
  1751. __out.push('>');
  1752. __out.push(this.T('Start new conversation'));
  1753. __out.push('</div>\n</div>');
  1754. }).call(this);
  1755. }).call(__obj);
  1756. __obj.safe = __objSafe, __obj.escape = __escape;
  1757. return __out.join('');
  1758. };