PageSourceSearch

https://ctcredit.net/wp-content/plugins/wp-live-chat-support/js/wplc_server.js?ver=8.1.5

js ctcredit.net collected 2026-10-02 00:12:30 UTC 35,884 bytes, 896 lines download raw bytes

1/*
2 * Hanldes Message transportation within WPLC
3 */
4var gifExtensionPattern = /http(s?):([/|.|\w|\s|-])*\.gif/;
5
6var wplc_server_method = null;
7var wplc_supress_server_logs = true; //We are now surpressing server logs
8var wplc_node_socket = null; //Will not be set unless
9var wplc_node_send_queue = new Array();
10var wplc_node_message_receiver = null;
11var wplc_node_message_restart_handler = null;
12var wplc_node_client_event_logger = null;
13var wplc_node_sockets_ready = false;
14var wplc_transport_prepared = false;
15
16var wplc_node_async_array = new Array(); //Array which will be sent to our async URL for storage
17var wplc_node_async_send_rate = 1; //Amount of messages that need to be present before we sent the async request
18var wplc_node_async_cookie_check_complete = false;
19
20var wplc_node_port_open = true; //This can be set to false to prevent any future data being sent
21var wplc_node_is_client_typing = false;
22var wplc_node_is_pair_typing_indicator_visible = false;
23var wplc_node_pair_name = "";
24
25var wplc_node_switch_ajax_complete = false;
26var wplc_node_retry_count = 0;
27
28var wplc_msg_history = new Array();
29
30var wplc_xhr; //XHR global (allows us to abort previous AJAX request when the agent flips between screens quickly)
31
32
33
34function WPLCServer() {
35  var wplc_server_ref = this;
36  //Default to ajax until chat starts
37  wplc_server_method = WPLCServer.Ajax;
38  wplc_server_ref.send = wplc_server_method.send;
39
40  wplc_server_ref.isInSocketMode = wplc_server_method.isInSocketMode;
41  wplc_server_ref.isPreparingSocketMode = wplc_server_method.isPreparingSocketMode;
42  wplc_server_ref.transportPrepared = wplc_server_method.transportPrepared;
43  wplc_server_ref.asyncStorage = wplc_server_method.asyncStorage;
44  wplc_server_ref.forceClosePort = wplc_server_method.forceClosePort;
45  wplc_server_ref.sendMessage = wplc_server_method.sendMessage;
46
47
48  wplc_server_ref.prepareTransport = function(callback, messageHandler, restartHandler, clientEventLog) {
49    wplc_server_log("-------------------");
50    wplc_server_log("Preparing Transport");
51    if (config.wplc_use_node_server) {
52      if (window.WebSocket) {
53        //Sockets are supported
54        wplc_server_method = WPLCServer.Socket;
55        wplc_server_log("Socket Mode");
56      } else {
57        wplc_server_method = WPLCServer.Ajax;
58        wplc_server_log("Ajax Mode");
59      }
60    } else {
61      wplc_server_method = WPLCServer.Ajax;
62      wplc_server_log("Ajax Mode");
63    }
64
65    wplc_server_method.init(function() {
66      wplc_server_ref.send = wplc_server_method.send;
67      wplc_server_ref.isInSocketMode = wplc_server_method.isInSocketMode;
68      wplc_server_ref.isPreparingSocketMode = wplc_server_method.isPreparingSocketMode;
69      wplc_server_ref.transportPrepared = wplc_server_method.transportPrepared;
70      wplc_server_ref.asyncStorage = wplc_server_method.asyncStorage;
71      wplc_server_ref.forceClosePort = wplc_server_method.forceClosePort;
72      wplc_server_ref.sendMessage = wplc_server_method.sendMessage;
73
74      if (typeof callback === "function") {
75        callback();
76      }
77    }, messageHandler, function() {
78      wplc_server_method = WPLCServer.Ajax;
79      wplc_server_log("Ajax Mode - Fail Over");
80
81      wplc_server_ref.send = wplc_server_method.send;
82      wplc_server_ref.isInSocketMode = wplc_server_method.isInSocketMode;
83      wplc_server_ref.isPreparingSocketMode = function() { return false; };
84      wplc_server_ref.transportPrepared = wplc_server_method.transportPrepared;
85      wplc_server_ref.asyncStorage = wplc_server_method.asyncStorage;
86      wplc_server_ref.forceClosePort = wplc_server_method.forceClosePort;
87      wplc_server_ref.sendMessage = wplc_server_method.sendMessage;
88
89      if (typeof wplc_ajaxurl !== "undefined" && typeof wplc_nonce !== "undefined" && typeof wplc_cid !== "undefined") {
90        var wplc_fail_over_data = {
91          action: 'wplc_node_switch_to_ajax',
92          security: wplc_nonce,
93          cid: wplc_cid
94        };
95
96        jQuery.ajax({
97          url: wplc_ajaxurl,
98          data: wplc_fail_over_data,
99          type: "POST",
100          timeout: 120000,
101          success: function(response) {
102            wplc_server_log("Ajax Mode Enabled");
103          },
104          error: function(error, exception) {
105            wplc_server_log("Chat Fail Over Could Not Be Setup");
106          },
107          complete: function(response) {
108            if (typeof callback === "function") {
109              callback();
110            }
111          }
112        });
113      }
114    }, restartHandler, clientEventLog);
115
116    wplc_server_log("Transport Prepared");
117    wplc_server_log("-------------------");
118    wplc_transport_prepared = true;
119  }
120
121  wplc_server_ref.browserIsSocketReady = function() {
122    if (config.wplc_use_node_server) {
123      if (window.WebSocket) {
124        return true;
125      } else {
126        return false;
127      }
128    } else {
129      return false;
130    }
131  }
132}
133
134WPLCServer.Socket = {};
135
136WPLCServer.Ajax = {
137  init: function(callback, messageHandler, failOver, restartHandler, clientEventLog) {
138    wplc_server_log("Ajax Init");
139    if (typeof callback === "function") {
140      callback();
141    }
142  },
143  send: function(wplc_send_url, wplc_send_data, wplc_send_type, wplc_send_timeout, wplc_send_success_callback, wplc_send_fail_callback, wplc_send_complete_callback) {
144    jQuery.ajax({
145      url: wplc_send_url,
146      data: wplc_send_data,
147      type: wplc_send_type,
148      timeout: wplc_send_timeout,
149      success: function(response) {
150        if (typeof wplc_send_success_callback === "function") {
151          if (typeof wplc_send_data['action'] !== "undefined" && wplc_send_data['action'] !== "wplc_start_chat") { //Is this the start?
152            wplc_send_success_callback(response);
153          } else {
154            //Check if we are going to go into socket mode after this?
155            if (config.wplc_use_node_server) {
156              if (window.WebSocket) {
157                wplc_send_success_callback(response); //Send the data if we are going to sockets after this
158              }
159            }
160          }
161        }
162      },
163      error: function(error, exception) {
164        if (typeof wplc_send_fail_callback === "function") {
165          wplc_send_fail_callback(error, exception);
166        }
167      },
168      complete: function(response) {
169        if (typeof wplc_send_complete_callback === "function") {
170          wplc_send_complete_callback(response, wplc_send_data);
171        }
172      }
173    });
174  },
175  isInSocketMode: function() {
176    return wplc_node_sockets_ready;
177  },
178  isPreparingSocketMode: function() {
179    var preparing = false;
180    if (config.wplc_use_node_server) {
181      if (window.WebSocket) {
182        preparing = true;
183      }
184    }
185
186    return preparing;
187  },
188  transportPrepared: function() {
189    return wplc_transport_prepared;
190  },
191  asyncStorage: function(wplc_send_url, wplc_send_data, wplc_send_timeout) {
192    //Do nothing -> Ajax handles
193  },
194  forceClosePort: function() {
195    //Do Nothing ajax doesnt use socket ports
196  },
197  sendMessage: function(wplc_send_url, wplc_send_data, wplc_send_type, wplc_send_timeout, wplc_send_success_callback, wplc_send_fail_callback, wplc_send_complete_callback) {
198    WPLCServer.Ajax.send(wplc_send_url, wplc_send_data, wplc_send_type, wplc_send_timeout, wplc_send_success_callback, wplc_send_fail_callback, wplc_send_complete_callback);
199  }
200};
201
202
203function wplc_server_log(msg) {
204  if (wplc_supress_server_logs !== true && window.console) {
205    console.log("WPLC SERVER: " + msg);
206  }
207}
208
209function wplc_server_error(msg) {
210  if (window.console) {
211    console.error("WPLC SERVER ERROR: " + msg);
212  }
213}
214
215function wplc_socket_send(data, success, fail, complete) {
216  if (wplc_node_port_open) {
217    wplc_socket_add_to_queue(data, success, fail, complete);
218
219    //if(data.action !== "wplc_user_send_msg" && data.action !== "wplc_admin_send_msg"){
220    var wplc_current_queue_item = wplc_socket_get_next_in_queue();
221    if (wplc_current_queue_item !== false) {
222      if (typeof wplc_node_socket !== "undefined" && wplc_node_socket !== null) {
223        if (wplc_node_socket.readyState !== WebSocket.CONNECTING && wplc_node_socket.readyState !== WebSocket.CLOSING && wplc_node_socket.readyState !== WebSocket.CLOSED) {
224          wplc_current_queue_item.data.is_typing = typeof wplc_node_is_client_typing !== "undefined" ? wplc_node_is_client_typing : false;
225          wplc_node_socket.send(JSON.stringify(wplc_current_queue_item.data));
226
227          if (typeof wplc_current_queue_item.success === "function") {
228            wplc_current_queue_item.success();
229          }
230        } else {
231          //Try again in a sec just now -> Add it to the queue
232          setTimeout(function() {
233            wplc_socket_send(data, success, fail, complete);
234          }, 500);
235        }
236      } else {
237        setTimeout(function() {
238          //Try again in a sec just now -> Add it to the queue
239          wplc_socket_send(data, success, fail, complete);
240        }, 500);
241      }
242    }
243    //}
244  }
245}
246
247function wplc_sanitize_attributes(str) {
248  var wplc_allowed_attributes = "onload,onclick,alert,onerror,dalert";
249  var allowed_attr = wplc_allowed_attributes.split(",");
250  for (i = 0; i < allowed_attr.length; i++) {
251    str = str.replace(allowed_attr[i], '');
252  }
253
254  return str;
255}
256
257function wplc_socket_add_to_queue(data, success, fail, complete) {
258  if (typeof data.server_token === "undefined") {
259    if (typeof tcx_api_key !== "undefined") {
260      data.server_token = tcx_api_key;
261    } else {
262      wplc_server_error("No Server Token Present, Something will go wrong");
263    }
264  }
265
266
267  var queue_item = {
268    data: data,
269    success: success,
270    fail: fail,
271    complete: complete
272  }
273
274  if (wplc_node_send_queue.length > 0) {
275    var last_item = wplc_node_send_queue[wplc_node_send_queue.length - 1];
276    if (JSON.stringify(last_item.data) !== JSON.stringify(data)) {
277      wplc_node_send_queue.push(queue_item);
278    }
279  } else {
280    wplc_node_send_queue.push(queue_item);
281  }
282}
283
284function wplc_socket_get_next_in_queue() {
285  if (wplc_node_send_queue.length > 0) {
286    return wplc_node_send_queue.shift();
287  } else {
288    return false;
289  }
290}
291
292function wplc_rest_api(type, wplc_send_data, wplc_send_timeout, next) {
293
294  if (typeof wplc_xhr !== "undefined" && typeof wplc_xhr.abort() !== "undefined") { wplc_xhr.abort(); }
295  if (typeof next === "undefined" || next === null) { next = function() {}; }
296
297  var wplc_node_ajax_action = type;
298
299  //Send the data to the Async
300  if (!!wplc_restapi_enabled.value && typeof wplc_restapi_endpoint !== "undefined") {
301    //REST API is ready to rumble
302    var anti_cache = Date.now();
303    wplc_send_url = wplc_restapi_endpoint + "/" + type + "?nocache=" + anti_cache;
304    var prepared_data = wplc_send_data;
305    var x = {
306      action: wplc_node_ajax_action,
307      relay_action: wplc_send_data.action,
308      chat_id: wplc_send_data.cid,
309      security: wplc_send_data.security,
310      message: wplc_send_data.msg,
311      server_token: wplc_restapi_token,
312      wplc_extra_data: document.wplc_extra_data,
313      wplc_data: wplc_send_data
314    };
315
316    prepared_data.server_token = wplc_restapi_token;
317    prepared_data.token = wplc_restapi_token; /* backwards compat */
318    if (typeof prepared_data.wplc_extra_data === "undefined") {
319      prepared_data.wplc_extra_data = document.wplc_extra_data;
320    }
321    prepared_data._wpnonce = wplc_restapi_nonce;
322
323    wplc_xhr = jQuery.ajax({
324      url: wplc_send_url,
325      data: prepared_data,
326      type: "POST",
327      timeout: wplc_send_timeout,
328      success: function(response) {
329        wplc_server_log("REST SEND = SUCCESS");
330        next(response);
331      },
332      error: function(error, exception) {
333        wplc_server_log("REST SEND = FAIL");
334        next();
335      },
336    });
337  } else {
338    wplc_server_log("NO REST API :(");
339    next();
340  }
341}
342
343function wplc_json_validator(str) {
344  try {
345    JSON.parse(str);
346  } catch (e) {
347    return false;
348  }
349  return true;
350}
351
352function wplc_node_parse_async_from_object(obj, complete) {
353  for (var i in obj) {
354    if (obj.hasOwnProperty(i)) {
355      wplc_node_async_array.push(obj[i]);
356    }
357  }
358
359  if (typeof complete === "function") {
360    complete();
361  }
362}
363
364function wplc_node_global_message_receiver(data) {
365  if (data) {
366    if (typeof data !== "object") {
367      data = JSON.parse(data);
368    }
369  }
370
371  if (typeof data['pair_name'] !== "undefined") {
372    if (data['pair_name'] !== wplc_node_pair_name) {
373      wplc_node_pair_name = data['pair_name'];
374    }
375  }
376
377  if (typeof data['pair_typing'] !== "undefined") {
378
379    if (data['pair_typing'] === true || data['pair_typing'] === "true") {
380      if (wplc_node_is_pair_typing_indicator_visible === false) {
381        if (jQuery("#wplc_user_typing").length > 0) {} else {
382          jQuery(".typing_indicator").html("<span id='wplc_user_typing'>" + wplc_safe_html(wplc_node_pair_name + config.wplc_localized_string_is_typing_single) + "</span>");
383          jQuery(".typing_indicator").addClass("typing_indicator_active");
384        }
385      }
386      wplc_node_is_pair_typing_indicator_visible = true;
387    } else {
388      if (wplc_node_is_pair_typing_indicator_visible === true) {
389        if (jQuery("#wplc_user_typing").length > 0) {
390          jQuery("#wplc_user_typing").fadeOut("slow").remove();
391          jQuery(".typing_indicator").removeClass("typing_indicator_active");
392        }
393      }
394      wplc_node_is_pair_typing_indicator_visible = false;
395    }
396
397  }
398}
399
400function wplc_add_date_and_time(the_message, originates) {
401
402  if (parseInt(originates) === 1 || parseInt(originates) === 2) {
403
404    var time_msg = '';
405
406    /* identfy the timestamp */
407    if (typeof the_message.other === "undefined" || typeof the_message.other.datetime === "undefined" || the_message.other === false) {
408      /* only run if it hasnt got a timestamp in the .other.datetime key */
409      if (typeof the_message.timestamp !== "undefined") {
410        /* most likely came from node as node */
411
412        if (typeof the_message.other !== "object") { the_message.other = {}; }
413        the_message.other.datetime = the_message.timestamp;
414
415      }
416    }
417
418    if (typeof the_message.other === "undefined" || typeof the_message.other.datetime === "undefined") {
419      /* there is no datetime so return nothing */
420      return '';
421    } else {
422      if (typeof wplc_show_chat_detail !== "undefined") {
423
424        var datetimestamp = the_message.other.hasOwnProperty('datetimeUTC') ? the_message.other.datetimeUTC : the_message.other.datetime;
425        var dateTime = new Date(parseInt(datetimestamp) * 1000);
426
427        if (typeof wplc_show_chat_detail.date !== 'undefined' && '1' === wplc_show_chat_detail.date) {
428
429          var date_format = typeof wplc_datetime_format !== 'undefined' && wplc_datetime_format.hasOwnProperty('date_format') ? wplc_datetime_format.date_format : 'n/d';
430          var date_month = dateTime.getMonth();
431          var date_day = dateTime.getDate();
432          var date_day_no = dateTime.getDay();
433          var date_year = dateTime.getFullYear();
434
435          time_msg += date_format
436            .replace(/S/g, '%S%')
437            .replace(/D/g, '%D%')
438            .replace(/l/g, '%l%')
439            .replace(/F/g, '%F%')
440            .replace(/M/g, '%M%')
441            .replace(/j/g, date_day)
442            .replace(/d/g, date_day < 10 ? '0' + date_day : date_day)
443            .replace(/w/g, date_day_no)
444            .replace(/n/g, date_month + 1)
445            .replace(/m/g, date_month + 1 < 10 ? '0' + (date_month + 1) : date_month + 1)
446            .replace(/Y/g, date_year)
447            .replace(/y/g, date_year.toString().substr(2, 2))
448            .replace(/%S%/g, 1 === date_day ? 'st' : (2 === date_day ? 'nd' : (3 === date_day ? 'rd' : 'th')))
449            .replace(/%D%/g, config.date_days[date_day_no].substr(0, 3))
450            .replace(/%l%/g, config.date_days[date_day_no])
451            .replace(/%F%/g, config.date_months[date_month])
452            .replace(/%M%/g, config.date_months[date_month].substr(0, 3)) + ' ';
453
454        }
455        if (typeof wplc_show_chat_detail.time !== "undefined" && '1' === wplc_show_chat_detail.time) {
456
457          var time_format = typeof wplc_datetime_format !== 'undefined' && wplc_datetime_format.hasOwnProperty('time_format') ? wplc_datetime_format.time_format : 'H:i';
458          var time_hours_12 = dateTime.getHours() > 12 ? dateTime.getHours() - 12 : (dateTime.getHours() < 1 ? 12 : dateTime.getHours());
459          var time_hours_24 = dateTime.getHours();
460          var time_am_pm = time_hours_24 > 11 ? 'pm' : 'am';
461          var time_minutes = dateTime.getMinutes();
462
463          time_msg += time_format
464            .replace(/g/g, time_hours_12)
465            .replace(/h/g, time_hours_12 < 10 ? '0' + time_hours_12 : time_hours_12)
466            .replace(/G/g, time_hours_24)
467            .replace(/H/g, time_hours_24 < 10 ? '0' + time_hours_24 : time_hours_24)
468            .replace(/i/g, time_minutes < 10 ? '0' + time_minutes : time_minutes)
469            .replace(/a/g, time_am_pm.toLowerCase())
470            .replace(/A/g, time_am_pm.toUpperCase());
471
472        }
473        if (time_msg !== '') {
474          if (parseInt(originates) === 1) { aoru_class = 'wplc-msg-float-left'; } else { aoru_class = 'wplc-msg-float-right'; }
475          time_msg = '<span class="timedate ' + aoru_class + '">' + time_msg + '</span>';
476        }
477      }
478
479
480      return time_msg;
481    }
482  } else {
483    return '';
484  }
485
486}
487
488function wplc_get_chat_person_name_msg_field(name) {
489  try {
490    return '<span class="wplc-chat-person-name">' + name + ': </span>';
491  } catch (err) {
492    //console.log("Could not wplc_get_chat_person_name_msg_field() " + err);
493  }
494}
495
496/**
497 * Pushes the message object to the chat box
498 *
499 * @param  {object} the_message The message object
500 * @param  {string} aoru        a for Agent, u for User
501 * @return void
502 */
503function wplc_push_message_to_chatbox(the_message, aoru, next) {
504  /**
505   * First check if we have processed this message already, by comparing the ID
506   *
507   * Some system notifications may not come through with an ID so we can accept those.
508   */
509  var add_message = true;
510
511  if (typeof the_message.mid !== "undefined" && aoru === "u") {
512    if (parseInt(the_message.mid) != 0 && the_message.mid != null) {
513      if (typeof wplc_msg_history[the_message.mid] !== "undefined") {
514        /* we have this message already */
515        add_message = false;
516      } else {
517        /* add this to our history */
518        wplc_msg_history[the_message.mid] = true;
519      }
520    }
521  }
522
523  if (add_message) {
524    add_message = typeof the_message.originates !== "undefined" && the_message.originates !== null && the_message.originates !== "null";
525  }
526
527  if (add_message) {
528    var message_class = "";
529    var message_grav = "";
530    var message_from = "";
531    var message_content = "";
532    var message_aid;
533    var audioPattern = new RegExp(/blob.wav/);
534    var isAudioPattern = false;
535
536    var msgType = 'user';
537    if (parseInt(the_message.originates) === 1) {
538      msgType = 'admin';
539    } else {
540      if (parseInt(the_message.originates) === 0 || parseInt(the_message.originates) === 3) {
541        msgType = 'system';
542      }
543    }
544
545    switch (msgType) {
546
547      case 'admin':
548        {
549          //From Admin
550          /* Define which agent it was sent from  */
551          message_aid = false;
552          if (typeof the_message.other !== "undefined" && typeof the_message.other.aid !== "undefined") {
553            message_aid = the_message.other.aid.toString(); /* set it to a string because wp_localize doesnt know how to set keys as integers */
554          } else if (typeof the_message.other !== "undefined" && typeof the_message.other.agent_id !== "undefined") {
555            /* cloud server uses "agent_id" instead of "aid" */
556            message_aid = the_message.other.agent_id.toString();
557          }
558          message_class = "wplc-admin-message wplc-color-bg-4 wplc-color-2 wplc-color-border-4";
559
560          // If it is audio message
561          isAudioPattern = audioPattern.test(the_message.msg);
562          if (isAudioPattern) {
563            message_class += " wplc-user-message-audio";
564          }
565
566          if (aoru === 'u') {
567            /* message came from admin, intended for user */
568            if (message_aid !== false && typeof wplc_agent_data !== "undefined" && typeof wplc_agent_data[message_aid] !== "undefined") {
569              /* we know who the agent was that sent this message (v7.1.00+) */
570              if (typeof wplc_show_chat_detail !== "undefined") {
571                if (typeof wplc_show_chat_detail.avatar !== "undefined" && wplc_show_chat_detail.avatar === "1") {
572                  message_grav = (typeof wplc_agent_data[message_aid].md5 !== "undefined" ? "<img src='" + wplc_user_avatars[message_aid] + "?s=80&d=mm' class='wplc-admin-message-avatar' />" : "");
573                }
574                if (typeof wplc_show_chat_detail.name !== "undefined" && wplc_show_chat_detail.name === "1") {
575                  message_from = (typeof wplc_agent_data[message_aid].name !== "undefined" ? wplc_get_chat_person_name_msg_field(wplc_agent_data[message_aid].name) : "");
576                }
577              }
578            } else {
579              /* we do'nt know which agent sent this message, so lets set it as the current user instead (backwards compat) */
580              if (typeof wplc_show_chat_detail !== "undefined") {
581                if (typeof wplc_show_chat_detail.avatar !== "undefined" && wplc_show_chat_detail.avatar === "1") {
582                  message_grav = (typeof wplc_current_agent.email !== "undefined" ? "<img src='" + wplc_user_avatars[message_aid] + "?s=80&d=mm' class='wplc-admin-message-avatar' />" : "");
583                }
584                if (typeof wplc_show_chat_detail.name !== "undefined" && wplc_show_chat_detail.name === "1") {
585                  message_from = (typeof wplc_current_agent.name !== "undefined" ? wplc_get_chat_person_name_msg_field(wplc_current_agent.name) : "");
586                }
587              }
588            }
589          } else {
590            if (message_aid !== false && typeof wplc_agent_data !== "undefined" && typeof wplc_agent_data[message_aid] !== "undefined") {
591              /* we know who the agent was that sent this message (v7.1.00+) */
592              if (typeof wplc_show_chat_detail !== "undefined") {
593                if (typeof wplc_show_chat_detail.avatar !== "undefined" && wplc_show_chat_detail.avatar === "1") {
594                  message_grav = (typeof wplc_agent_data[message_aid].md5 !== "undefined" ? "<img src='//www.gravatar.com/avatar/" + wplc_agent_data[message_aid].md5 + "?s=80&d=mm'  class='wplc-admin-message-avatar' />" : "");
595                }
596                if (typeof wplc_show_chat_detail.name !== "undefined" && wplc_show_chat_detail.name === "1") {
597                  message_from = (typeof wplc_agent_data[message_aid].name !== "undefined" ? wplc_get_chat_person_name_msg_field(wplc_agent_data[message_aid].name) : "");
598                }
599              }
600            } else {
601              if (typeof wplc_show_chat_detail.avatar !== "undefined" && wplc_show_chat_detail.avatar === "1") {
602                message_grav = (typeof wplc_admin_agent_email !== "undefined" ? "<img src='//www.gravatar.com/avatar/" + wplc_admin_agent_email + "?s=80&d=mm'  class='wplc-admin-message-avatar' />" : "");
603              }
604              if (typeof wplc_show_chat_detail.name !== "undefined" && wplc_show_chat_detail.name === "1") {
605                message_from = (typeof wplc_admin_agent_name !== "undefined" ? wplc_get_chat_person_name_msg_field(wplc_admin_agent_name) : "");
606              }
607            }
608          }
609
610          message_content = the_message.msg;
611          wplc_new_message_sound = true;
612          break;
613        }
614
615      case 'system':
616        {
617          //System Notification
618          message_class = "wplc-system-notification wplc-color-4";
619          message_content = the_message.msg;
620          if (typeof the_message.other.ntype !== "undefined") {
621            if (the_message.other.ntype === "joined") {
622              jQuery.event.trigger({ type: "wplc_agent_joined", ndata: the_message });
623            }
624          }
625          break;
626        }
627
628      case 'user':
629        {
630          /* most likely from the user */
631          message_class = "wplc-user-message wplc-color-bg-1 wplc-color-2 wplc-color-border-1";
632          isAudioPattern = audioPattern.test(the_message.msg);
633          if (isAudioPattern) {
634            message_class += " wplc-user-message-audio";
635          }
636
637          if (aoru === 'u') {
638            if (jQuery(wplc_email).val() !== "") {
639              message_grav = md5(jQuery(wplc_email).val());
640            } else {
641              if (typeof visitor_list !== "undefined" && typeof visitor_list[active_chatid] !== "undefined" && typeof visitor_list[active_chatid].email !== "undefined") {
642                message_grav = md5(visitor_list[active_chatid].email);
643              } else {
644                if (typeof wplc_cookie_email !== "undefined" && wplc_cookie_email !== "") {
645                  message_grav = md5(wplc_cookie_email);
646                } else {
647                  message_grav = 'x';
648                }
649              }
650            }
651
652            message_grav = "<img src='//www.gravatar.com/avatar/" + message_grav + "?s=80&d=mm'  class='wplc-user-message-avatar' />";
653            if (typeof Cookies.get("wplc_name") === "undefined") {
654              message_from = wplc_get_chat_person_name_msg_field(config.wplc_user_default_visitor_name);
655            } else {
656              message_from = wplc_get_chat_person_name_msg_field(Cookies.get("wplc_name"));
657            }
658          } else {
659            if (typeof wplc_chat_email !== "undefined") {
660              message_grav = wplc_chat_email;
661            } else {
662              if (typeof visitor_list !== "undefined" && typeof visitor_list[active_chatid] !== "undefined" && typeof visitor_list[active_chatid].email !== "undefined") {
663                message_grav = md5(visitor_list[active_chatid].email);
664              } else {
665                if (typeof wplc_cookie_email !== "undefined" && wplc_cookie_email !== "") {
666                  message_grav = md5(wplc_cookie_email);
667                } else {
668                  message_grav = 'x';
669                }
670              }
671            }
672            message_grav = "<img src='//www.gravatar.com/avatar/" + message_grav + "?s=80&d=mm'  class='wplc-user-message-avatar' />";
673            if (typeof wplc_chat_name !== "undefined") {
674              message_from = wplc_get_chat_person_name_msg_field(wplc_chat_name);
675            }
676          }
677          message_content = the_message.msg;
678          break;
679        }
680
681    }
682
683    if (typeof the_message.other !== "undefined" && typeof the_message.other.from_an_agent !== "undefined") {
684      if (the_message.other.from_an_agent === true || the_message.other.from_an_agent === "true") {
685        message_class += ' agent_to_agent';
686      }
687    }
688
689    if (typeof the_message.afrom !== 'undefined' && typeof the_message.ato !== 'undefined') {
690      if (the_message.afrom > 0 && the_message.ato > 0) {
691        if (parseInt(agent_id) !== the_message.afrom) {
692          message_class += ' agent_to_agent';
693        }
694      }
695    }
696
697    message_class += " message_" + the_message.mid;
698
699    if (message_content !== "") {
700      //message_content = wplc_sanitize_attributes(message_content);
701      // If it is audio message
702      isAudioPattern = audioPattern.test(message_content);
703
704      // Open the HTML of a message
705      var concatenated_message = "<span class='" + message_class + "' mid='" + the_message.mid + "'>";
706
707      if (typeof wplc_show_chat_detail !== "undefined") {
708        if (typeof wplc_show_chat_detail.avatar !== "undefined" && wplc_show_chat_detail.avatar === "1") {
709          concatenated_message += message_grav;
710        }
711
712        // Add a wrapper for the person name and the message, this wrapper is necessary to implement the UI of the admin chat	
713        if (isAudioPattern) {
714          concatenated_message += "<div class='wplc-msg-content wplc-msg-content-audio' mid='" + the_message.mid + "'>";
715        } else {
716          concatenated_message += "<div class='wplc-msg-content' mid='" + the_message.mid + "'>";
717        }
718
719        if (isAudioPattern) {
720          concatenated_message += "<span class='wplc-msg-content-audio-icon'></span>";
721        } else if (typeof wplc_show_chat_detail.name !== "undefined" && wplc_show_chat_detail.name === "1") {
722          concatenated_message += message_from;
723        }
724      } else {
725        // Add a wrapper for the person name and the message, this wrapper is necessary to implement the UI of the admin chat	
726        concatenated_message += "<div class='wplc-msg-content'>";
727      }
728
729      if (isAudioPattern) {
730        message_content = "<a href='" + message_content + "' target='_blank'>" + (typeof wplc_visitor_voice !== 'undefined' && typeof wplc_visitor_voice.play_sound !== 'undefined' ? wplc_visitor_voice.play_sound : 'Open Voice Note') + "</a>";
731      } else {
732        if (!!the_message.decorateurl) {
733          message_content = wp_url_decorator(message_content); // only decorate urls, assume html is already escaped
734        } else {
735          if (!!the_message.other && the_message.other.preformatted) {
736            // if message is preformatted, do nothing, escaping is up to formatting routine
737          } else {
738            message_content = wplcFormatParser(message_content); // does all parsing
739          }
740        }
741      }
742
743      // If it is a GIF message
744      if (message_content.match(gifExtensionPattern)) {
745        concatenated_message += "<span class='messageBody'><img src='" + wplc_get_clean_gifurl(message_content) + "' class='gif-img'/></span>";
746      } else if (isAudioPattern) {
747        // If it is audio pattern
748        concatenated_message += "<span class='messageBody'>" + message_content + "</span>";
749      } else {
750        // If it is a regular message
751        concatenated_message += "<span class='messageBody'>" + message_content + "</span>";
752      }
753
754      // Close the person name/message wrapper, if it was added
755      concatenated_message += "</div>";
756
757      // Close the HTML of a message
758      concatenated_message += "</span>";
759      concatenated_message += wplc_add_date_and_time(the_message, the_message.originates);
760
761      if (aoru === 'u') {
762        wplc_chat_box_elemn = "#wplc_chatbox";
763      } else {
764        if (config.wplc_use_node_server) {
765          wplc_chat_box_elemn = "#messages";
766        } else {
767          wplc_chat_box_elemn = "#admin_chat_box_area_" + wplc_cid;
768        }
769      }
770
771      jQuery(wplc_chat_box_elemn).append(concatenated_message);
772    }
773  }
774  next();
775}
776
777jQuery(function() {
778  jQuery(function() {
779    var wplc_node_searchTimeout;
780
781    jQuery("body").on("keydown", "#wplc_chatmsg", function(e) {
782      if (e.which == 13 && jQuery.trim(document.getElementById('wplc_chatmsg').value) == '') {
783        // sink this event
784        return false;
785      }
786    });
787
788    jQuery("body").on("keydown", "#wplc_chatmsg, #wplc_admin_chatmsg", function(e) {
789      if (typeof wplc_node_sockets_ready !== "undefined" && wplc_node_sockets_ready === true) {
790        if (typeof wplc_node_is_client_typing !== "undefined") {
791          if (e.which <= 90 && e.which >= 48) {
792            if (wplc_node_is_client_typing) {
793              wplc_node_renew_typing();
794              return;
795            }
796            wplc_node_is_client_typing = true;
797
798            wplc_node_searchTimeout = setTimeout(wplc_node_clear_typing, 1000);
799          }
800        }
801      }
802    });
803
804    jQuery("body").on("click", "#wplc_na_msg_btn", function() {
805      var wplc_is_gdpr_enabled = jQuery(this).attr('data-wplc-gdpr-enabled');
806      if (typeof wplc_is_gdpr_enabled !== "undefined" && (wplc_is_gdpr_enabled === 'true')) {
807        var wplc_gdpr_opt_in_checked = jQuery("#wplc_chat_gdpr_opt_in").is(':checked');
808        if (typeof wplc_gdpr_opt_in_checked === "undefined" || wplc_gdpr_opt_in_checked === false) {
809          /* GDPR requirements not met */
810          jQuery("#wplc_chat_gdpr_opt_in").addClass('incomplete');
811          return false;
812        }
813        jQuery("#wplc_chat_gdpr_opt_in").removeClass('incomplete');
814      }
815      var wplc_name = jQuery("#wplc_name").val().replace(/(<([^>]+)>)/ig, "");
816      var wplc_email = jQuery("#wplc_email").val().replace(/(<([^>]+)>)/ig, "");
817      var wplc_msg = jQuery("#wplc_message").val();
818      var wplc_domain = jQuery("#wplc_domain_offline").val();
819      var ip_address = jQuery("#wplc_ip_address").val();
820
821      if (wplc_name.length <= 0) { alert(wplc_error_messages.please_enter_name); return false; }
822      if (wplc_email.length <= 0) { alert(wplc_error_messages.please_enter_email); return false; }
823      var testEmail = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,12}$/i;
824      if (!testEmail.test(wplc_email)) {
825        alert(wplc_error_messages.please_enter_valid_email);
826        return false;
827      }
828      if (wplc_msg.length <= 0) { alert(wplc_error_messages.empty_message); return false; }
829      jQuery("#wp-live-chat.classic #wp-live-chat-2-info").hide();
830      jQuery("#wplc_message_div").html(wplc_offline_msg);
831
832      wplc_cid = Cookies.get('wplc_cid');
833
834      var data = {
835        action: 'wplc_user_send_offline_message',
836        security: wplc_nonce,
837        cid: wplc_cid,
838        name: wplc_name,
839        email: wplc_email,
840        msg: wplc_msg,
841        ip: ip_address,
842        domain: wplc_domain,
843        wplc_extra_data: wplc_extra_data
844      };
845
846      jQuery.post(wplc_ajaxurl_site, data, function(response) {
847        jQuery("#wplc_message_div").html(wplc_offline_msg3);
848      });
849      if (typeof wplc_enable_ga !== "undefined" && wplc_enable_ga === '1') {
850        if (typeof ga !== "undefined") {
851          ga('send', {
852            hitType: 'event',
853            eventCategory: 'WP_Live_Chat_Support',
854            eventAction: 'Event',
855            eventLabel: 'User Send Offline Message'
856          });
857        }
858      }
859    });
860
861
862    function wplc_node_renew_typing() {
863      clearTimeout(wplc_node_searchTimeout);
864      wplc_node_searchTimeout = setTimeout(wplc_node_clear_typing, 1000);
865    }
866
867    function wplc_node_clear_typing() {
868      wplc_node_is_client_typing = false;
869      clearTimeout(wplc_node_searchTimeout);
870    }
871  });
872});
873
874var wplc_generate_system_notification_object = function(msg, other, originates) {
875  the_message = {};
876  the_message.originates = originates;
877  the_message.msg = msg;
878  the_message.other = other;
879  var wplc_d = new Date();
880  the_message.other.datetime = Math.round(wplc_d.getTime() / 1000);
881  return the_message;
882}
883
884function wplc_display_system_notification(message) {
885  message_output = '<div id="tcx_notification_message" class="wplc-color-bg-1 wplc-color-2">' + message.msg + '</div>';
886
887  if (jQuery('#tcx_notification_message').length == 0) {
888    jQuery('#wp-live-chat-4').prepend(message_output);
889  }
890}
891
892function wplc_clear_system_notification() {
893  if (jQuery('#tcx_notification_message').length !== 0) {
894    jQuery('#tcx_notification_message').remove();
895  }
896}

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.