PageSourceSearch

https://webchat.epic.com.cy:3000/client/fidchat.js

js epic.com.cy collected 2026-10-02 03:00:32 UTC 58,874 bytes, 1,602 lines download raw bytes

1/****************************
2* Jusan Fidelity Chat
3* Copyright (c) 2023
4*
5* Jusan, S.A.
6* Vivero 5.
7* 28040 - Madrid
8* Spain
9*
10* www.jusan.es
11* [email protected]
12****************************/
13
14var CHAT_WINDOW_OPENED_HEIGHT = 245;
15const CHAT_WINDOW_OPENED_HEIGHT_OPENED = 580;
16const CHAT_WINDOW_CLOSED_HEIGHT = 0;
17const CHAT_WINDOW_TRANSITION_SPEED = 1; //bigger number = slower animation
18
19var j = function (el) { return document.querySelector(el); },
20    ua = window.navigator.userAgent,
21    isIE = /MSIE|Trident|Edge/.test(ua),
22    socket = null,
23    email = true,
24    phone = false,
25    username = true,
26    anonymous = false,
27    agentUnavailable = false,
28    welcome = false,
29    colorTheme = "#45b2eb",
30    textColorTheme = "white",
31    dataStartTextColor = colorTheme,//"black";
32    buttonType = "short", //long, short
33    uploadFiles = false,
34
35    invitationMessage = "Chat with us",
36    insertName = "Name required",
37    insertEmail = "Email required",
38    insertPhone = "Phone required",
39    //insertLastName = "Lastname required",
40    insertContractNumber = "Contract number",
41    insertSubject = "Subject",
42    insertDepartment = "Department",
43    waitMessage = "Start",
44    sendChat = "Receive chat by email",
45    sendMessage = "Send a message...",
46    server = isIE ? j("#fidchat").src.split("/client")[0] : new URL(document.currentScript.src).origin,
47    fieldsIds = {
48        "phone": "Teléfono",
49        "name": "Nombre",
50        "lastname": "Apellidos"
51    },
52    qualityTitle = "Quality poll",
53    group = "",
54    qualityQuestions = [],
55    questionsShown = false,
56    questionsSent = false,
57    phoneRequired = false,
58    emailRequired = false,
59    nameRequired = false,
60    sendEmailToClient = false,
61    autoOpen = false,
62    showNames = false,
63    showEmojis = false,
64    typingText = "Typing...",
65    qualitySendText = "Send",
66    sendButton = true,
67    closeTimeout = 10000,
68    isBlank = function (obj) {
69        if (!obj || obj.trim() === "") return true;
70        if (obj.length && obj.length > 0) return false;
71        for (var prop in obj) if (obj[prop]) return false;
72        return true;
73    },
74    jPOST = function (url, data, callBack, async) {
75        var request = new XMLHttpRequest();
76        request.open('POST', url, async);
77        request.setRequestHeader('Accept', '*/*');
78        request.setRequestHeader('Content-type', 'application/json');
79        request.onreadystatechange = function () {
80            if (request.readyState == 4 && request.status == 200) {
81                callBack(request.responseText);
82            } else {
83                callBack(false);
84            }
85        };
86        request.send(data);
87    },
88    Guid = function () {
89        function part() {
90            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1).toUpperCase();
91        };
92
93        return {
94            NewGuid: function () { return (part() + part() + "-" + part() + "-" + part() + "-" + part() + "-" + part() + part() + part()); },
95            Empty: "00000000-0000-0000-0000-000000000000"
96        };
97    }(),
98    jUpload = function (callBack) {
99        var form = new FormData(),
100            file = j("#juploadfile").files[0],
101            request = new XMLHttpRequest();
102        j("#jprogress").style.display = "inline-block";
103        form.append("file", file);
104        request.upload.addEventListener("progress", jProgressHandler, false);
105        request.onreadystatechange = function () {
106            if (request.readyState == 4 && request.status == 200) {
107                callBack(request.responseText);
108            } else {
109                callBack(false);
110            }
111        };
112        request.open('POST', server + "/uploadfile", true);
113        request.send(form);
114    },
115    jProgressHandler = function (event) {
116        var percent = (event.loaded / event.total) * 100;
117        j("#jprogress").value = Math.round(percent);
118    },
119    isMobile = (function (a) { return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
119sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)) })(navigator.userAgent || navigator.vendor || window.opera)
120
121function sendEmail() {
122
123    if (j(".date-message") == null && j(".jus-window").clientHeight > 100) {
124
125        var pane = j('.scroll-pane'),
126            messageContainer = "fec" + Date.now(),
127            $divDate = document.createElement("div"),
128            $span = document.createElement("span"),
129            $divClear = document.createElement("div");
130
131        $divDate.id = messageContainer;
132        $divDate.classList.add('date-message');
133        $span.classList.add("text");
134        $span.textContent = sendChat;
135        $divClear.classList.add("jus-clear");
136        $divDate.appendChild($span);
137        pane.appendChild($divDate);
138        pane.appendChild($divClear);
139
140        if (isIE) {
141            pane.scrollTop = pane.scrollHeight;
142        } else {
143            pane.scrollTo(0, pane.scrollHeight);
144        }
145
146        $divDate.addEventListener("click", function () {
147            jPOST(
148                server + "/sendEmail",
149                JSON.stringify({ chatGuid: getCookie("faChatGuid"), email: j("#email").value }),
150                function (res) {
151                    if (res)
152                        closeChat();
153                },
154                true
155            );
156        });
157    }
158    else {
159        closeChat();
160    }
161};
162
163function initChat() {
164
165    var token = getCookie("faChatToken") != null ? getCookie("faChatToken") : Guid.NewGuid(),
166        name = "",
167        email = "",
168        phoneVal = "",
169        fields = null;
170
171    if (j("#email"))
172        email = j("#email").value;
173    if (j("#name"))
174        name = getCookie("fcChatName") != null && getCookie("fcChatName").trim() != "" ? getCookie("fcChatName") : j("#name").value;
175    if (j("#phone"))
176        phoneVal = j("#phone").value;
177
178    socket = io.connect(server, { query: { token: token } });
179    if (anonymous) {
180        name = "unknown";
181        email = "unknown@fidelity." + Guid.NewGuid() + ".fc";
182    }
183
184    setCookieFidelity("faChatToken", token);
185    setCookieFidelity("fcChatName", name);
186
187    var fieldsValues = j(".jus-window").querySelectorAll(".jus-user-input");
188
189    if (fieldsValues != null && fieldsValues.length > 0) {
190        fields = [];
191        fieldsValues.forEach(x => {
192            var id = fieldsIds[x.id];
193            fields.push({
194                id: id || x.id,
195                type: x.type,
196                value: x.value
197            });
198        });
199    }
200
201    socket.on("connect", function (socket) {
202        if (!welcome) {
203            jPOST(
204                server + "/initChat",
205                JSON.stringify({ id: token, name: name, email: email, group: group, phone: phoneVal, language: window.navigator.language.substr(0, 2), fields: fields, color: colorTheme }),
206                function (res) {
207                    if (res) {
208                        initializeSockets(token);
209                    } else {
210                        window.email = false;
211                        setTimeout(x => {
212                            j(".jus-window-header .jus-close").click();
213                        }, closeTimeout);
214                    }
215                },
216                false
217            );
218        } else {
219            initializeSockets(token);
220        }
221    });
222};
223
224function drawMessage(message, agent, date, name) {
225
226    message = sanitizeHTML(message);
227
228    var pane = j('.scroll-pane'),
229        $div = document.createElement("div"),
230        $span = document.createElement("span"),
231        $divClear = document.createElement("div"),
232        $divDate = document.createElement("div");
233
234    if (agent)
235        message = parseLink(message, agent ? colorTheme : textColorTheme);
236
237    $divDate.classList.add(agent ? "jus-data-left" : "jus-data-right");
238    if (showNames) {
239        if (agent) {
240            $divDate.innerHTML = `${date.toLocaleDateString()} ${date.toLocaleTimeString()} <span style="color:${colorTheme};">${(name || "")}</span> `;
241        } else {
242            $divDate.innerHTML = `<span style="color:${colorTheme};">${(getCookie("fcChatName") || "")}</span> ${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
243        }
244    }
245    else {
246        $divDate.textContent = `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
247    }
248
249    $div.classList.add(agent ? "agent-message" : "user-message");
250    if (!agent) {
251        $div.style.backgroundColor = colorTheme;
252        $div.style.color = textColorTheme;
253    }
254    $span.classList.add("text");
255
256    if (agent)
257        $span.innerHTML = message;
258    else
259        $span.innerText = message;
260    
261    $divClear.classList.add("jus-clear");
262    $div.appendChild($span);
263    pane.appendChild($div);
264    pane.appendChild($divDate);
265    pane.appendChild($divClear);
266    setTimeout(function () {
267        if (isIE) {
268            pane.scrollTop = pane.scrollHeight;
269        } else {
270            pane.scrollTo(0, pane.scrollHeight);
271        }
272    }, 500);
273
274    document.getElementsByClassName("jus-agentstatus")[0].style.display = "inline-block";
275
276    Array.from(document.getElementsByClassName("j-menu-btn")).forEach(x => {
277        x.removeEventListener("click", writeButtonText);
278        x.addEventListener("click", writeButtonText);
279    });
280
281};
282
283function writeButtonText(e) {
284    if (e.target.dataset.render && e.target.dataset.render == 'true')
285        drawMessage(this.value, false, new Date(), "");
286
287    addUserNewMessage(this.value, false, "", this.innerText);
288}
289
290function addUserNewMessage(message, media, mediaType, buttonText) {
291    var token = getCookie("faChatToken"),
292        name = "",
293        email = "";
294
295    if (j("#email"))
296        email = j("#email").value
297    if (j("#name"))
298        name = j("#name").value;
299
300    var newMessage = {
301        id: token,
302        name: name,
303        fullname: name + " " + email,
304        text: message,
305        buttonText: buttonText,
306        date: null,
307        media: media,
308        mediaType: mediaType,
309        url: message
310    },
311        pane = j(".scroll-pane");
312
313
314    socket.emit('addUserNewMessage', newMessage);
315
316    if (isIE) {
317        pane.scrollTop = pane.scrollHeight;
318    } else {
319        pane.scrollTo(0, pane.scrollHeight);
320    }
321};
322
323function closeChatWindow(elem, callback) {
324    var height = parseInt(elem.style.height.replace("px", ""));
325    if (height > CHAT_WINDOW_CLOSED_HEIGHT) {
326        elem.style.overflowX = "";
327        elem.style.overflowY = "";
328        elem.style.overflow = "";
329        function frame() {
330            height -= 5;
331            elem.style.height = height + 'px'
332            if (height <= CHAT_WINDOW_CLOSED_HEIGHT) {
333                clearInterval(id)
334                callback();
335                elem.scrollTop = 0;
336            }
337        }
338        var id = setInterval(frame, CHAT_WINDOW_TRANSITION_SPEED)
339    } else {
340        callback();
341    }
342};
343
344function openChatWindow(elem, callback) {
345    var height = parseInt(elem.style.height.replace("px", ""));
346    var windowHeight = CHAT_WINDOW_OPENED_HEIGHT;
347
348    if (elem.style.height == CHAT_WINDOW_OPENED_HEIGHT + "px" || j("#jusanchat").style.display != "none")
349        windowHeight = CHAT_WINDOW_OPENED_HEIGHT_OPENED;
350
351    if (window.innerHeight < CHAT_WINDOW_OPENED_HEIGHT)
352        windowHeight = window.innerHeight;
353
354    if (height <= windowHeight) {
355        function frame() {
356            height += 5;
357            elem.style.height = height + 'px'
358            if (height >= windowHeight) {
359                clearInterval(id)
360                callback();
361                //elem.style.overflowY = "auto";
362            }
363        }
364        var id = setInterval(frame, CHAT_WINDOW_TRANSITION_SPEED)
365    } else {
366        callback();
367    }
368};
369
370function closeChat() {
371
372    if (!questionsSent)
373        saveQuestionQualityResults();
374
375    if (getCookie("faChatToken") != undefined && getCookie("faChatToken") != null) {
376        socket.emit('closeConversationClient', getCookie("faChatToken"));
377        removeCookie("faChatToken");
378        socket.close();
379    }
380    if (getCookie("fcChatName") != undefined && getCookie("fcChatName") != null) {
381        removeCookie("fcChatName");
382    }
383    var $divQuestions = j("#qualityQuestions"),
384        $divChat = j("#jusanchat");
385    $divQuestions.innerHTML = "";
386    $divQuestions.style.display = "none";
387    $divChat.style.display = "inline-block";
388    questionsShown = false;
389    agentUnavailable = false;
390    welcome = false;
391
392    j(".scroll-pane").innerHTML = "";
393
394    if (j("#name"))
395        j("#name").value = "";
396
397    if (j("#email"))
398        j("#email").value = "";
399
400
401    j(".jus-open-window-container").style.display = "inline-block";
402    j("#jusanchat").style.cssText = "display: none;";
403    j(".chat-text-input").setAttribute("readonly", "readonly");
404    if (j(".jus-wait") != null)
405        j(".jus-wait").remove();
406
407    closeChatWindow(j(".jus-window"), function () {
408        if (getCookie("faChatToken") != null) closeChat();
409        loginPage(true);
410    });
411};
412
413function initializeSockets(token) {
414
415    socket.off('recoverChats');
416    socket.off('updateUserUpdateConversation');
417    socket.off('unavailableAgent');
418    socket.off('availableAgent');
419    socket.off('qualityQuestions');
420    socket.off('conversationClosed');
421    socket.off('automaticMessages');
422
423    socket.on('recoverChats', function (data) {
424        if (data != null) {
425            recoverChats(data);
426        }
427    });
428
429    socket.on('updateUserUpdateConversation', function (message) {
430        pleaseWait(false);
431        agentUnavailable = false;
432        j(".chat-text-input").removeAttribute("readonly");
433        j(".chat-text-input").placeholder = sendMessage;
434        welcome = true;
435        if (!message.media) {
436            if (message.text)
437                drawMessage(message.text, true, new Date(), (message.name || ""));
438        } else {
439            drawMediaMessage(message, true, new Date(), (message.name || ""));
440        }
441    });
442
443    socket.on('unavailableAgent', function (message) {
444        if (!agentUnavailable) {
445            drawMessage(message, true, new Date(), (message.name || ""));
446        }
447        pleaseWait(false);
448    });
449
450    socket.on('availableAgent', function (message) {
451        pleaseWait(false);
452        agentUnavailable = false;
453        j(".chat-text-input").removeAttribute("readonly");
454        j(".chat-text-input").placeholder = sendMessage;
455        welcome = true;
456        qualityQuestions = message;
457    });
458    socket.on('qualityQuestions', function (message) {
459        qualityQuestions = message;
460    });
461
462    socket.on('conversationClosed', function (conversationId) {
463        j(".inputs-div input").disabled = true;
464        j(".chat-text-input").setAttribute("readonly", "readonly");
465        removeCookie("faChatToken");
466        socket.close();
467        if (!anonymous && email && sendEmailToClient) {
468            sendEmail();
469        } else if (qualityQuestions.length > 0 && !questionsShown) {
470            drawQuestions();
471        } else {
472            setTimeout(x => {
473                closeChat();
474            }, closeTimeout);
475
476        }
477
478    });
479
480    socket.on('connect_error', function (err) {
481        //closeChat();
482    });
483
484    socket.on('chatGuid', function (chatGuid) {
485        setCookieFidelity("faChatGuid", chatGuid);
486    });
487    socket.on('typingAgent', function (chatGuid) {
488        console.log('typingAgent');
489        var element = document.getElementsByClassName("jus-typing");
490        if (element.length > 0)
491            element[0].innerHTML = typingText;
492    });
493    socket.on('typingDoneAgent', function (chatGuid) {
494        var element = document.getElementsByClassName("jus-typing");
495        if (element.length > 0)
496            element[0].innerHTML = "";
497    });
498
499};
500
501function recoverChats(data) {
502
503    j(j(".chat-text-input").style.display != "none" ? ".chat-text-input" : "#name").focus();
504    j("#jusanchat").style.cssText = "display: inline-block;";
505    j(".chat-text-input").removeAttribute("readonly");
506    var height = CHAT_WINDOW_OPENED_HEIGHT_OPENED;
507    if (window.outerHeight < CHAT_WINDOW_OPENED_HEIGHT_OPENED)
508        height = window.outerHeight;
509    j(".jus-window").style.height = height + "px";
510    qualityQuestions = data.qualityQuestions;
511    loginPage(false);
512    data.messages = data.messages.sort(function (a, b) { return new Date(a.date) - new Date(b.date) });
513    data.messages.forEach(function (v, i) {
514        if ((v.text != null && v.text != "" && !v.media) || v.media) {
515
516            var date = new Date(v.date);
517
518            if (!v.media) {
519
520                drawMessage(v.text, v.type != "U", date, (v.name || ""))
521            } else {
522                drawMediaMessage(v, v.type != "U", new Date(), (v.name || ""));
523            }
524        }
525    });
526    calculateInputSize();
527};
528
529function loginPage(login) {
530    if (login) {
531        j(".chatlog").style.display = "none";
532        j(".chat-text-input").style.display = "none";
533        j(".jus-form").style.display = "inline-block";
534        if (username)
535            j("#name").focus();
536
537    } else {
538        j(".chatlog").style.display = "inline-block";
539        j(".chat-text-input").style.display = "inline-block";
540        j(".jus-form").style.display = "none";
541        var fctoken = getCookie("faChatToken");
542        if (fctoken == null)
543            initChat();
544    }
545};
546function sendMessageEv() {
547    var msj = j(".chat-text-input").value;
548    if (j("#juploadfile") != null && j("#juploadfile").files != null && j("#juploadfile").files.length > 0) {
549        jUpload(function (res) {
550            if (res) {
551                var message = JSON.parse(res);
552                drawMediaMessage(message, false, new Date(), "");
553                addUserNewMessage(message.url, true, message.mediaType);
554                document.getElementsByClassName("jus-cancel-file")[0].style.display = "none";
555                j(".chat-text-input").style.cursor = "";
556                if (document.getElementById('juploadfile'))
557                    document.getElementById('juploadfile').value = "";
558                j("#jprogress").style.display = "none";
559                j(".chat-text-input").value = "";
560            }
561        });
562    } else {
563        drawMessage(msj, false, new Date());
564        addUserNewMessage(msj);
565        j(".chat-text-input").value = "";
566    }
567
568}
569
570function pleaseWait(wait) {
571    var $divWait = document.createElement("div"),
572        dot1 = document.createElement("div"),
573        dot2 = document.createElement("div"),
574        dot3 = document.createElement("div"),
575        dot4 = document.createElement("div");
576    dot1.style.backgroundColor = colorTheme;
577    dot2.style.backgroundColor = colorTheme;
578    dot3.style.backgroundColor = colorTheme;
579    dot4.style.backgroundColor = colorTheme;
580    $divWait.className = "jus-wait";
581    $divWait.appendChild(dot1);
582    $divWait.appendChild(dot2);
583    $divWait.appendChild(dot3);
584    $divWait.appendChild(dot4);
585    if (wait) {
586        j(".jus-window-header").appendChild($divWait)
587    } else {
588        if (j(".jus-wait"))
589            j(".jus-window-header").removeChild(j(".jus-wait"))
590    }
591}
592
593function initializeChat(then) {
594
595    var fctoken = getCookie("faChatToken"),
596        $div = document.createElement("div"),
597        $divTitle = document.createElement("div"),
598        $divWindowHeader = document.createElement("div"),
599        $divOpen = document.createElement("div"),
600        $divChat = document.createElement("div"),
601        $form = document.createElement("form"),
602        $inputName = document.createElement("input"),
603        $inputEmail = document.createElement("input"),
604        $divButton = document.createElement("div"),
605        $button = document.createElement("button"),
606        $divChatlog = document.createElement("div"),
607        $inputMessage = document.createElement("input"),
608        $span = document.createElement("span"),
609        $divInvMsg = document.createElement("div"),
610        $buttonClose = document.createElement("button"),
611        $inputPhone = document.createElement("input"),
612        $divLogo2 = document.createElement("div"),
613
614        //$inputLastName = document.createElement("input"),
615
616        $divSchedule = document.createElement("div"),
617        $inputUploadHidden = document.createElement("input"),
618        $buttonUpload = document.createElement("button"),
619        $iCancelFile = document.createElement("span"),
620        $divQuestions = document.createElement("div"),
621        $progress = document.createElement("progress"),
622        $buttonMinimize = document.createElement("button"),
623        $divChatInputs = document.createElement("div"),
624        $i = document.createElement("i"),
625        $buttonEmoji = document.createElement("button"),
626        $iEmoji = document.createElement("i"),
627        $divEmojis = document.createElement("div"),
628        $divFilteredEmojis = document.createElement("div"),
629        $agentStatus = document.createElement("div"),
630        $spanTyping = document.createElement("span"),
631        $buttonSend = document.createElement("button"),
632        $iSend = document.createElement("i");
633
634    $spanTyping.classList.add("jus-typing");
635    $spanTyping.innerText = "";
636    $spanTyping.style.color = textColorTheme;
637    $divChatInputs.classList.add("inputs-div");
638
639    $i.classList.add("fa", "fa-paperclip");
640    $iEmoji.classList.add("fa", "fa-smile-o");
641    $inputUploadHidden.type = "file";
642    $inputUploadHidden.accept = ".jpg, .jpeg, .png, .xls, .csv, .xlsx, .pdf, .doc, .docx, .mp4, .mp3, .mpeg, .wav";
643    $inputUploadHidden.style.display = "none";
644    $inputUploadHidden.id = "juploadfile";
645
646    $buttonUpload.type = "button";
647    $buttonUpload.appendChild($i);
648    $buttonUpload.classList.add("jus-upload");
649    $buttonUpload.style.setProperty("color", colorTheme, "important");
650
651    $iSend.classList.add("fa", "fa-chevron-circle-right");
652
653    $buttonSend.type = "button";
654    $buttonSend.appendChild($iSend);
655    $buttonSend.classList.add("jus-send");
656    $buttonSend.style.setProperty("color", colorTheme, "important");
657
658    $agentStatus.classList.add("jus-agentstatus");
659    $agentStatus.style.display = "none";
660
661    //EMOJIS
662    $buttonEmoji.appendChild($iEmoji);
663    $buttonEmoji.classList.add("emojibutton");
664    $buttonEmoji.style.setProperty("color", colorTheme, "important");
665    $divEmojis.classList.add("emojilist");
666    $divEmojis.style.display = "none";
667
668    $divFilteredEmojis.classList.add("filteredemojis");
669
670    $buttonEmoji.addEventListener("click", function () {
671        $divEmojis.style.display = $divEmojis.style.display == "none" ? "block" : "none";
672        $divEmojis.firstChild.click();
673    });
674    var emojiCategories = emojiList.map(x => x.category).filter((value, index, self) => self.indexOf(value) === index);
675
676
677    emojiCategories.forEach(x => {
678
679        var category = emojiList.find(y => y.category == x),
680            $buttonCategory = document.createElement("button");
681
682        $buttonCategory.innerHTML = category.char;
683        $buttonCategory.setAttribute('data-category', x);
684        $buttonCategory.classList.add("emojicategory");
685        $buttonCategory.style.borderColor = colorTheme;
686
687        $divEmojis.appendChild($buttonCategory);
688
689        $buttonCategory.addEventListener("click", y => {
690            var selectetCateg = y.target.getAttribute("data-category"),
691                emojis = emojiList.filter(j => j.category == selectetCateg);
692
693            $divFilteredEmojis.innerHTML = "";
694            emojis.forEach(i => {
695                var emoji = document.createElement("button");
696
697                emoji.classList.add("emojifiltered");
698
699                emoji.innerHTML = i.char;
700                $divFilteredEmojis.appendChild(emoji);
701
702                emoji.addEventListener("click", z => {
703                    $inputMessage.value += z.target.innerHTML;
704                });
705
706            });
707        });
708    });
709
710    $divEmojis.appendChild($divFilteredEmojis);
711    //EMOJIS END
712    $divWindowHeader.style.display = "none";
713
714    $iCancelFile.classList.add("jus-cancel-file");
715    $iCancelFile.style.display = "none";
716    $iCancelFile.innerHTML = "&#10006;";
717
718    $inputUploadHidden.addEventListener("change", function () {
719        if (this.files != null && this.files.length > 0) {
720            var filesNames = "",
721                filesLength = this.files.length;
722
723            Array.from(this.files).forEach((v, i) => {
724                filesNames += v.name + (filesLength == (i + 1) ? "" : ", ");
725            });
726
727            $inputMessage.value = filesNames;
728            $iCancelFile.style.display = "inline-block";
729            $inputMessage.style.cursor = "not-allowed";
730            $inputMessage.focus();
731        }
732    });
733
734    $iCancelFile.addEventListener("click", function () {
735        $iCancelFile.style.display = "none";
736        $inputMessage.style.cursor = "";
737        $inputMessage.value = "";
738        if (document.getElementById('juploadfile'))
739            document.getElementById('juploadfile').value = "";
740    });
741
742    $buttonUpload.addEventListener("click", function () {
743        $inputUploadHidden.click();
744    });
745
746    $buttonSend.addEventListener("click", function () {
747        if (isBlank(j(".chat-text-input").value) == false) {
748            sendMessageEv();
749        }
750        $inputMessage.focus();
751    });
752
753    $progress.id = "jprogress";
754    $progress.classList.add("jprogress");
755    $progress.style.display = "none";
756
757    $span.id = "lengther";
758
759    $divOpen.id = "openwindow";
760    $divChat.id = "jusanchat";
761    $divChat.style.cssText = "display: none;";
762
763    $divQuestions.id = "qualityQuestions";
764    $divQuestions.style.cssText = "display: none;";
765
766    $inputName.id = "name";
767    $inputName.setAttribute("placeholder", insertName);
768    $inputName.setAttribute("type", "text");
769    $inputName.setAttribute("maxlength", 32);
770    if (nameRequired)
771        $inputName.setAttribute("required", "required");
772    $inputName.classList.add("jus-user-input");
773
774    $inputEmail.id = "email";
775    $inputEmail.setAttribute("placeholder", insertEmail);
776    $inputEmail.setAttribute("type", "email");
777    $inputEmail.setAttribute("maxlength", 128);
778    if (emailRequired)
779        $inputEmail.setAttribute("required", "required");
780    $inputEmail.classList.add("jus-user-input");
781
782    $inputPhone.id = "phone";
783    $inputPhone.setAttribute("placeholder", insertPhone);
784    $inputPhone.setAttribute("type", "tel");
785    $inputPhone.setAttribute("maxlength", 32);
786    if (phoneRequired)
787        $inputPhone.setAttribute("required", "required");
788    $inputPhone.classList.add("jus-user-input");
789
790    $button.id = "jusanstartchat";
791    $button.innerHTML = waitMessage; //"&#10147;" + 
792    $button.classList.add("jus-button");
793
794    $inputMessage.setAttribute("type", "text");
795    $inputMessage.setAttribute("readonly", "readonly");
796    $inputMessage.classList.add("chat-text-input");
797
798    $div.className = "jus-window"
799
800    $form.classList.add("jus-form");
801
802
803    $divButton.style.cssText = "";
804
805    $divChatlog.className = "scroll-pane chatlog";
806
807    $divTitle.className = "jus-open-window-container";
808    $divTitle.appendChild($divOpen);
809
810    $divWindowHeader.className = "jus-window-header";
811    $divWindowHeader.style.cssText = "display: none;";
812
813    $divInvMsg.className = "jus-invitation-message";
814    $divInvMsg.textContent = invitationMessage;
815    if (buttonType == "long") {
816        $divOpen.className = "openwindow2";
817        var $inv = document.createElement("div");
818        $inv.className = "jus-invitation-message jus-inv";
819        $inv.textContent = invitationMessage;
820        $inv.style.color = textColorTheme;
821        $divOpen.appendChild($inv);
822    }
823
824    $divInvMsg.style.color = textColorTheme;
825    $divOpen.style.backgroundColor = colorTheme;
826    $divWindowHeader.style.backgroundColor = colorTheme;
827    $divLogo2.style.backgroundColor = colorTheme;
828    $button.style.color = dataStartTextColor;
829
830
831    $buttonClose.className = "jus-close";
832    $buttonClose.innerHTML = "&times;";
833    $buttonMinimize.className = "jus-minimize";
834    $buttonMinimize.innerHTML = "&minus;";
835
836    $buttonClose.style.color = textColorTheme;
837    $buttonMinimize.style.color = textColorTheme;
838
839    $divLogo2.className = "jus-logo2";
840
841    // $inputLastName.id = "lastname";
842    // $inputLastName.setAttribute("placeholder", insertLastName);
843    // $inputLastName.setAttribute("type", "text");
844    // $inputLastName.setAttribute("required", "required");
845    // $inputLastName.classList.add("user-input");
846
847    $divSchedule.style.position = "relative";
848    $divSchedule.style.top = "40px";
849    $divSchedule.style.left = "25px";
850    $divSchedule.style.width = "95%";
851
852    $divWindowHeader.appendChild($divLogo2);
853    $divWindowHeader.appendChild($divInvMsg);
854    $divWindowHeader.appendChild($spanTyping);
855    $divWindowHeader.appendChild($buttonClose);
856    $divWindowHeader.appendChild($buttonMinimize);
857    $divWindowHeader.appendChild($agentStatus);
858    $div.appendChild($divTitle);
859    $div.appendChild($divWindowHeader);
860
861    $divButton.appendChild($button);
862
863    // [$inputName, $inputLastName].forEach(function (v, i) {
864    //     $form.appendChild(v);
865    // });
866    if (username)
867        $form.appendChild($inputName);
868
869    if (email)
870        $form.appendChild($inputEmail);
871
872    if (phone)
873        $form.appendChild($inputPhone);
874
875
876    var activeElements = [username, email, phone].filter(x => x).length;
877
878    switch (activeElements) {
879        case 1:
880            CHAT_WINDOW_OPENED_HEIGHT = 190;
881            break;
882        case 2:
883            CHAT_WINDOW_OPENED_HEIGHT = 240;
884            break;
885        case 3:
886            CHAT_WINDOW_OPENED_HEIGHT = 290;
887            break;
888        default:
889            CHAT_WINDOW_OPENED_HEIGHT = 140;
890
891    }
892
893    $form.appendChild($divButton);
894    $form.appendChild($divSchedule);
895    $div.appendChild($form);
896    $divChatInputs.appendChild($inputMessage);
897
898    [$divChatlog, $divChatInputs].forEach(function (v, i) {
899        $divChat.appendChild(v);
900    });
901
902    if (uploadFiles) {
903        [$divEmojis, (sendButton ? $buttonSend : null), $buttonUpload, (showEmojis ? $buttonEmoji : null), $inputUploadHidden, $iCancelFile, $progress].forEach(function (v, i) {
904            if (v)
905                $divChatInputs.appendChild(v);
906        });
907    } else {
908        [$divEmojis, (sendButton ? $buttonSend : null), (showEmojis ? $buttonEmoji : null)].forEach(function (v, i) {
909            if (v)
910                $divChatInputs.appendChild(v);
911        });
912    }
913
914    $div.appendChild($divChat);
915    $div.appendChild($divQuestions);
916    [$div, $span].forEach(function (v, i) {
917        j("body").appendChild(v);
918    });
919
920
921    loginPage(fctoken == null);
922
923    if (fctoken == null)
924        j(".jus-window").style.cssText = "height: " + CHAT_WINDOW_CLOSED_HEIGHT + "px;"
925    else {
926        j(".jus-open-window-container").style.display = "none";
927        j(".jus-window-header").style.display = "inline-block";
928        j(".jus-window-header").style.backgroundColor = colorTheme;
929    }
930
931    $divOpen.addEventListener("click", function () {
932        var height = parseInt(j(".jus-window").style.height.replace("px", ""));
933        j(".jus-window").style.overflow = "hidden";
934        questionsSent = false;
935        if (height <= 100) {
936            j(".jus-open-window-container").style.display = "none";
937            j(".jus-window-header").style.display = "inline-block";
938            j(".jus-window-header").style.backgroundColor = colorTheme;
939
940            openChatWindow(j(".jus-window"), function () {
941                j(j(".chat-text-input").style.display != "none" ? ".chat-text-input" : "#name").focus();
942                calculateInputSize();
943            });
944        }
945
946        if (anonymous) {
947            j("#name").value = "anonymous";
948            j("#email").value = "anonymous@" + Guid.NewGuid(), + ".fc";
949            loginPage(true);
950        }
951    });
952
953    $buttonClose.addEventListener("click", function () {
954        token = getCookie("faChatToken");
955        if (token != undefined && token != null) {
956            socket.emit('closeConversationClient', token);
957        } else {
958            if (qualityQuestions.length > 0 && !questionsShown) {
959                drawQuestions();
960            } else {
961                closeChat();
962            }
963        }
964
965    });
966
967    $buttonMinimize.addEventListener("click", function () {
968        closeChatWindow(j(".jus-window"), function () {
969            j(".jus-open-window-container").style.display = "inline-block";
970        });
971    });
972
973    $form.addEventListener("submit", function (event) {
974        pleaseWait(true);
975        loginPage(false);
976        event.preventDefault();
977        j(".chat-text-input").value = "";
978        j(".chat-text-input").disabled = false;
979        j("#jusanchat").style.cssText = "display: inline-block;";
980        openChatWindow(j(".jus-window"), function () {
981            j(j(".chat-text-input").style.display != "none" ? ".chat-text-input" : "#name").focus();
982            calculateInputSize();
983        });
984    });
985
986    $inputMessage.addEventListener("keypress", function (e) {
987        if (e.keyCode == 13 && isBlank(j(".chat-text-input").value) == false) {
988
989            sendMessageEv();
990            return false;
991        } else {
992            if (document.getElementById('juploadfile'))
993                document.getElementById('juploadfile').value = "";
994        }
995    });
996    var timer;
997    $inputMessage.addEventListener("keyup", function (e) {
998        socket.emit('typingClient', getCookie("faChatToken"));
999        clearTimeout(timer);
1000        timer = setTimeout(function () {
1001            socket.emit('typingDoneClient', getCookie("faChatToken"));
1002        }, 2000);
1003    });
1004
1005    then(true);
1006
1007};
1008
1009function loadMessages() {
1010
1011    jPOST(
1012        server + "/loadMessages",
1013        JSON.stringify({ group: group }),
1014        function (res) {
1015            if (res) {
1016                var response = JSON.parse(res);
1017                invitationMessage = response.invitation;
1018                insertName = response.insertName;
1019                insertEmail = response.insertEmail;
1020                insertPhone = response.insertPhone;
1021                waitMessage = response.waitMessage;
1022                sendChat = response.sendChat;
1023                sendMessage = response.sendMessage;
1024            }
1025        },
1026        false
1027    );
1028};
1029
1030function loadJusanScript(url, callback) {
1031    var $script = document.createElement("script");
1032    if (callback) { $script.onload = callback; }
1033    document.head.appendChild($script, document.currentScript);
1034    $script.src = url;
1035};
1036
1037function getJson(file, callback) {
1038    var rawFile = new XMLHttpRequest();
1039    rawFile.open("GET", server + "/" + file, false);
1040    rawFile.onreadystatechange = function () {
1041        if (rawFile.readyState === 4 && rawFile.status == "200") {
1042            callback(rawFile.responseText);
1043        }
1044    }
1045    rawFile.send();
1046}
1047
1048function drawMediaMessage(message, agent, date, name) {
1049
1050    message.text = sanitizeHTML(message.text);
1051
1052    var pane = j('.scroll-pane'),
1053        $div = document.createElement("div"),
1054        mediaElement, $a = document.createElement("a"),
1055        $divClear = document.createElement("div"),
1056        $divDate = document.createElement("div"),
1057        url = server + message.url;
1058
1059    $a.classList.add(agent ? "media-left" : "media-right");
1060    $a.target = "_blank";
1061    $a.rel = "noopener noreferrer";
1062    $a.href = url;
1063
1064    $a.innerText = message.text || "";
1065
1066
1067    $divDate.classList.add(agent ? "jus-data-left" : "jus-data-right");
1068    if (showNames) {
1069        if (agent) {
1070            $divDate.innerHTML = `${date.toLocaleDateString()} ${date.toLocaleTimeString()} <span style="color:${colorTheme};">${(name || "")}</span> `;
1071        } else {
1072            $divDate.innerHTML = `<span style="color:${colorTheme};">${(getCookie("fcChatName") || "")}</span> ${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
1073        }
1074    } else {
1075        $divDate.textContent = `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
1076    }
1077
1078    $div.classList.add(agent ? "agent-message" : "user-message");
1079    if (!agent) {
1080        $div.style.backgroundColor = colorTheme;
1081    }
1082
1083    $divClear.classList.add("jus-clear");
1084    $div.appendChild($a);
1085    pane.appendChild($div);
1086    switch (message.mediaType) {
1087        case "image":
1088            mediaElement = document.createElement("img");
1089            mediaElement.src = url;
1090            mediaElement.style.width = "100%";
1091            $a.append(mediaElement);
1092            break;
1093        case "video":
1094            mediaElement = document.createElement("video");
1095            mediaElement.controls = true;
1096            mediaElement.src = url;
1097            mediaElement.style.width = "100%";
1098            $a.append(mediaElement);
1099            break;
1100        case "audio":
1101        case "voice":
1102            mediaElement = document.createElement("audio");
1103            mediaElement.controls = true;
1104            mediaElement.src = url;
1105            mediaElement.style.width = "100%";
1106            $a.append(mediaElement);
1107            break;
1108        case "document":
1109            if (message.url.indexOf(".pdf") > -1) {
1110                mediaElement = document.createElement("object");
1111                mediaElement.data = url;
1112                mediaElement.style.width = "100%";
1113                $a.append(mediaElement);
1114            }
1115            break;
1116        case "options":
1117            $a.innerText = "";
1118            var p = document.createElement('p'),
1119                divButtons = document.createElement("div");
1120            p.innerHTML = message.text;
1121            divButtons.classList.add("optionscontainer");
1122
1123            $div.appendChild(p);
1124            pane.append(divButtons);
1125
1126
1127            Array.from(document.getElementsByClassName("j-menu-btn")).forEach(x => {
1128                x.removeEventListener("click", writeButtonText);
1129                x.addEventListener("click", writeButtonText);
1130            });
1131            if (message.options != null && message.options.length > 0) {
1132                // message.options.forEach((v, i) => {
1133
1134                //     var b = document.createElement('button');
1135                //     b.setAttribute('content', v.value);
1136                //     b.setAttribute('class', 'jusbtn');
1137                //     b.textContent = v.label;
1138                //     divButtons.appendChild(b);
1139                //     b.addEventListener("click", function (e) {
1140                //         drawMessage(v.label, false, new Date(), "");
1141                //         addUserNewMessage(v.value);
1142                //     });
1143                // });
1144            }
1145            break;
1146    }
1147
1148    pane.appendChild($divDate);
1149    pane.appendChild($divClear);
1150    setTimeout(function () {
1151        if (isIE) {
1152            pane.scrollTop = pane.scrollHeight;
1153        } else {
1154            pane.scrollTo(0, pane.scrollHeight);
1155        }
1156    }, 500);
1157}
1158
1159function drawQuestions() {
1160    var $divQuestions = j("#qualityQuestions"),
1161        $divChat = j("#jusanchat"),
1162        $h4title = document.createElement("h3"),
1163        $button = document.createElement("button");
1164
1165    $button.textContent = qualitySendText;
1166    $button.id = "sendJquestions";
1167    $button.style.backgroundColor = colorTheme;
1168    $h4title.textContent = qualityTitle;
1169    questionsShown = true;
1170    $divQuestions.style.display = "inline-block";
1171    $divChat.style.display = "none";
1172    $divQuestions.append($h4title)
1173
1174    qualityQuestions.forEach((x, i) => {
1175        var $p = document.createElement("p"),
1176            $span = document.createElement("span");
1177
1178        $span.classList.add("jstargroup");
1179        $p.append(x.question);
1180
1181        $divQuestions.append($p);
1182        $divQuestions.append($span);
1183
1184        for (var j = x.min; j <= x.max; j += 1) {
1185            var $inputRadio = document.createElement("input")
1186            $label = document.createElement("label");
1187            $label.textContent = j;
1188            $label.htmlFor = "jquestion_" + i + "x" + j;
1189            $inputRadio.id = "jquestion_" + i + "x" + j;
1190
1191            $inputRadio.name = "jquestion_" + i;
1192            $inputRadio.type = "radio";
1193            if (j == 0)
1194                $inputRadio.classList.add("jinputradio");
1195            $inputRadio.value = j;
1196            $span.prepend($label);
1197            $span.prepend($inputRadio);
1198        }
1199
1200    });
1201
1202    $button.addEventListener("click", saveQuestionQualityResults);
1203    $divQuestions.append($button);
1204}
1205
1206function saveQuestionQualityResults() {
1207    var data = {
1208        questionsResults: [],
1209        questionsResultsStr: "",
1210        chatGuid: getCookie("faChatGuid")
1211    };
1212
1213    qualityQuestions.forEach((x, i) => {
1214        var val = j('input[name="jquestion_' + i + '"]:checked');
1215        data.questionsResults.push(val != null ? val.value : 0);
1216    });
1217    data.questionsResultsStr = data.questionsResults.join("|");
1218    jPOST(
1219        server + "/saveQuality",
1220        JSON.stringify(data),
1221        function (res) {
1222            questionsSent = true;
1223            closeChat();
1224        },
1225        false
1226    );
1227}
1228var domReady = j("#fidchat").getAttribute("data-dom-ready") || "true";
1229console.log(`%c >>>>>>> Initialzie chat when document is ready "${domReady}"`, 'background: #0D0208; color: #00FF41;');
1230
1231if (domReady == "true") {
1232    document.addEventListener('DOMContentLoaded', loadChat);
1233}
1234else {
1235    loadChat();
1236}
1237
1238function loadChat() {
1239    console.log("%c >>>>>>> Initializing CHAT", 'background: #0D0208; color: #00FF41;');
1240    group = j("#fidchat").getAttribute("data-group") || "";
1241    console.log(`%c >>>>>>> group "${group}"`, 'background: #0D0208; color: #00FF41;');
1242    buttonType = j("#fidchat").getAttribute("data-button-type") || buttonType;
1243    console.log(`%c >>>>>>> buttonType "${buttonType}"`, 'background: #0D0208; color: #00FF41;');
1244    invitationMessage = j("#fidchat").getAttribute("data-invitation") || invitationMessage;
1245    console.log(`%c >>>>>>> invitationMessage "${invitationMessage}"`, 'background: #222; color: #00FF41');
1246    insertName = j("#fidchat").getAttribute("data-name") || insertName;
1247    console.log(`%c >>>>>>> insertName "${insertName}"`, 'background: #0D0208; color: #00FF41');
1248    //insertLastName = j("#fidchat").getAttribute("data-lastname") || insertLastName;
1249    insertEmail = j("#fidchat").getAttribute("data-email") || insertEmail;
1250    console.log(`%c >>>>>>> insertEmail "${insertEmail}"`, 'background: #0D0208; color: #00FF41');
1251    waitMessage = j("#fidchat").getAttribute("data-start") || waitMessage;
1252    console.log(`%c >>>>>>> waitMessage "${waitMessage}"`, 'background: #0D0208; color: #00FF41;');
1253    colorTheme = j("#fidchat").getAttribute("data-color-theme") || colorTheme;
1254    console.log(`%c >>>>>>> colorTheme "${colorTheme}"`, 'background: #0D0208; color: #00FF41');
1255    insertPhone = j("#fidchat").getAttribute("data-phone") || insertPhone;
1256    console.log(`%c >>>>>>> insertPhone "${insertPhone}"`, 'background: #0D0208; color: #00FF41');
1257    qualityTitle = j("#fidchat").getAttribute("data-quality") || qualityTitle;
1258    console.log(`%c >>>>>>> qualityTitle "${qualityTitle}"`, 'background: #0D0208; color: #00FF41');
1259    sendMessage = j("#fidchat").getAttribute("data-placeholder") || sendMessage;
1260    console.log(`%c >>>>>>> sendMessage "${sendMessage}"`, 'background: #0D0208; color: #00FF41');
1261    textColorTheme = j("#fidchat").getAttribute("data-text-color") || "white";
1262    console.log(`%c >>>>>>> textColorTheme "${textColorTheme}"`, 'background: #0D0208; color: #00FF41');
1263    dataStartTextColor = j("#fidchat").getAttribute("data-startText-color") || dataStartTextColor;
1264    console.log(`%c >>>>>>> dataStartTextColor "${dataStartTextColor}"`, 'background: #0D0208; color: #00FF41');
1265
1266    try {
1267        phoneRequired = JSON.parse(j("#fidchat").getAttribute("data-phone-required")) || phoneRequired;
1268        console.log(`%c >>>>>>> phoneRequired "${phoneRequired}"`, 'background: #0D0208; color: #00FF41');
1269    } catch (e) {
1270        phoneRequired = false;
1271        console.warn("PARAMETER phoneRequired not configured.");
1272    }
1273
1274    try {
1275        emailRequired = JSON.parse(j("#fidchat").getAttribute("data-email-required"));
1276        console.log(`%c >>>>>>> emailRequired "${emailRequired}"`, 'background: #0D0208; color: #00FF41');
1277    } catch (e) {
1278        emailRequired = false;
1279        console.warn("PARAMETER emailRequired not configured.");
1280    }
1281
1282    try {
1283        nameRequired = JSON.parse(j("#fidchat").getAttribute("data-name-required"));
1284        console.log(`%c >>>>>>> nameRequired "${nameRequired}"`, 'background: #0D0208; color: #00FF41');
1285    } catch (e) {
1286        nameRequired = false;
1287        console.warn("PARAMETER nameRequired not configured.");
1288    }
1289
1290    try {
1291        uploadFiles = JSON.parse(j("#fidchat").getAttribute("data-upload")) || uploadFiles;
1292        console.log(`%c >>>>>>> uploadFiles "${uploadFiles}"`, 'background: #0D0208; color: #00FF41');
1293    } catch (error) {
1294        uploadFiles = false;
1295        console.warn("PARAMETER upload not configured.");
1296    }
1297
1298    try {
1299        phone = JSON.parse(j("#fidchat").getAttribute("data-phoneInput")) || phone;
1300        console.log(`%c >>>>>>> phone "${phone}"`, 'background: #0D0208; color: #00FF41');
1301    } catch (error) {
1302        phone = false;
1303        console.warn("PARAMETER phoneInput not configured.");
1304    }
1305
1306
1307    try {
1308        email = JSON.parse(j("#fidchat").getAttribute("data-emailInput"));
1309        console.log(`%c >>>>>>> email "${email}"`, 'background: #0D0208; color: #00FF41');
1310        if (email == null)
1311            email = true;
1312    } catch (error) {
1313        email = true;
1314        console.warn("PARAMETER emailInput not configured.");
1315    }
1316
1317    try {
1318        username = JSON.parse(j("#fidchat").getAttribute("data-nameInput"));
1319        console.log(`%c >>>>>>> username "${username}"`, 'background: #0D0208; color: #00FF41');
1320        if (username == null)
1321            username = true;
1322    } catch (error) {
1323        username = true;
1324        console.warn("PARAMETER nameInput not configured.");
1325    }
1326
1327    try {
1328        sendEmailToClient = JSON.parse(j("#fidchat").getAttribute("data-sendEmailToClient")) || sendEmailToClient;
1329        console.log(`%c >>>>>>> sendEmailToClient "${sendEmailToClient}"`, 'background: #0D0208; color: #00FF41');
1330    } catch (error) {
1331        sendEmailToClient = false;
1332        console.warn("PARAMETER sendEmailToClient not configured.");
1333    }
1334
1335    try {
1336        autoOpen = JSON.parse(j("#fidchat").getAttribute("data-autoOpen")) || autoOpen;
1337        console.log(`%c >>>>>>> autoOpen "${autoOpen}"`, 'background: #0D0208; color: #00FF41');
1338    } catch (error) {
1339        autoOpen = false;
1340        console.warn("PARAMETER autoOpen not configured.");
1341    }
1342    try {
1343
1344        showNames = JSON.parse(j("#fidchat").getAttribute("data-showNames")) || showNames;
1345        console.log(`%c >>>>>>> showNames "${showNames}"`, 'background: #0D0208; color: #00FF41');
1346    } catch (error) {
1347        showNames = false;
1348        console.warn("PARAMETER showNames not configured.");
1349    }
1350
1351    try {
1352
1353        typingText = j("#fidchat").getAttribute("data-typingText") || typingText;
1354        console.log(`%c >>>>>>> typingText "${typingText}"`, 'background: #0D0208; color: #00FF41');
1355    } catch (error) {
1356        typingText = "Typing...";
1357        console.warn("PARAMETER typingText not configured.");
1358    }
1359
1360    try {
1361        showEmojis = JSON.parse(j("#fidchat").getAttribute("data-showEmojis")) || showEmojis;
1362        console.log(`%c >>>>>>> showEmojis "${showEmojis}"`, 'background: #0D0208; color: #00FF41');
1363    } catch (error) {
1364        showEmojis = false;
1365        console.warn("PARAMETER showEmojis not configured.");
1366    }
1367
1368    try {
1369        qualitySendText = j("#fidchat").getAttribute("data-qualitySendText") || qualitySendText;
1370        console.log(`%c >>>>>>> qualitySendText "${autoOpen}"`, 'background: #0D0208; color: #00FF41');
1371    } catch (error) {
1372        qualitySendText = "Send";
1373        console.warn("PARAMETER qualitySendText not configured.");
1374    }
1375
1376    try {
1377        closeTimeout = parseInt(j("#fidchat").getAttribute("data-close-timeout")) || closeTimeout;
1378        console.log(`%c >>>>>>> closeTimeout "${closeTimeout}"`, 'background: #0D0208; color: #00FF41');
1379    } catch (error) {
1380        closeTimeout = 10000;
1381        console.warn("PARAMETER closeTimeout not configured.");
1382    }
1383
1384    try {
1385        anonymous = j("#fidchat").getAttribute("data-anonymous") == "true" || anonymous;
1386        console.log(`%c >>>>>>> anonymous "${anonymous}"`, 'background: #0D0208; color: #00FF41');
1387    } catch (error) {
1388        anonymous = false;
1389        console.warn("PARAMETER anonymous not configured.");
1390    }
1391
1392    try {
1393        sendButton = j("#fidchat").getAttribute("data-send-button") == "true" || sendButton;
1394        console.log(`%c >>>>>>> sendButton "${sendButton}"`, 'background: #0D0208; color: #00FF41');
1395    } catch (error) {
1396        anonymous = false;
1397        console.warn("PARAMETER sendButton not configured.");
1398    }
1399
1400    if (anonymous) {
1401        phone = false;
1402        email = false;
1403        username = false;
1404        phoneRequired = false;
1405        emailRequired = false;
1406        nameRequired = false;
1407    }
1408
1409    var $head = j("head"),
1410        $linkCss = document.createElement("link"),
1411        $linkCssRtl = document.createElement("link"),
1412        $linkFonts = document.createElement("link"),
1413        $linkFontsAwesome = document.createElement("link"),
1414        scriptfile = server + "/lib/socket.io.js",
1415        emojisScript = server + "/client/emoji.js",
1416        utilsScript = server + "/js/utils.js";
1417
1418    $linkCss.setAttribute("rel", "stylesheet");
1419    $linkCss.setAttribute("type", "text/css");
1420
1421    $linkFontsAwesome.setAttribute("rel", "stylesheet");
1422    $linkFontsAwesome.setAttribute("type", "text/css");
1423    $linkFontsAwesome.setAttribute("href", server + "/css/font-awesome.min.css");
1424
1425
1426    $linkCss.setAttribute("href", server + "/client/stylesv2.css");
1427
1428    $linkCss.setAttribute("media", "all");
1429
1430    $head.appendChild($linkFontsAwesome);
1431    $head.appendChild($linkCss);
1432
1433    if (document.dir == "rtl" || window.navigator.language.substr(0, 2) == "he" || window.navigator.language.substr(0, 2) == "ar") {
1434        $linkCssRtl.setAttribute("rel", "stylesheet");
1435        $linkCssRtl.setAttribute("type", "text/css");
1436        $linkCssRtl.setAttribute("href", server + "/client/stylesv2_rtl.css");
1437        $linkCssRtl.setAttribute("media", "all");
1438        $head.appendChild($linkCssRtl);
1439    }
1440
1441    $head.appendChild($linkFonts);
1442
1443    loadJusanScript(scriptfile, function () {
1444        loadJusanScript(emojisScript, function () {
1445            loadJusanScript(utilsScript, function () {
1446                if (j(".jus-window") == null) {
1447                    jPOST(
1448                        server + "/checkConversation",
1449                        JSON.stringify({ id: getCookie("faChatToken") }),
1450                        function (res) {
1451
1452                            if (!res || res == "false")
1453                                removeCookie("faChatToken");
1454
1455                            initializeChat(function () {
1456                                if (getCookie("faChatToken") != null) {
1457                                    initChat();
1458
1459                                } else {
1460                                    if (autoOpen && !isMobile) {
1461                                        j("#openwindow").click();
1462                                        j("#jusanstartchat").click();
1463                                    }
1464
1465                                    if (autoOpen && isMobile) {
1466                                        pleaseWait(true);
1467                                        loginPage(false);
1468                                        j(".chat-text-input").value = "";
1469                                        j(".chat-text-input").disabled = false;
1470                                        j("#jusanchat").style.cssText = "display: inline-block;";
1471                                    }
1472                                }
1473                            });
1474
1475                        },
1476                        false
1477                    );
1478
1479                }
1480            });
1481        });
1482    });
1483}
1484
1485function parseLink(text, colorTheme) {
1486    let urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim,
1487        pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim,
1488        emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim;
1489
1490    return text
1491        .replace(urlPattern, `<a href="$&" target="_blank"  style="/*color:${colorTheme};*/">$&</a>`)
1492        .replace(pseudoUrlPattern, `$1<a href="http://$2" style="/*color:${colorTheme};*/" target="_blank">$2</a>`)
1493        .replace(emailAddressPattern, `<a href="mailto:$&" style="/*color:${colorTheme};*/" target="_blank">$&</a>`);
1494}
1495
1496function calculateInputSize() {
1497
1498
1499    var width = j("#jusanchat").offsetWidth,
1500        send = j(".jus-send"),
1501        input = j(".chat-text-input");
1502
1503    if (showEmojis && ((!uploadFiles && sendButton) || (uploadFiles && !sendButton))) {
1504        send.style.right = "10px";
1505        input.style.width = (width - 90) + "px";
1506        input.style.paddingRight = "35px";
1507    }
1508
1509    if (showEmojis && !uploadFiles && !sendButton) {
1510        send.style.right = "10px";
1511        input.style.width = (width - 70) + "px";
1512        input.style.paddingRight = "10px";
1513    }
1514
1515    if (!showEmojis && uploadFiles && sendButton) {
1516        input.style.width = (width - 100) + "px";
1517        input.style.paddingRight = "70px";
1518        input.style.paddingLeft = "10px";
1519    }
1520
1521
1522    if (!showEmojis && ((!uploadFiles && sendButton) || (uploadFiles && !sendButton))) {
1523        send.style.right = "10px";
1524        input.style.width = (width - 65) + "px";
1525        input.style.paddingRight = "35px";
1526        input.style.paddingLeft = "10px";
1527    }
1528
1529    if (!showEmojis && !uploadFiles && !sendButton) {
1530        input.style.width = (width - 40) + "px";
1531        input.style.paddingRight = "10px";
1532        input.style.paddingLeft = "10px";
1533    }
1534
1535}
1536
1537function setCookieFidelity(name, value) {
1538
1539    let expires = "";
1540    let domain = getBaseDomain();
1541    let date = new Date();
1542
1543    date.setTime(date.getTime() + (30 * 24 * 60 * 60 * 1000));
1544    expires = "; expires=" + date.toUTCString();
1545
1546    let cookieString = name + "=" + (value || "") + expires + "; path=/";
1547    if (domain)
1548        cookieString += "; domain=" + domain;
1549
1550    cookieString += "; secure";
1551
1552
1553    document.cookie = cookieString;
1554}
1555
1556
1557function getBaseDomain() {
1558
1559    let hostname = window.location.hostname;
1560    let parts = hostname.split('.');
1561
1562    let multiLevelTLDs = new Set([
1563        'com.au', 'net.au', 'org.au', 'edu.au', 'gov.au',
1564        'co.uk', 'org.uk', 'gov.uk', 'ac.uk',
1565        'co.jp', 'ne.jp', 'or.jp', 'go.jp',
1566        'com.cy', 'net.cy', 'gov.cy', 'org.cy'
1567    ]);
1568
1569    if (parts.length <= 1) {
1570        return hostname;
1571    }
1572
1573    for (let i = 0; i < parts.length - 1; i++) {
1574        let possibleTLD = parts.slice(i).join('.');
1575        if (multiLevelTLDs.has(possibleTLD)) {
1576            return parts.slice(i - 1).join('.');
1577        }
1578    }
1579
1580    return parts.slice(-2).join('.');
1581}
1582
1583function getCookie(name) {
1584    let cookie = {};
1585    document.cookie.split(';').forEach(function (el) {
1586        let split = el.split('=');
1587        cookie[split[0].trim()] = split.slice(1).join("=");
1588    })
1589    return cookie[name];
1590}
1591
1592function removeCookie(name) {
1593    let domain = getBaseDomain();
1594    let cookieString = name + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/";
1595
1596    if (domain)
1597        cookieString += "; domain=" + domain;
1598
1599    cookieString += "; secure";
1600
1601    document.cookie = cookieString;
1602}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.