Browse code

removed 4 files

DoubleBastionAdmin authored on25/03/2022 13:14:12
Showing4 changed files
1 1
deleted file mode 100644
... ...
@@ -1,7 +0,0 @@
1
-
2
-======= CHANGELOG =======
3
-
4
-Versions:
5
-
6
-== 1.0.0 - 2022-1-27 ==
7
-* Initial Release.
8 0
deleted file mode 100644
... ...
@@ -1,12547 +0,0 @@
1
-/**
2
- *  Copyright (C) 2021  Double Bastion LLC
3
- *
4
- *  This file is part of Roundpin, which is licensed under the
5
- *  GNU Affero General Public License Version 3.0. The license terms
6
- *  are detailed in the "LICENSE.txt" file located in the root directory.
7
- *
8
- *  This is a modified version of the original file
9
- *  "phone.js", first modified in 2020.
10
- *
11
- *  The original "phone.js" file was written by Conrad de Wet.
12
- *  We thank Conrad de Wet for his work and we list below
13
- *  the copyright notice of the original "phone.js" file:
14
-
15
-/*
16
- Copyright (c) 2020  - Conrad de Wet - All Rights Reserved.
17
-=============================================================
18
-File: phone.js
19
-License: GNU Affero General Public License v3.0
20
-Version: 0.1.0
21
-Owner: Conrad de Wet
22
-Date: April 2020
23
-Git: https://github.com/InnovateAsterisk/Browser-Phone
24
-*/
25
-
26
-// Global Settings
27
-// ===============
28
-var enabledExtendedServices = false;
29
-var enabledGroupServices = false;
30
-
31
-// Lanaguage Packs (lang/xx.json)
32
-// ===============
33
-// Note: The following should correspond to files on your server.
34
-// eg: If you list "fr" then you need to add the file "fr.json".
35
-// Use the "en.json" as a template.
36
-// More specific lanagauge must be first. ie: "zh-hans" should be before "zh".
37
-// "en.json" is always loaded by default
38
-const availableLang = ["ja", "zh-hans", "zh", "ru", "tr", "nl"];
39
-
40
-// User Settings & Defaults
41
-// ========================
42
-var wssServer = getDbItem("wssServer", null);
43
-var profileUserID = getDbItem("profileUserID", null);
44
-var profileUser = getDbItem("profileUser", null);
45
-var profileName = getDbItem("profileName", null);
46
-var WebSocketPort = getDbItem("WebSocketPort", null);
47
-var ServerPath = getDbItem("ServerPath", null);
48
-var SipUsername = getDbItem("SipUsername", null);
49
-var SipPassword = getDbItem("SipPassword", null);
50
-var StunServer = getDbItem("StunServer", "");
51
-
52
-var TransportConnectionTimeout = parseInt(getDbItem("TransportConnectionTimeout", 15));        // The timeout in seconds for the initial connection to make on the web socket port
53
-var TransportReconnectionAttempts = parseInt(getDbItem("TransportReconnectionAttempts", 99));  // The number of times to attempt to reconnect to a WebSocket when the connection drops.
54
-var TransportReconnectionTimeout = parseInt(getDbItem("TransportReconnectionTimeout", 15));    // The time in seconds to wait between WebSocket reconnection attempts.
55
-
56
-var userAgentStr = getDbItem("UserAgentStr", "Roundpin (SipJS - 0.11.6)");          // Set this to whatever you want.
57
-var hostingPrefex = getDbItem("HostingPrefex", "");                                 // Use if hosting off root directiory. eg: "/phone/" or "/static/"
58
-var RegisterExpires = parseInt(getDbItem("RegisterExpires", 300));                  // Registration expiry time (in seconds)
59
-var WssInTransport = (getDbItem("WssInTransport", "1") == "1");                     // Set the transport parameter to wss when used in SIP URIs. (Required for Asterisk as it doesnt support Path)
60
-var IpInContact = (getDbItem("IpInContact", "1") == "1");                           // Set a random IP address as the host value in the Contact header field and Via sent-by parameter. (Suggested for Asterisk)
61
-var IceStunCheckTimeout = parseInt(getDbItem("IceStunCheckTimeout", 500));  // Set amount of time in milliseconds to wait for the ICE/STUN server
62
-var AutoAnswerEnabled = (getDbItem("AutoAnswerEnabled", "0") == "1");       // Automatically answers the phone when the call comes in, if you are not on a call already
63
-var DoNotDisturbEnabled = (getDbItem("DoNotDisturbEnabled", "0") == "1");   // Rejects any inbound call, while allowing outbound calls
64
-var CallWaitingEnabled = (getDbItem("CallWaitingEnabled", "1") == "1");     // Rejects any inbound call if you are on a call already.
65
-var RecordAllCalls = (getDbItem("RecordAllCalls", "0") == "1");             // Starts Call Recording when a call is established.
66
-var StartVideoFullScreen = (getDbItem("StartVideoFullScreen", "1") == "0"); // Starts a vdeo call in the full screen (browser screen, not dektop)
67
-var AutoGainControl = (getDbItem("AutoGainControl", "1") == "1");           // Attempts to adjust the microphone volume to a good audio level. (OS may be better at this)
68
-var EchoCancellation = (getDbItem("EchoCancellation", "1") == "1");         // Attemots to remove echo over the line.
69
-var NoiseSuppression = (getDbItem("NoiseSuppression", "1") == "1");         // Attempts to clear the call qulity of noise.
70
-var MirrorVideo = getDbItem("VideoOrientation", "rotateY(180deg)");         // Displays the self-preview in normal or mirror view, to better present the preview. 
71
-var maxFrameRate = getDbItem("FrameRate", "");                              // Suggests a frame rate to your webcam if possible.
72
-var videoHeight = getDbItem("VideoHeight", "");                             // Suggests a video height (and therefore picture quality) to your webcam.
73
-var videoAspectRatio = getDbItem("AspectRatio", "");                        // Suggests an aspect ratio (1:1 | 4:3 | 16:9) to your webcam.
74
-var NotificationsActive = (getDbItem("Notifications", "0") == "1");
75
-var StreamBuffer = parseInt(getDbItem("StreamBuffer", 50));                 // The amount of rows to buffer in the Buddy Stream
76
-var PosterJpegQuality = parseFloat(getDbItem("PosterJpegQuality", 0.6));    // The image quality of the Video Poster images
77
-var VideoResampleSize = getDbItem("VideoResampleSize", "HD");               // The resample size (height) to re-render video that gets presented (sent). (SD = ???x360 | HD = ???x720 | FHD = ???x1080)
78
-var RecordingVideoSize = getDbItem("RecordingVideoSize", "HD");             // The size/quality of the video track in the recodings (SD = 640x360 | HD = 1280x720 | FHD = 1920x1080)
79
-var RecordingVideoFps = parseInt(getDbItem("RecordingVideoFps", 12));       // The Frame Per Second of the Video Track recording
80
-var RecordingLayout = getDbItem("RecordingLayout", "them-pnp");             // The Layout of the Recording Video Track (side-by-side | us-pnp | them-pnp | us-only | them-only)
81
-var DidLength = parseInt(getDbItem("DidLength", 6));                        // DID length from which to decide if an incoming caller is a "contact" or an "extension".
82
-var MaxDidLength = parseInt(getDbItem("maximumNumberLength", 16));          // Maximum langth of any DID number including international dialled numbers.
83
-var DisplayDateFormat = getDbItem("DateFormat", "YYYY-MM-DD");              // The display format for all dates. https://momentjs.com/docs/#/displaying/
84
-var DisplayTimeFormat = getDbItem("TimeFormat", "h:mm:ss A");               // The display format for all times. https://momentjs.com/docs/#/displaying/
85
-var Language = getDbItem("Language", "auto");                               // Overrides the langauage selector or "automatic". Must be one of availableLang[]. If not defaults to en. Testing: zh-Hans-CN, zh-cmn-Hans-CN, zh-Hant, de, de-DE, en-US, fr, fr-FR, es-ES, sl-IT-nedis, hy-Latn-IT-arevela
86
-
87
-// Permission Settings
88
-var EnableTextMessaging = (getDbItem("EnableTextMessaging", "1") == "1");               // Enables the Text Messaging
89
-var DisableFreeDial = (getDbItem("DisableFreeDial", "0") == "1");                       // Removes the Dial icon in the profile area, users will need to add buddies in order to dial.
90
-var DisableBuddies = (getDbItem("DisableBuddies", "0") == "1");                         // Removes the Add Someone menu item and icon from the profile area. Buddies will still be created automatically. 
91
-var EnableTransfer = (getDbItem("EnableTransfer", "1") == "1");                         // Controls Transfering during a call
92
-var EnableConference = (getDbItem("EnableConference", "1") == "1");                     // Controls Conference during a call
93
-var AutoAnswerPolicy = getDbItem("AutoAnswerPolicy", "allow");                          // allow = user can choose | disabled = feature is disabled | enabled = feature is always on
94
-var DoNotDisturbPolicy = getDbItem("DoNotDisturbPolicy", "allow");                      // allow = user can choose | disabled = feature is disabled | enabled = feature is always on
95
-var CallWaitingPolicy = getDbItem("CallWaitingPolicy", "allow");                        // allow = user can choose | disabled = feature is disabled | enabled = feature is always on
96
-var CallRecordingPolicy = getDbItem("CallRecordingPolicy", "allow");                    // allow = user can choose | disabled = feature is disabled | enabled = feature is always on
97
-var EnableAccountSettings = (getDbItem("EnableAccountSettings", "1") == "1");           // Controls the Account tab in Settings
98
-var EnableAudioVideoSettings = (getDbItem("EnableAudioVideoSettings", "1") == "1");     // Controls the Audio & Video tab in Settings
99
-var EnableAppearanceSettings = (getDbItem("EnableAppearanceSettings", "1") == "1");     // Controls the Appearance tab in Settings
100
-var EnableChangeUserPasswordSettings = (getDbItem("EnableChangeUserPasswordSettings", "1") == "1"); // Controls the 'Change Password' tab in Settings
101
-var EnableChangeUserEmailSettings = (getDbItem("EnableChangeUserEmailSettings", "1") == "1");       // Controls the 'Change Email' tab in Settings
102
-var EnableCloseUserAccount = (getDbItem("EnableCloseUserAccount", "1") == "1");                     // Controls the 'Close Account' tab in Settings
103
-var EnableAlphanumericDial = (getDbItem("EnableAlphanumericDial", "1") == "1");                     // Allows calling /[^\da-zA-Z\*\#\+]/g default is /[^\d\*\#\+]/g
104
-var EnableVideoCalling = (getDbItem("EnableVideoCalling", "1") == "1");                             // Enables Video during a call
105
-var winVideoConf = null;
106
-var winVideoConfCheck = 0;
107
-
108
-// System variables
109
-// ================
110
-var localDB = window.localStorage;
111
-var userAgent = null;
112
-var voicemailSubs = null;
113
-var BlfSubs = [];
114
-var CanvasCollection = [];
115
-var Buddies = [];
116
-var isReRegister = false;
117
-var dhtmlxPopup = null;
118
-var selectedBuddy = null;
119
-var selectedLine = null;
120
-var alertObj = null;
121
-var confirmObj = null;
122
-var promptObj = null;
123
-var windowsCollection = null;
124
-var messagingCollection = null;
125
-var HasVideoDevice = false;
126
-var HasAudioDevice = false;
127
-var HasSpeakerDevice = false;
128
-var AudioinputDevices = [];
129
-var VideoinputDevices = [];
130
-var SpeakerDevices = [];
131
-var Lines = [];
132
-var lang = {};
133
-var audioBlobs = {};
134
-var newLineNumber = 0;
135
-var videoAudioCheck = 0;
136
-var RCLoginCheck = 0;
137
-var decSipPass = '';
138
-var currentChatPrivKey = '';
139
-var sendFileCheck = 0;
140
-var upFileName = '';
141
-var sendFileChatErr = '';
142
-var pubKeyCheck = 0;
143
-var splitMessage = {};
144
-
145
-// Utilities
146
-// =========
147
-function uID(){
148
-    return Date.now()+Math.floor(Math.random()*10000).toString(16).toUpperCase();
149
-}
150
-function utcDateNow(){
151
-    return moment().utc().format("YYYY-MM-DD HH:mm:ss UTC");
152
-}
153
-function getDbItem(itemIndex, defaultValue){
154
-    var localDB = window.localStorage;
155
-    if(localDB.getItem(itemIndex) != null) return localDB.getItem(itemIndex);
156
-    return defaultValue;
157
-}
158
-function getAudioSrcID(){
159
-    var id = localDB.getItem("AudioSrcId");
160
-    return (id != null)? id : "default";
161
-}
162
-function getAudioOutputID(){
163
-    var id = localDB.getItem("AudioOutputId");
164
-    return (id != null)? id : "default";
165
-}
166
-function getVideoSrcID(){
167
-    var id = localDB.getItem("VideoSrcId");
168
-    return (id != null)? id : "default";
169
-}
170
-function getRingerOutputID(){
171
-    var id = localDB.getItem("RingOutputId");
172
-    return (id != null)? id : "default";
173
-}
174
-function formatDuration(seconds){
175
-    var sec = Math.floor(parseFloat(seconds));
176
-    if(sec < 0){
177
-        return sec;
178
-    }
179
-    else if(sec >= 0 && sec < 60){
180
-         return sec + " " + ((sec != 1) ? lang.seconds_plural : lang.second_single);
181
-    } 
182
-    else if(sec >= 60 && sec < 60 * 60){ // greater then a minute and less then an hour
183
-        var duration = moment.duration(sec, 'seconds');
184
-        return duration.minutes() + " "+ ((duration.minutes() != 1) ? lang.minutes_plural: lang.minute_single) +" " + duration.seconds() +" "+ ((duration.seconds() != 1) ? lang.seconds_plural : lang.second_single);
185
-    } 
186
-    else if(sec >= 60 * 60 && sec < 24 * 60 * 60){ // greater than an hour and less then a day
187
-        var duration = moment.duration(sec, 'seconds');
188
-        return duration.hours() + " "+ ((duration.hours() != 1) ? lang.hours_plural : lang.hour_single) +" " + duration.minutes() + " "+ ((duration.minutes() != 1) ? lang.minutes_plural: lang.minute_single) +" " + duration.seconds() +" "+ ((duration.seconds() != 1) ? lang.seconds_plural : lang.second_single);
189
-    } 
190
-    //  Otherwise.. this is just too long
191
-}
192
-function formatShortDuration(seconds) {
193
-    var sec = Math.floor(parseFloat(seconds));
194
-    if(sec < 0){
195
-        return sec;
196
-    } 
197
-    else if(sec >= 0 && sec < 60){
198
-        return "00:"+ ((sec > 9)? sec : "0"+sec );
199
-    } 
200
-    else if(sec >= 60 && sec < 60 * 60){ // greater then a minute and less then an hour
201
-        var duration = moment.duration(sec, 'seconds');
202
-        return ((duration.minutes() > 9)? duration.minutes() : "0"+duration.minutes()) + ":" + ((duration.seconds() > 9)? duration.seconds() : "0"+duration.seconds());
203
-    } 
204
-    else if(sec >= 60 * 60 && sec < 24 * 60 * 60){ // greater than an hour and less then a day
205
-        var duration = moment.duration(sec, 'seconds');
206
-        return ((duration.hours() > 9)? duration.hours() : "0"+duration.hours())  + ":" + ((duration.minutes() > 9)? duration.minutes() : "0"+duration.minutes())  + ":" + ((duration.seconds() > 9)? duration.seconds() : "0"+duration.seconds());
207
-    } 
208
-    //  Otherwise.. this is just too long
209
-}
210
-function formatBytes(bytes, decimals) {
211
-    if (bytes === 0) return "0 "+ lang.bytes;
212
-    var k = 1024;
213
-    var dm = (decimals && decimals >= 0)? decimals : 2;
214
-    var sizes = [lang.bytes, lang.kb, lang.mb, lang.gb, lang.tb, lang.pb, lang.eb, lang.zb, lang.yb];
215
-    var i = Math.floor(Math.log(bytes) / Math.log(k));
216
-    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
217
-}
218
-function UserLocale(){
219
-    var language = window.navigator.userLanguage || window.navigator.language; // "en", "en-US", "fr", "fr-FR", "es-ES", etc.
220
-
221
-    langtag = language.split('-');
222
-    if(langtag.length == 1){
223
-        return ""; 
224
-    } 
225
-    else if(langtag.length == 2) {
226
-        return langtag[1].toLowerCase();  // en-US => us
227
-    }
228
-    else if(langtag.length >= 3) {
229
-        return langtag[1].toLowerCase();  // en-US => us
230
-    }
231
-}
232
-function GetAlternateLanguage() {
233
-    var userLanguage = window.navigator.userLanguage || window.navigator.language; // "en", "en-US", "fr", "fr-FR", "es-ES", etc.
234
-
235
-    if(Language != "auto") userLanguage = Language;
236
-    userLanguage = userLanguage.toLowerCase();
237
-    if(userLanguage == "en" || userLanguage.indexOf("en-") == 0) return "";  // English is already loaded
238
-
239
-    for(l = 0; l < availableLang.length; l++) {
240
-        if(userLanguage.indexOf(availableLang[l].toLowerCase()) == 0) {
241
-            console.log("Alternate Language detected: ", userLanguage);
242
-            // Set up Moment with the same langugae settings
243
-            moment.locale(userLanguage);
244
-            return availableLang[l].toLowerCase();
245
-        }
246
-    }
247
-    return "";
248
-}
249
-function getFilter(filter, keyword) {
250
-    if(filter.indexOf(",", filter.indexOf(keyword +": ") + keyword.length + 2) != -1) {
251
-        return filter.substring(filter.indexOf(keyword +": ") + keyword.length + 2, filter.indexOf(",", filter.indexOf(keyword +": ") + keyword.length + 2));
252
-    }
253
-    else {
254
-        return filter.substring(filter.indexOf(keyword +": ") + keyword.length + 2);
255
-    }
256
-}
257
-function base64toBlob(base64Data, contentType) {
258
-    if(base64Data.indexOf("," != -1)) base64Data = base64Data.split(",")[1]; // [data:image/png;base64] , [xxx...]
259
-    var byteCharacters = atob(base64Data);
260
-    var slicesCount = Math.ceil(byteCharacters.length / 1024);
261
-    var byteArrays = new Array(slicesCount);
262
-    for (var s = 0; s < slicesCount; ++s) {
263
-        var begin = s * 1024;
264
-        var end = Math.min(begin + 1024, byteCharacters.length);
265
-        var bytes = new Array(end - begin);
266
-        for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
267
-            bytes[i] = byteCharacters[offset].charCodeAt(0);
268
-        }
269
-        byteArrays[s] = new Uint8Array(bytes);
270
-    }
271
-    return new Blob(byteArrays, { type: contentType });
272
-}
273
-function MakeDataArray(defaultValue, count) {
274
-    var rtnArray = new Array(count);
275
-    for(var i=0; i< rtnArray.length; i++) {
276
-        rtnArray[i] = defaultValue;
277
-    }
278
-    return rtnArray;
279
-}
280
-// Save account configuration data to SQL database
281
-function saveConfToSqldb() {
282
-
283
-    wssServer = $("#Configure_Account_wssServer").val();
284
-    WebSocketPort = parseInt($("#Configure_Account_WebSocketPort").val());
285
-    ServerPath = $("#Configure_Account_ServerPath").val();
286
-    profileName = $("#Configure_Account_profileName").val();
287
-    SipUsername = $("#Configure_Account_SipUsername").val();
288
-    SipPassword = $("#Configure_Account_SipPassword").val();
289
-
290
-    var STUNServer = $("#Configure_Account_StunServer").val();
291
-    var AUDIOOutputId = $("#playbackSrc").val();
292
-    var VIDEOSrcId = $("#previewVideoSrc").val();
293
-    var VIDEOHeight = $("input[name=Settings_Quality]:checked").val(); 
294
-    var FRAMERate = parseInt($("input[name=Settings_FrameRate]:checked").val());
295
-    var ASPECTRatio = $("input[name=Settings_AspectRatio]:checked").val();
296
-    var VIDEOOrientation = $("input[name=Settings_Oriteation]:checked").val();
297
-    var AUDIOSrcId = $("#microphoneSrc").val();
298
-    var AUTOGainControl = ($("#Settings_AutoGainControl").is(':checked'))? "1" : "0";
299
-    var ECHOCancellation = ($("#Settings_EchoCancellation").is(':checked'))? "1" : "0";
300
-    var NOISESuppression = ($("#Settings_NoiseSuppression").is(':checked'))? "1" : "0";
301
-    var RINGOutputId = $("#ringDevice").val();
302
-    var VideoConfExtension = $("#Video_Conf_Extension").val();
303
-    var VideoConfWindowWidth = $("#Video_Conf_Window_Width").val();
304
-    var PROFILEpicture = (typeof getDbItem("profilePicture", "") === 'undefined') ? "" : getDbItem("profilePicture", "");
305
-    var NOTIFYCheck = ($("#Settings_Notifications").is(":checked"))? 1 : 0;
306
-    var EMAILIntegration = ($("#emailIntegration").is(":checked"))? 1 : 0;
307
-    var RCDomain = $("#RoundcubeDomain").val();
308
-    var RCbasicauthuser = $("#rcBasicAuthUser").val();
309
-    var RCbasicauthpass = $("#rcBasicAuthPass").val();
310
-    var RCuser = $("#RoundcubeUser").val();
311
-    var RCpassword = $("#RoundcubePass").val();
312
-
313
-    if (userName != '') {
314
-
315
-       if (wssServer != '' && WebSocketPort != '' && ServerPath != '' && SipUsername != '' && SipPassword != '') {
316
-
317
-          $.ajax({
318
-             type: "POST",
319
-             url: "save-update-settings.php",
320
-             dataType: "JSON",
321
-             data: {
322
-                     username: userName,
323
-                     wss_server: wssServer,
324
-                     web_socket_port: WebSocketPort,
325
-                     server_path: ServerPath,
326
-                     profile_name: profileName,
327
-                     sip_username: SipUsername,
328
-                     sip_password: SipPassword,
329
-                     stun_server: STUNServer,
330
-                     audio_output_id: AUDIOOutputId,
331
-                     video_src_id: VIDEOSrcId,
332
-                     video_height: VIDEOHeight,
333
-                     frame_rate: FRAMERate,
334
-                     aspect_ratio: ASPECTRatio,
335
-                     video_orientation: VIDEOOrientation,
336
-                     audio_src_id: AUDIOSrcId,
337
-                     auto_gain_control: AUTOGainControl,
338
-                     echo_cancellation: ECHOCancellation,
339
-                     noise_suppression: NOISESuppression,
340
-                     ring_output_id: RINGOutputId,
341
-                     video_conf_extension: VideoConfExtension,
342
-                     video_conf_window_width: VideoConfWindowWidth,
343
-                     profile_picture: PROFILEpicture,
344
-                     notifications: NOTIFYCheck,
345
-                     use_roundcube: EMAILIntegration,
346
-                     rcdomain: RCDomain,
347
-                     rcbasicauthuser: RCbasicauthuser,
348
-                     rcbasicauthpass: RCbasicauthpass,
349
-                     rcuser: RCuser,
350
-                     rcpassword: RCpassword,
351
-                     s_ajax_call: validateSToken
352
-             },
353
-             success: function(response) {
354
-                             window.location.reload();
355
-                      },
356
-             error: function(response) {
357
-                             alert("An error occurred while attempting to save the account configuration data!");
358
-             }
359
-          });
360
-
361
-       } else { alert("Fields: 'WebSocket Domain', 'WebSocket Port', 'WebSocket Path', 'SIP Username' and 'SIP Password' are required ! Please fill in all these fields !"); }
362
-
363
-    } else { alert("An error occurred while attempting to save the data!"); }
364
-}
365
-// Get account configuration data from SQL database
366
-function getConfFromSqldb() {
367
-
368
-          $.ajax({
369
-             type: "POST",
370
-             url: "get-settings.php",
371
-             dataType: "JSON",
372
-             data: {
373
-                     username: userName,
374
-                     s_ajax_call: validateSToken
375
-             },
376
-             success: function(datafromdb) {
377
-
378
-                        // Get configuration data from SQL database
379
-                        if (datafromdb.wss_server == null || datafromdb.web_socket_port == null || datafromdb.server_path == null ||
380
-                            datafromdb.sip_username == null || datafromdb.sip_password == null) {
381
-
382
-                            ConfigureExtensionWindow();
383
-
384
-                        } else {
385
-
386
-				if (!localStorage.getItem('firstReLoad')) {
387
-				     localStorage['firstReLoad'] = true;
388
-				     window.setTimeout(function() { window.location.reload(); }, 200);
389
-				}
390
-
391
-                                if (datafromdb.stun_server == null || typeof datafromdb.stun_server == 'undefined') {
392
-                                    var stunData = '';
393
-                                } else { var stunData = datafromdb.stun_server; }
394
-
395
-		                localDB.setItem("profileUserID", uID());
396
-				localDB.setItem("userrole", datafromdb.userrole);
397
-				localDB.setItem("wssServer", datafromdb.wss_server);
398
-				localDB.setItem("WebSocketPort", datafromdb.web_socket_port);
399
-				localDB.setItem("ServerPath", datafromdb.server_path);
400
-				localDB.setItem("profileUser", datafromdb.sip_username);
401
-				localDB.setItem("profileName", datafromdb.profile_name);
402
-				localDB.setItem("SipUsername", datafromdb.sip_username);
403
-				localDB.setItem("SipPassword", datafromdb.sip_password);
404
-				localDB.setItem("StunServer", stunData);
405
-				localDB.setItem("AudioOutputId", datafromdb.audio_output_id);
406
-				localDB.setItem("VideoSrcId", datafromdb.video_src_id);
407
-				localDB.setItem("VideoHeight", datafromdb.video_height);
408
-				localDB.setItem("FrameRate", datafromdb.frame_rate);
409
-				localDB.setItem("AspectRatio", datafromdb.aspect_ratio);
410
-				localDB.setItem("VideoOrientation", datafromdb.video_orientation);
411
-				localDB.setItem("AudioSrcId", datafromdb.audio_src_id);
412
-				localDB.setItem("AutoGainControl", datafromdb.auto_gain_control);
413
-				localDB.setItem("EchoCancellation", datafromdb.echo_cancellation);
414
-				localDB.setItem("NoiseSuppression", datafromdb.noise_suppression);
415
-				localDB.setItem("RingOutputId", datafromdb.ring_output_id);
416
-                                localDB.setItem("VidConfExtension", datafromdb.video_conf_extension);
417
-                                localDB.setItem("VidConfWindowWidth", datafromdb.video_conf_window_width);
418
-				localDB.setItem("profilePicture", datafromdb.profile_picture);
419
-				localDB.setItem("Notifications", datafromdb.notifications);
420
-                                localDB.setItem("useRoundcube", datafromdb.use_roundcube);
421
-                                localDB.setItem("rcDomain", (datafromdb.rcdomain != '' && datafromdb.rcdomain != null && typeof datafromdb.rcdomain != 'undefined')? datafromdb.rcdomain : "");
422
-                                localDB.setItem("rcBasicAuthUser", datafromdb.rcbasicauthuser);
423
-                                localDB.setItem("rcBasicAuthPass", datafromdb.rcbasicauthpass);
424
-                                localDB.setItem("RoundcubeUser", datafromdb.rcuser);
425
-                                localDB.setItem("RoundcubePass", datafromdb.rcpassword);
426
-
427
-		                Register();
428
-                        }
429
-                      },
430
-             error: function(datafromdb) {
431
-                           alert("An error occurred while attempting to retrieve account configuration data from the database!");
432
-             }
433
-          });
434
-}
435
-
436
-// Save contact data to SQL database
437
-function saveContactToSQLDB(newPerson) {
438
-
439
-    if (newPerson.length != 0) {
440
-             $.ajax({
441
-                type: "POST",
442
-                url: "save-contact.php",
443
-                dataType: "JSON",
444
-                data: {
445
-                     username: userName,
446
-                     contact_name: newPerson[0],
447
-                     contact_desc: newPerson[1],
448
-                     extension_number: newPerson[2],
449
-                     contact_mobile: newPerson[3],
450
-                     contact_num1: newPerson[4],
451
-                     contact_num2: newPerson[5],
452
-                     contact_email: newPerson[6],
453
-                     s_ajax_call: validateSToken
454
-                },
455
-                success: function(response) {
456
-                         if (response.result != 'success') { alert(response.result); }
457
-                },
458
-                error: function(response) {
459
-                         alert("An error occurred while attempting to save the contact to the database!");
460
-                }
461
-          });
462
-    } else { alert("An error occurred while attempting to save the data!"); }
463
-}
464
-
465
-// Update contact data in SQL database
466
-function updateContactToSQLDB(newPerson) {
467
-
468
-    if (newPerson.length != 0) {
469
-        if (newPerson[7] != '' && newPerson[7] != null && typeof newPerson[7] != 'undefined') {
470
-            $.ajax({
471
-                type: "POST",
472
-                url: "update-contact.php",
473
-                dataType: "JSON",
474
-                data: {
475
-                     contact_name: newPerson[0],
476
-                     contact_desc: newPerson[1],
477
-                     extension_number: newPerson[2],
478
-                     contact_mobile: newPerson[3],
479
-                     contact_num1: newPerson[4],
480
-                     contact_num2: newPerson[5],
481
-                     contact_email: newPerson[6],
482
-                     contactDBID: newPerson[7],
483
-                     s_ajax_call: validateSToken
484
-                },
485
-                success: function(response) {
486
-                         if (response.result != 'success') { alert(response.result); }
487
-                },
488
-                error: function(response) {
489
-                         alert("An error occurred while attempting to save the data!");
490
-                }
491
-            });
492
-        } else { alert("Error while attempting to retrieve contact data from the database!"); }
493
-    } else { alert("An error occurred while attempting to save the data!"); }
494
-}
495
-// Save contact picture data to SQL database
496
-function saveContactPicToSQLDB(newPic) {
497
-
498
-    if (newPic.length != 0) {
499
-        $.ajax({
500
-             type: "POST",
501
-             url: "save-update-contact-picture.php",
502
-             dataType: "JSON",
503
-             data: {
504
-                     username: userName,
505
-                     contact_name: newPic[0],
506
-                     profile_picture_c: newPic[1],
507
-                     s_ajax_call: validateSToken
508
-             },
509
-             success: function(response) {
510
-                      },
511
-             error: function(response) {
512
-                          alert("An error occurred while attempting to save contact picture!");
513
-             }
514
-        });
515
-    } else { alert("An error occurred while attempting to save contact picture!"); }
516
-}
517
-// Get contact data from SQL database
518
-function getContactsFromSQLDB() {
519
-
520
-          $.ajax({
521
-             type: "POST",
522
-             url: "get-contacts.php",
523
-             dataType: "JSON",
524
-             data: {
525
-                     username: userName,
526
-                     s_ajax_call: validateSToken
527
-             },
528
-             success: function(contactsfromdb) {
529
-
530
-                        // Get contacts from SQL database and save them to localDB
531
-                        var jsonCon = InitUserBuddies();
532
-
533
-                        $.each(contactsfromdb.contactsinfo, function(ind, contactrow) {
534
-			       var id = uID();
535
-			       var dateNow = utcDateNow();
536
-
537
-                               if (contactsfromdb.contactsinfo[ind].extension_number == '' || contactsfromdb.contactsinfo[ind].extension_number == null) {
538
- 
539
-				    jsonCon.DataCollection.push(
540
-					{
541
-					    Type: "contact",
542
-					    LastActivity: dateNow,
543
-					    ExtensionNumber: "",
544
-					    MobileNumber: contactsfromdb.contactsinfo[ind].contact_mobile,
545
-					    ContactNumber1: contactsfromdb.contactsinfo[ind].contact_num1,
546
-					    ContactNumber2: contactsfromdb.contactsinfo[ind].contact_num2,
547
-					    uID: null,
548
-					    cID: id,
549
-					    gID: null,
550
-					    DisplayName: contactsfromdb.contactsinfo[ind].contact_name,
551
-					    Position: "",
552
-					    Description: contactsfromdb.contactsinfo[ind].contact_desc, 
553
-					    Email: contactsfromdb.contactsinfo[ind].contact_email,
554
-					    MemberCount: 0
555
-					}
556
-				    );
557
-
558
-                                    if (contactsfromdb.contactsinfo[ind].profile_picture_c != '' && contactsfromdb.contactsinfo[ind].profile_picture_c != null) {
559
-                                        localDB.setItem("img-"+id+"-contact", contactsfromdb.contactsinfo[ind].profile_picture_c);
560
-                                    }
561
-
562
-			            var buddyObj = new Buddy("contact", id, contactsfromdb.contactsinfo[ind].contact_name, "", contactsfromdb.contactsinfo[ind].contact_mobile, contactsfromdb.contactsinfo[ind].contact_num1, contactsfromdb.contactsinfo[ind].contact_num2, dateNow, contactsfromdb.contactsinfo[ind].contact_desc, contactsfromdb.contactsinfo[ind].contact_email);
563
-			            AddBuddy(buddyObj, true, false, false);
564
-
565
-                               } else {
566
-
567
-				    jsonCon.DataCollection.push(
568
-					{
569
-					    Type: "extension",
570
-					    LastActivity: dateNow,
571
-					    ExtensionNumber: contactsfromdb.contactsinfo[ind].extension_number,
572
-					    MobileNumber: contactsfromdb.contactsinfo[ind].contact_mobile,
573
-					    ContactNumber1: contactsfromdb.contactsinfo[ind].contact_num1,
574
-					    ContactNumber2: contactsfromdb.contactsinfo[ind].contact_num2,
575
-					    uID: id,
576
-					    cID: null,
577
-					    gID: null,
578
-					    DisplayName: contactsfromdb.contactsinfo[ind].contact_name,
579
-					    Position: contactsfromdb.contactsinfo[ind].contact_desc,
580
-					    Description: "", 
581
-					    Email: contactsfromdb.contactsinfo[ind].contact_email,
582
-					    MemberCount: 0
583
-					}
584
-				    );
585
-
586
-                                    if (contactsfromdb.contactsinfo[ind].profile_picture_c != '' && contactsfromdb.contactsinfo[ind].profile_picture_c != null) {
587
-                                        localDB.setItem("img-"+id+"-extension", contactsfromdb.contactsinfo[ind].profile_picture_c);
588
-                                    }
589
-
590
-			            var buddyObj = new Buddy("extension", id, contactsfromdb.contactsinfo[ind].contact_name, contactsfromdb.contactsinfo[ind].extension_number, contactsfromdb.contactsinfo[ind].contact_mobile, contactsfromdb.contactsinfo[ind].contact_num1, contactsfromdb.contactsinfo[ind].contact_num2, dateNow, contactsfromdb.contactsinfo[ind].contact_desc, contactsfromdb.contactsinfo[ind].contact_email);
591
-			            AddBuddy(buddyObj, true, false, true);
592
-                               } 
593
-                        });
594
-
595
-		        jsonCon.TotalRows = jsonCon.DataCollection.length;
596
-		        localDB.setItem(profileUserID + "-Buddies", JSON.stringify(jsonCon));
597
-
598
-                        UpdateUI();
599
-                        PopulateBuddyList();
600
-
601
-                      },
602
-             error: function(contactsfromdb) {
603
-                           alert("An error occurred while attempting to retrieve contacts data from the database!");
604
-             }
605
-          });
606
-}
607
-
608
-// Get external users data from SQL database
609
-function getExternalUserConfFromSqldb() {
610
-
611
-         $.ajax({
612
-             type: "POST",
613
-             url: "get-external-users-conf.php",
614
-             dataType: "JSON",
615
-             data: {
616
-                     username: userName, 
617
-                     s_ajax_call: validateSToken
618
-             },
619
-             success: function(extdatafromdb) {
620
-
621
-                        var extdatafromdbstr = JSON.stringify(extdatafromdb);
622
-
623
-                        if (extdatafromdbstr.length > 0) {
624
-
625
-                            localDB.setItem("externalUserConfElem", extdatafromdb.length);
626
-
627
-                            for (var t = 0; t < extdatafromdb.length; t++) {
628
-				 localDB.setItem("extUserExtension-"+t, extdatafromdb[t]['exten_for_external']);
629
-                                 localDB.setItem("extUserExtensionPass-"+t, extdatafromdb[t]['exten_for_ext_pass']);
630
-                                 localDB.setItem("confAccessLink-"+t, extdatafromdb[t]['conf_access_link']);
631
-                            }
632
-                        }
633
-                      },
634
-             error: function(extdatafromdb) {
635
-                           alert("An error occurred while attempting to retrieve external users configuration data from the database!");
636
-             }
637
-         });
638
-}
639
-
640
-// Check if there are any links for external access associated with the current username
641
-function checkExternalLinks() {
642
-
643
-        if (confirm("Links that can allow external users to access the video conferences are stored in the database. If you don\'t need them anymore, it\'s recommended to remove them in order to prevent unwanted access to your conferences. Press OK to remove all the links for external access associated with your username from the database and then exit Roundpin, or press Cancel to leave the links in the database and just exit.")) {
644
-
645
-             $.ajax({
646
-                 type: "POST",
647
-                 url: "remove-links-for-external-access.php",
648
-                 dataType: "JSON",
649
-                 data: {
650
-                        username: userName,
651
-                        s_ajax_call: validateSToken
652
-                       },
653
-                 success: function(response) {
654
-                            alert("All the links for external access to conferences associated with your username have been successfully removed from the database!");
655
-
656
-		            Unregister();
657
-			    console.log("Signing Out ...");
658
-			    localStorage.clear();
659
-			    if (winVideoConf != null) {
660
-			        winVideoConf.close();
661
-			    }
662
-			    window.open('https://' + window.location.host + '/logout.php', '_self');
663
-                 },
664
-                 error: function(response) {
665
-                            alert("An error occurred while trying to remove the data from the database!");
666
-
667
-		            Unregister();
668
-			    console.log("Signing Out ...");
669
-			    localStorage.clear();
670
-			    if (winVideoConf != null) {
671
-			        winVideoConf.close();
672
-			    }
673
-			    window.open('https://' + window.location.host + '/logout.php', '_self');
674
-                 }
675
-             });
676
-
677
-        } else {
678
-                 Unregister();
679
-		 console.log("Signing Out ...");
680
-		 localStorage.clear();
681
-		 if (winVideoConf != null) {
682
-		     winVideoConf.close();
683
-		 }
684
-		 window.open('https://' + window.location.host + '/logout.php', '_self');
685
-        }
686
-}
687
-
688
-// Remove contact from SQL database
689
-function deleteBuddyFromSqldb(buddyDisplayName) {
690
-
691
-          $.ajax({
692
-             type: "POST",
693
-             url: "remove-contact.php",
694
-             dataType: "JSON",
695
-             data: {
696
-                     username: userName,
697
-                     contact_name: buddyDisplayName,
698
-                     s_ajax_call: validateSToken
699
-             },
700
-             success: function(delresult) {
701
-             },
702
-             error: function(delresult) {
703
-                        alert("An error occurred while attempting to remove the contact from the database!");
704
-             }
705
-          });
706
-}
707
-
708
-// Save new Roundpin user password
709
-function saveNewUserPassword() {
710
-
711
-      var currentPassword = $("#Current_User_Password").val();
712
-      var newPassword = $("#New_User_Password").val();
713
-      var repeatPassword = $("#Repeat_New_User_Password").val();
714
-
715
-      if (currentPassword == '' || newPassword == '' || repeatPassword == '') { alert("Please fill in all the fields!"); return; }
716
-
717
-      // Verify if the new password meets constraints
718
-      if (/^((?=.*\d)(?=.*[a-z])(?=.*\W).{10,})$/.test(newPassword)) {
719
-
720
-          if (repeatPassword == newPassword) {
721
-		  $.ajax({
722
-		     type: "POST",
723
-		     url: "save-new-user-password.php",
724
-		     dataType: "JSON",
725
-		     data: {
726
-		             username: userName,
727
-		             current_password: currentPassword,
728
-                             new_password: newPassword,
729
-		             s_ajax_call: validateSToken
730
-		     },
731
-		     success: function(passchangemessage) {
732
-                                       alert(passchangemessage);
733
-		     },
734
-		     error: function(passchangemessage) {
735
-		                alert("An error occurred while attempting to change the user password!");
736
-		     }
737
-		  });
738
-          } else { alert("The passwords entered in the new password fields don't match!"); }
739
-
740
-      } else {
741
-          alert("The new password does not meet the requirements (to be at least 10 characters long, to contain at least one letter, at least one digit and at least one special character). Please choose a different password ! ");
742
-        }
743
-}
744
-
745
-// Save new Roundpin user email
746
-function saveNewUserEmail() {
747
-
748
-      var currentEmail = $("#Current_User_Email").val();
749
-      var newEmail = $("#New_User_Email").val();
750
-      var repeatEmail = $("#Repeat_New_User_Email").val();
751
-
752
-      if (currentEmail == '' || newEmail == '' || repeatEmail == '') { alert("Please fill in all the fields!"); return; }
753
-
754
-      // Verify if the new email is a valid email address
755
-      if (/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(newEmail)) {
756
-
757
-          if (repeatEmail == newEmail) {
758
-		  $.ajax({
759
-		     type: "POST",
760
-		     url: "save-new-user-email.php",
761
-		     dataType: "JSON",
762
-		     data: {
763
-		             username: userName,
764
-		             current_email: currentEmail,
765
-                             new_email: newEmail,
766
-		             s_ajax_call: validateSToken
767
-		     },
768
-		     success: function(emailchangemessage) {
769
-                                       alert(emailchangemessage);
770
-		     },
771
-		     error: function(emailchangemessage) {
772
-		                alert("An error occurred while attempting to change the user email address!");
773
-		     }
774
-		  });
775
-          } else { alert("The email addresses entered in the new email fields don't match!"); }
776
-
777
-      } else {
778
-            alert("The new email address is not a valid email address. Please enter a valid email address!");
779
-        }
780
-}
781
-
782
-// Close Roundpin user account
783
-function closeUserAccount() {
784
-
785
-      closeVideoAudio();
786
-
787
-      ConfirmConfigExtWindow(lang.confirm_close_account, lang.close_roundpin_user_account, function() {
788
-
789
-		  $.ajax({
790
-		     type: "POST",
791
-		     url: "close-user-account.php",
792
-		     dataType: "JSON",
793
-		     data: {
794
-		             username: userName,
795
-		             s_ajax_call: validateSToken
796
-		     },
797
-		     success: function(closeaccountmessage) {
798
-                                       alert(closeaccountmessage);
799
-                                       SignOut();
800
-		     },
801
-		     error: function(closeaccountmessage) {
802
-		                alert("An error occurred while attempting to close your user account!");
803
-		     }
804
-		  });
805
-      });
806
-}
807
-
808
-// Launch video conference
809
-function LaunchVideoConference() {
810
-     if (winVideoConfCheck == 0) {
811
-	    winVideoConf = window.open('https://' + window.location.host + '/videoconference/index.php');
812
-	    winVideoConfCheck = 1;
813
-     } else { alert("The video conference has been launched. If you want to launch it again refresh the page, then click \"Launch Video Conference\"."); }
814
-}
815
-// Generate a new text chat key
816
-function generateChatRSAKeys(currentSIPusername) {
817
-
818
-          var crypto = new JSEncrypt({default_key_size: 1024});
819
-          crypto.getKey();
820
-          var currentChatPubKey = crypto.getPublicKey();
821
-          currentChatPrivKey = crypto.getPrivateKey();
822
-
823
-	  $.ajax({
824
-	     type: "POST",
825
-	     url: "save-text-chat-pub-key.php",
826
-	     dataType: "JSON",
827
-	     data: {
828
-	             currentextension: currentSIPusername,
829
-                     currentchatpubkey: currentChatPubKey,
830
-	             s_ajax_call: validateSToken
831
-	     },
832
-	     success: function() {
833
-	     },
834
-	     error: function() {
835
-	                alert("An error occurred while trying to save the new text chat public key!");
836
-	     }
837
-	  });
838
-}
839
-
840
-// Remove the 'uploads' directory used to temporarily store files received during text chat
841
-function removeTextChatUploads(currentSIPUser) {
842
-	$.ajax({
843
-	     type: "POST",
844
-	     url: "text-chat-remove-uploaded-files.php",
845
-	     dataType: "JSON",
846
-	     data: {
847
-		     sipusername: currentSIPUser,
848
-		     s_ajax_call: validateSToken
849
-	     },
850
-	     success: function(resresult) {
851
-                          if (resresult.note != 'success') {
852
-                              alert("An error occurred while trying to remove the text chat 'uploads' directory!");
853
-                          }
854
-             },
855
-             error: function(resresult) {
856
-                              alert("An error occurred while attempting to remove the text chat 'uploads' directory!");
857
-             }
858
-        });
859
-}
860
-// On page reload, close the video conference tab if it is opened
861
-function closeVideoConfTab() {
862
-         if (winVideoConf) { winVideoConf.close(); }
863
-}
864
-
865
-// Show Email window
866
-function ShowEmailWindow() {
867
-
868
-   if (getDbItem("useRoundcube", "") == 1) {
869
-
870
-      $("#roundcubeFrame").remove();
871
-      $("#rightContent").show();
872
-      $(".streamSelected").each(function() { $(this).css("display", "none"); });
873
-      $("#rightContent").append('<iframe id="roundcubeFrame" name="displayFrame"></iframe>');
874
-
875
-      var rcDomain = '';
876
-      var rcBasicAuthUser = '';
877
-      var rcBasicAuthPass = '';
878
-      var rcUsername = '';
879
-      var rcPasswd = '';
880
-
881
-      $.ajax({
882
-             'async': false,
883
-             'global': false,
884
-             type: "POST",
885
-             url: "get-email-info.php",
886
-             dataType: "JSON",
887
-             data: {
888
-                     username: userName,
889
-                     s_ajax_call: validateSToken
890
-             },
891
-             success: function(datafromdb) {
892
-                               rcDomain = datafromdb.rcdomain;
893
-                               rcBasicAuthUser = encodeURIComponent(datafromdb.rcbasicauthuser);
894
-                               rcBasicAuthPass = encodeURIComponent(datafromdb.rcbasicauthpass);
895
-                               rcUsername = datafromdb.rcuser;
896
-                               rcPasswd = datafromdb.rcpassword;
897
-             },
898
-             error: function(datafromdb) {
899
-                             alert("An error occurred while trying to retrieve data from the database!");
900
-             }
901
-      });
902
-
903
-      if (rcBasicAuthUser != '' && rcBasicAuthPass != '') { 
904
-          var actionURL = "https://"+ rcBasicAuthUser +":"+ rcBasicAuthPass +"@"+ rcDomain +"/"; 
905
-      } else { var actionURL = "https://"+ rcDomain +"/"; }
906
-
907
-      var form = '<form id="rcForm" method="POST" action="'+ actionURL +'" target="displayFrame">'; 
908
-      form += '<input type="hidden" name="_action" value="login" />';
909
-      form += '<input type="hidden" name="_task" value="login" />';
910
-      form += '<input type="hidden" name="_autologin" value="1" />';
911
-      form += '<input name="_user" value="'+ rcUsername +'" type="text" />';
912
-      form += '<input name="_pass" value="'+ rcPasswd +'" type="password" />';
913
-      form += '<input id="submitButton" type="submit" value="Login" />';
914
-      form += '</form>';
915
-
916
-      $("#roundcubeFrame").append(form);
917
-
918
-      if (RCLoginCheck == 0) {
919
-          $("#submitButton").click();
920
-          RCLoginCheck = 1;
921
-      } else { $("#roundcubeFrame").attr("src", actionURL); }
922
-
923
-   } else { alert("Email Integration is not enabled ! You can enable Roundcube email integration by clicking on the 'Settings' wheel in the user profile section from below > 'Settings' > 'Email Integration' > 'Enable Roundcube email integration'"); }
924
-}
925
-// Shrink the left panel
926
-function CollapseLeftPanel() {
927
-    if ($(window).width() >= 920) {
928
-        if ($("#leftContent").hasClass("shrinkLeftContent")) {
929
-            $("#leftContent").removeClass("shrinkLeftContent");
930
-            $("#rightContent").removeClass("widenRightContent");
931
-            $('#aboutImg').css("margin-right", "-3px");
932
-        } else {
933
-            $("#leftContent").addClass("shrinkLeftContent");
934
-            $("#rightContent").addClass("widenRightContent");
935
-            $('#aboutImg').css("margin-right", "3px");
936
-        }
937
-    }
938
-}
939
-// Show the 'About' window
940
-function ShowAboutWindow() {
941
-
942
-   $.jeegoopopup.close();
943
-   var aboutHtml = '<div>';
944
-   aboutHtml += '<div id="windowCtrls"><img id="minimizeImg" src="images/1_minimize.svg" title="Restore" /><img id="maximizeImg" src="images/2_maximize.svg" title="Maximize" /><img id="closeImg" src="images/3_close.svg" title="Close" /></div>';
945
-   aboutHtml += '<div class="UiWindowField scroller">';
946
-   aboutHtml += '<div><img id="AboutLogoImg" src="images/login-logo.svg"/></div>';
947
-   aboutHtml += '<div id="aboutPopup">'+lang.about_text+'</div>';
948
-   aboutHtml += '</div></div>';
949
-
950
-   $.jeegoopopup.open({
951
-                title: 'About Roundpin',
952
-                html: aboutHtml,
953
-                width: '640',
954
-                height: '500',
955
-                center: true,
956
-                scrolling: 'no',
957
-                skinClass: 'jg_popup_basic',
958
-                overlay: true,
959
-                opacity: 50,
960
-                draggable: true,
961
-                resizable: false,
962
-                fadeIn: 0
963
-   });
964
-
965
-   $("#jg_popup_b").append('<button id="ok_button">'+ lang.ok +'</button>');
966
-
967
-   var maxWidth = $(window).width() - 12;
968
-   var maxHeight = $(window).height() - 88;
969
-
970
-   if (maxWidth < 656 || maxHeight < 500) { 
971
-       $.jeegoopopup.width(maxWidth).height(maxHeight);
972
-       $.jeegoopopup.center();
973
-       $("#maximizeImg").hide();
974
-       $("#minimizeImg").hide();
975
-   } else { 
976
-       $.jeegoopopup.width(640).height(500);
977
-       $.jeegoopopup.center();
978
-       $("#minimizeImg").hide();
979
-       $("#maximizeImg").show();
980
-   }
981
-
982
-   $(window).resize(function() {
983
-       maxWidth = $(window).width() - 12;
984
-       maxHeight = $(window).height() - 88;
985
-
986
-       $.jeegoopopup.center();
987
-       if (maxWidth < 656 || maxHeight < 500) { 
988
-           $.jeegoopopup.width(maxWidth).height(maxHeight);
989
-           $.jeegoopopup.center();
990
-           $("#maximizeImg").hide();
991
-           $("#minimizeImg").hide();
992
-       } else { 
993
-           $.jeegoopopup.width(640).height(500);
994
-           $.jeegoopopup.center();
995
-           $("#minimizeImg").hide();
996
-           $("#maximizeImg").show();
997
-       }
998
-   });
999
-
1000
-   
1001
-   $("#minimizeImg").click(function() { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); });
1002
-   $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); });
1003
-
1004
-   $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); });
1005
-   $("#ok_button").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); });
1006
-   $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); });
1007
-   $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } });
1008
-}
1009
-
1010
-// Show system notifications on incoming calls
1011
-function incomingCallNote() {
1012
-   var incomingCallNotify = new Notification(lang.incomming_call, { icon: "../images/notification-logo.svg", body: "New incoming call !!!" });
1013
-   incomingCallNotify.onclick = function (event) {
1014
-       return;
1015
-   };
1016
-
1017
-   if (document.hasFocus()) {
1018
-       return;
1019
-   } else { setTimeout(incomingCallNote, 8000); }
1020
-}
1021
-
1022
-// Change page title on incoming calls
1023
-function changePageTitle() {
1024
-    if ($(document).attr("title") == "Roundpin") { $(document).prop("title", "New call !!!"); } else { $(document).prop("title", "Roundpin"); }
1025
-    if (document.hasFocus()) {
1026
-        $(document).prop("title", "Roundpin");
1027
-        return;
1028
-    } else { setTimeout(changePageTitle, 460); }
1029
-}
1030
-
1031
-// Window and Document Events
1032
-// ==========================
1033
-$(window).on("beforeunload", function() {
1034
-    Unregister();
1035
-});
1036
-$(window).on("resize", function() {
1037
-    UpdateUI();
1038
-});
1039
-
1040
-// User Interface
1041
-// ==============
1042
-function UpdateUI(){
1043
-    if($(window).outerWidth() < 920){
1044
-        // Narrow Layout
1045
-        if(selectedBuddy == null & selectedLine == null) {
1046
-            // Nobody Selected
1047
-            $("#rightContent").hide();
1048
-
1049
-            $("#leftContent").css("width", "100%");
1050
-            $("#leftContent").show();
1051
-        }
1052
-        else {
1053
-            $("#rightContent").css("margin-left", "0px");
1054
-            $("#rightContent").show();
1055
-
1056
-            $("#leftContent").hide();
1057
-
1058
-            if(selectedBuddy != null) updateScroll(selectedBuddy.identity);
1059
-        }
1060
-    }
1061
-    else {
1062
-        // Wide Screen Layout
1063
-        if(selectedBuddy == null & selectedLine == null) {
1064
-            $("#leftContent").css("width", "320px");
1065
-            $("#rightContent").css("margin-left", "0px");
1066
-            $("#leftContent").show();
1067
-            $("#rightContent").hide();
1068
-        }
1069
-        else{
1070
-            $("#leftContent").css("width", "320px");
1071
-            $("#rightContent").css("margin-left", "320px");
1072
-            $("#leftContent").show();
1073
-            $("#rightContent").show();
1074
-
1075
-            if(selectedBuddy != null) updateScroll(selectedBuddy.identity);
1076
-        }
1077
-    }
1078
-    for(var l=0; l<Lines.length; l++){
1079
-        updateLineScroll(Lines[l].LineNumber);
1080
-    }
1081
-}
1082
-
1083
-// UI Windows
1084
-// ==========
1085
-function AddSomeoneWindow(numberStr){
1086
-
1087
-    $("#userMenu").hide();
1088
-    $.jeegoopopup.close();
1089
-
1090
-    var html = "<div id='AddNewContact'>";
1091
-
1092
-    html += "<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>";
1093
-
1094
-    html += "<div class='UiWindowField scroller'>";
1095
-
1096
-    html += "<div class=UiText>"+ lang.display_name +":</div>";
1097
-    html += "<div><input id=AddSomeone_Name class=UiInputText type=text placeholder='"+ lang.eg_display_name +"'></div>";
1098
-
1099
-    html += "<div class=UiText>"+ lang.title_description +":</div>";
1100
-    html += "<div><input id=AddSomeone_Desc class=UiInputText type=text placeholder='"+ lang.eg_general_manager +"'></div>";
1101
-
1102
-    html += "<div class=UiText>"+ lang.internal_subscribe_extension +":</div>";
1103
-    if(numberStr && numberStr.length > 1 && numberStr.length < DidLength && numberStr.substring(0,1) != "*"){
1104
-        html += "<div><input id=AddSomeone_Exten class=UiInputText type=text value="+ numberStr +" placeholder='"+ lang.eg_internal_subscribe_extension +"'></div>";
1105
-    }
1106
-    else{
1107
-        html += "<div><input id=AddSomeone_Exten class=UiInputText type=text placeholder='"+ lang.eg_internal_subscribe_extension +"'></div>";
1108
-    }
1109
-
1110
-    html += "<div class=UiText>"+ lang.mobile_number +":</div>";
1111
-    html += "<div><input id=AddSomeone_Mobile class=UiInputText type=text placeholder='"+ lang.eg_mobile_number +"'></div>";
1112
-
1113
-    html += "<div class=UiText>"+ lang.contact_number_1 +":</div>";
1114
-    if(numberStr && numberStr.length > 1){
1115
-        html += "<div><input id=AddSomeone_Num1 class=UiInputText type=text value="+ numberStr +" placeholder='"+ lang.eg_contact_number_1 +"'></div>";
1116
-    }
1117
-    else {
1118
-        html += "<div><input id=AddSomeone_Num1 class=UiInputText type=text placeholder='"+ lang.eg_contact_number_1 +"'></div>";
1119
-    }
1120
-
1121
-    html += "<div class=UiText>"+ lang.contact_number_2 +":</div>";
1122
-    html += "<div><input id=AddSomeone_Num2 class=UiInputText type=text placeholder='"+ lang.eg_contact_number_2 +"'></div>";
1123
-
1124
-    html += "<div class=UiText>"+ lang.email +":</div>";
1125
-    html += "<div><input id=AddSomeone_Email class=UiInputText type=text placeholder='"+ lang.eg_email +"'></div>";
1126
-
1127
-    html += "</div></div>"
1128
-
1129
-    $.jeegoopopup.open({
1130
-                title: 'Add Contact',
1131
-                html: html,
1132
-                width: '640',
1133
-                height: '500',
1134
-                center: true,
1135
-                scrolling: 'no',
1136
-                skinClass: 'jg_popup_basic',
1137
-                contentClass: 'addContactPopup',
1138
-                overlay: true,
1139
-                opacity: 50,
1140
-                draggable: true,
1141
-                resizable: false,
1142
-                fadeIn: 0
1143
-    });
1144
-
1145
-    $("#jg_popup_b").append("<div id=bottomButtons><button id=save_button>Save</button><button id=cancel_button>Cancel</button></div>");
1146
-
1147
-    $("#save_button").click(function() {
1148
-
1149
-      var currentASName = $("#AddSomeone_Name").val();
1150
-
1151
-      if (currentASName != null && currentASName.trim() !== '') {
1152
-
1153
-        if (/^[A-Za-z0-9\s\-\'\[\]\(\)]+$/.test(currentASName)) {
1154
-
1155
-	   var currentDesc = $("#AddSomeone_Desc").val();
1156
-	   if (currentDesc != null && currentDesc.trim() !== '') {
1157
-	       if (/^[A-Za-z0-9\s\-\.\'\"\[\]\(\)\{\}\_\!\?\~\@\%\^\&\*\+\>\<\;\:\=]+$/.test(currentDesc)) { var finCurrentDesc = currentDesc; } else { 
1158
-		   var finCurrentDesc = ''; alert('The title/description that you entered is not valid!'); }
1159
-	   } else { var finCurrentDesc = ''; }
1160
-
1161
-	   var currentExtension = $("#AddSomeone_Exten").val();
1162
-	   if (currentExtension != null && currentExtension.trim() !== '') {
1163
-	       if (/^[a-zA-Z0-9\*\#]+$/.test(currentExtension)) { var finCurrentExtension = currentExtension; } else { 
1164
-		   var finCurrentExtension = ''; alert("The extension that you entered in the 'Extension (Internal)' field is not a valid extension!"); }
1165
-	   } else { var finCurrentExtension = ''; }
1166
-
1167
-	   var currentMobile = $("#AddSomeone_Mobile").val();
1168
-	   if (currentMobile != null && currentMobile.trim() !== '') {
1169
-	       if (/^[0-9\s\+\#]+$/.test(currentMobile)) { var finCurrentMobile = currentMobile; } else {
1170
-		   var finCurrentMobile = ''; alert("The phone number that you entered in the 'Mobile Number' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); }
1171
-	   } else { var finCurrentMobile = ''; }
1172
-
1173
-	   var currentNum1 = $("#AddSomeone_Num1").val();
1174
-	   if (currentNum1 != null && currentNum1.trim() !== '') {
1175
-	       if (/^[0-9\s\+\#]+$/.test(currentNum1)) { var finCurrentNum1 = currentNum1; } else {
1176
-		   var finCurrentNum1 = ''; alert("The phone number that you entered in the 'Contact Number 1' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); }
1177
-	   } else { var finCurrentNum1 = ''; }
1178
-
1179
-	   var currentNum2 = $("#AddSomeone_Num2").val();
1180
-	   if (currentNum2 != null && currentNum2.trim() !== '') {
1181
-	       if (/^[0-9\s\+\#]+$/.test(currentNum2)) { var finCurrentNum2 = currentNum2; } else {
1182
-		   var finCurrentNum2 = ''; alert("The phone number that you entered in the 'Contact Number 2' field is not valid! The only allowed characters are: digits, spaces, plus signs and pound signs."); }
1183
-           } else { var finCurrentNum2 = ''; }
1184
-
1185
-	   var currentEmail = $("#AddSomeone_Email").val();
1186
-	   if (currentEmail != null && currentEmail.trim() !== '') {
1187
-	       if (/^[A-Za-z0-9\_\.\-\~\%\+\!\?\&\*\^\=\#\$\{\}\|\/]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\-]{2,63}$/.test(currentEmail)) { var finCurrentEmail = currentEmail; } else {
1188
-		   var finCurrentEmail = ''; alert("The email that you entered is not a valid email address!"); }
1189
-	   } else { var finCurrentEmail = ''; }
1190
-
1191
-
1192
-           // Add Contact / Extension
1193
-           var json = JSON.parse(localDB.getItem(profileUserID + "-Buddies"));
1194
-           if(json == null) json = InitUserBuddies();
1195
-
1196
-           if(finCurrentExtension == ''){
1197
-               // Add Regular Contact
1198
-               var id = uID();
1199
-               var dateNow = utcDateNow();
1200
-               json.DataCollection.push(
1201
-                   {
1202
-                    Type: "contact",
1203
-                    LastActivity: dateNow,
1204
-                    ExtensionNumber: "",
1205
-                    MobileNumber: finCurrentMobile,
1206
-                    ContactNumber1: finCurrentNum1,
1207
-                    ContactNumber2: finCurrentNum2,
1208
-                    uID: null,
1209
-                    cID: id,
1210
-                    gID: null,
1211
-                    DisplayName: currentASName,
1212
-                    Position: "",
1213
-                    Description: finCurrentDesc,
1214
-                    Email: finCurrentEmail,
1215
-                    MemberCount: 0
1216
-                   }
1217
-               );
1218
-               var newPerson = [];
1219
-               newPerson = [currentASName, finCurrentDesc, "", finCurrentMobile, finCurrentNum1, finCurrentNum2, finCurrentEmail];
1220
-               saveContactToSQLDB(newPerson);
1221
-
1222
-               var buddyObj = new Buddy("contact", id, currentASName, "", finCurrentMobile, finCurrentNum1, finCurrentNum2, dateNow, finCurrentDesc, finCurrentEmail);
1223
-               AddBuddy(buddyObj, false, false, false);
1224
-
1225
-           } else {
1226
-               // Add Extension
1227
-               var id = uID();
1228
-               var dateNow = utcDateNow();
1229
-               json.DataCollection.push(
1230
-                   {
1231
-                    Type: "extension",
1232
-                    LastActivity: dateNow,
1233
-                    ExtensionNumber: finCurrentExtension,
1234
-                    MobileNumber: finCurrentMobile,
1235
-                    ContactNumber1: finCurrentNum1,
1236
-                    ContactNumber2: finCurrentNum2,
1237
-                    uID: id,
1238
-                    cID: null,
1239
-                    gID: null,
1240
-                    DisplayName: currentASName,
1241
-                    Position: finCurrentDesc,
1242
-                    Description: "",
1243
-                    Email: finCurrentEmail,
1244
-                    MemberCount: 0
1245
-                   }
1246
-               );
1247
-
1248
-               var newPerson = [];
1249
-
1250
-               newPerson = [currentASName, finCurrentDesc, finCurrentExtension, finCurrentMobile, finCurrentNum1, finCurrentNum2, finCurrentEmail];
1251
-               saveContactToSQLDB(newPerson);
1252
-
1253
-               var buddyObj = new Buddy("extension", id, currentASName, finCurrentExtension, finCurrentMobile, finCurrentNum1, finCurrentNum2, dateNow, finCurrentDesc, finCurrentEmail);
1254
-               AddBuddy(buddyObj, false, false, true);
1255
-
1256
-           }
1257
-           // Update Size:
1258
-           json.TotalRows = json.DataCollection.length;
1259
-
1260
-           // Save To Local DB
1261
-           localDB.setItem(profileUserID + "-Buddies", JSON.stringify(json));
1262
-           UpdateBuddyList();
1263
-
1264
-           $.jeegoopopup.close();
1265
-           $("#jg_popup_b").empty();
1266
-
1267
-        } else { alert('The display name that you entered is not a valid display name!'); }
1268
-
1269
-      } else { alert("'Display Name' cannot be empty!"); }
1270
-       
1271
-   });
1272
-
1273
-   var maxWidth = $(window).width() - 12;
1274
-   var maxHeight = $(window).height() - 110;
1275
-
1276
-   if (maxWidth < 656 || maxHeight < 500) { 
1277
-       $.jeegoopopup.width(maxWidth).height(maxHeight);
1278
-       $.jeegoopopup.center();
1279
-       $("#maximizeImg").hide();
1280
-       $("#minimizeImg").hide();
1281
-   } else { 
1282
-       $.jeegoopopup.width(640).height(500);
1283
-       $.jeegoopopup.center();
1284
-       $("#minimizeImg").hide();
1285
-       $("#maximizeImg").show();
1286
-   }
1287
-
1288
-   $(window).resize(function() {
1289
-       maxWidth = $(window).width() - 16;
1290
-       maxHeight = $(window).height() - 110;
1291
-       $.jeegoopopup.center();
1292
-       if (maxWidth < 656 || maxHeight < 500) { 
1293
-           $.jeegoopopup.width(maxWidth).height(maxHeight);
1294
-           $.jeegoopopup.center();
1295
-           $("#maximizeImg").hide();
1296
-           $("#minimizeImg").hide();
1297
-       } else { 
1298
-           $.jeegoopopup.width(640).height(500);
1299
-           $.jeegoopopup.center();
1300
-           $("#minimizeImg").hide();
1301
-           $("#maximizeImg").show();
1302
-       }
1303
-   });
1304
-
1305
-   $("#minimizeImg").click(function() { $.jeegoopopup.width(640).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); });
1306
-   $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); });
1307
-
1308
-   $("#closeImg").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); });
1309
-   $("#cancel_button").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); });
1310
-   $("#jg_popup_overlay").click(function() { $.jeegoopopup.close(); $("#jg_popup_b").empty(); });
1311
-   $(window).on('keydown', function(event) { if (event.key == "Escape") { $.jeegoopopup.close(); $("#jg_popup_b").empty(); } });
1312
-}
1313
-
1314
-function CreateGroupWindow(){
1315
-}
1316
-
1317
-function closeVideoAudio() {
1318
-
1319
-        var localVideo = $("#local-video-preview").get(0);
1320
-        try{
1321
-            var tracks = localVideo.srcObject.getTracks();
1322
-            tracks.forEach(function(track) {
1323
-                track.stop();
1324
-            });
1325
-            localVideo.srcObject = null;
1326
-        }
1327
-        catch(e){}
1328
-
1329
-        try{
1330
-            var tracks = window.SettingsMicrophoneStream.getTracks();
1331
-            tracks.forEach(function(track) {
1332
-                track.stop();
1333
-            });
1334
-        }
1335
-        catch(e){}
1336
-        window.SettingsMicrophoneStream = null;
1337
-
1338
-        try{
1339
-            var soundMeter = window.SettingsMicrophoneSoundMeter;
1340
-            soundMeter.stop();
1341
-        }
1342
-        catch(e){}
1343
-        window.SettingsMicrophoneSoundMeter = null;
1344
-
1345
-        try{
1346
-            window.SettingsOutputAudio.pause();
1347
-        }
1348
-        catch(e){}
1349
-        window.SettingsOutputAudio = null;
1350
-
1351
-        try{
1352
-            var tracks = window.SettingsOutputStream.getTracks();
1353
-            tracks.forEach(function(track) {
1354
-                track.stop();
1355
-            });
1356
-        }
1357
-        catch(e){}
1358
-        window.SettingsOutputStream = null;
1359
-
1360
-        try{
1361
-            var soundMeter = window.SettingsOutputStreamMeter;
1362
-            soundMeter.stop();
1363
-        }
1364
-        catch(e){}
1365
-        window.SettingsOutputStreamMeter = null;
1366
-
1367
-        return true;
1368
-}
1369
-function ConfigureExtensionWindow() {
1370
-
1371
-    $("#settingsCMenu").hide();
1372
-    $.jeegoopopup.close();
1373
-
1374
-    var configWindow = "<div id=\"mainConfWindow\">";
1375
-    configWindow += "<div id='windowCtrls'><img id='minimizeImg' src='images/1_minimize.svg' title='Restore' /><img id='maximizeImg' src='images/2_maximize.svg' title='Maximize' /><img id='closeImg' src='images/3_close.svg' title='Close' /></div>"; 
1376
-    configWindow += "<div id=\"mainRightConf\">";
1377
-    configWindow += "<div id=\"rightMainConfWindow\">";
1378
-
1379
-    configWindow +=  "<div id=\"AccountHtml\" class=\"settingsSubSection\" style=\"display:block;\">";
1380
-    configWindow += "<div class=UiText>"+ lang.asterisk_server_address +": *</div>";
1381
-    configWindow += "<div><input id=Configure_Account_wssServer class=UiInputText type=text placeholder='"+ lang.eg_asterisk_server_address +"' value='"+ getDbItem("wssServer", "") +"'></div>";
1382
-    configWindow += "<div class=UiText>"+ lang.websocket_port +": *</div>";
1383
-    configWindow += "<div><input id=Configure_Account_WebSocketPort class=UiInputText type=text placeholder='"+ lang.eg_websocket_port +"' value='"+ getDbItem("WebSocketPort", "") +"'></div>";
1384
-    configWindow += "<div class=UiText>"+ lang.websocket_path +": *</div>";
1385
-    configWindow += "<div><input id=Configure_Account_ServerPath class=UiInputText type=text placeholder='"+ lang.eg_websocket_path +"' value='"+ getDbItem("ServerPath", "") +"'></div>";
1386
-    configWindow += "<div class=UiText>"+ lang.display_name +": *</div>";
1387
-
1388
-    var escapedDisplayName = 'value="' + getDbItem("profileName", "").replace("'","\'") + '"';
1389
-    configWindow += "<div><input id=Configure_Account_profileName class=UiInputText type=text placeholder='"+ lang.eg_display_name +"' "+ escapedDisplayName +"></div>";
1390
-    configWindow += "<div class=UiText>"+ lang.sip_username +": *</div>";
1391
-    configWindow += "<div><input id=Configure_Account_SipUsername class=UiInputText type=text placeholder='"+ lang.eg_sip_username +"' value='"+ getDbItem("SipUsername", "") +"'></div>";
1392
-    configWindow += "<div class=UiText>"+ lang.sip_password +": *</div>";
1393
-    configWindow += "<div><input id=Configure_Account_SipPassword class=UiInputText type=password placeholder='"+ lang.eg_sip_password +"' value='"+ getDbItem("SipPassword", "") +"'></div>";
1394
-    configWindow += "<div class=UiText>"+ lang.stun_server +":</div>";
1395
-    configWindow += "<div><input id=Configure_Account_StunServer class=UiInputText type=text placeholder='Eg: 123.123.123.123:8443' value='"+ getDbItem("StunServer", "") +"'></div>";
1396
-    configWindow += "<p style=\"color:#363636;\">* Required field.</p><br><br></div>";
1397
-
1398
-    configWindow += "<div id=\"AudioVideoHtml\" class=\"settingsSubSection\" style=\"display:none;\">";
1399
-    configWindow += "<div class=UiText>"+ lang.speaker +":</div>";
1400
-    configWindow += "<div style=\"text-align:center\"><select id=playbackSrc style=\"width:100%\"></select></div>";
1401
-    configWindow += "<div class=Settings_VolumeOutput_Container><div id=Settings_SpeakerOutput class=Settings_VolumeOutput></div></div>";
1402
-    configWindow += "<div><button class=on_white id=preview_output_play><i class=\"fa fa-play\"></i></button><button class=on_white id=preview_output_pause><i class=\"fa fa-pause\"></i></button></div>";
1403
-
1404
-    configWindow += "<br><div class=UiText>"+ lang.ring_device +":</div>";
1405
-    configWindow += "<div style=\"text-align:center\"><select id=ringDevice style=\"width:100%\"></select></div>";
1406
-    configWindow += "<div class=Settings_VolumeOutput_Container><div id=Settings_RingerOutput class=Settings_VolumeOutput></div></div>";
1407
-    configWindow += "<div><button class=on_white id=preview_ringer_play><i class=\"fa fa-play\"></i></button></div>";
1408
-
1409
-    configWindow += "<br><div class=UiText>"+ lang.microphone +":</div>";
1410
-    configWindow += "<div style=\"text-align:center\"><select id=microphoneSrc style=\"width:100%\"></select></div>";
1411
-    configWindow += "<div class=Settings_VolumeOutput_Container><div id=Settings_MicrophoneOutput class=Settings_VolumeOutput></div></div>";
1412
-    configWindow += "<br><br><div><input type=checkbox id=Settings_AutoGainControl><label for=Settings_AutoGainControl> "+ lang.auto_gain_control +"<label></div>";
1413
-    configWindow += "<div><input type=checkbox id=Settings_EchoCancellation><label for=Settings_EchoCancellation> "+ lang.echo_cancellation +"<label></div>";
1414
-    configWindow += "<div><input type=checkbox id=Settings_NoiseSuppression><label for=Settings_NoiseSuppression> "+ lang.noise_suppression +"<label></div>";
1415
-    configWindow += "<br><div class=UiText>"+ lang.camera +":</div>";
1416
-    configWindow += "<div style=\"text-align:center\"><select id=previewVideoSrc style=\"width:100%\"></select></div>";
1417
-    configWindow += "<br><div class=UiText>"+ lang.frame_rate +":</div>"
1418
-    configWindow += "<div class=pill-nav>";
1419
-    configWindow += "<input name=Settings_FrameRate id=r40 type=radio value=\"2\"><label class=radio_pill for=r40>2</label>";
1420
-    configWindow += "<input name=Settings_FrameRate id=r41 type=radio value=\"5\"><label class=radio_pill for=r41>5</label>";
1421
-    configWindow += "<input name=Settings_FrameRate id=r42 type=radio value=\"10\"><label class=radio_pill for=r42>10</label>";
1422
-    configWindow += "<input name=Settings_FrameRate id=r43 type=radio value=\"15\"><label class=radio_pill for=r43>15</label>";
1423
-    configWindow += "<input name=Settings_FrameRate id=r44 type=radio value=\"20\"><label class=radio_pill for=r44>20</label>";
1424
-    configWindow += "<input name=Settings_FrameRate id=r45 type=radio value=\"25\"><label class=radio_pill for=r45>25</label>";
1425
-    configWindow += "<input name=Settings_FrameRate id=r46 type=radio value=\"30\"><label class=radio_pill for=r46>30</label>";
1426
-    configWindow += "<input name=Settings_FrameRate id=r47 type=radio value=\"\"><label class=radio_pill for=r47><i class=\"fa fa-trash\"></i></label>";
1427
-    configWindow += "</div>";
1428
-    configWindow += "<br><br><div class=UiText>"+ lang.quality +":</div>";
1429
-    configWindow += "<div class=pill-nav>";
1430
-    configWindow += "<input name=Settings_Quality id=r30 type=radio value=\"160\"><label class=radio_pill for=r30><i class=\"fa fa-video-camera\" style=\"transform: scale(0.4)\"></i> HQVGA</label>";
1431
-    configWindow += "<input name=Settings_Quality id=r31 type=radio value=\"240\"><label class=radio_pill for=r31><i class=\"fa fa-video-camera\" style=\"transform: scale(0.6)\"></i> QVGA</label>";
1432
-    configWindow += "<input name=Settings_Quality id=r32 type=radio value=\"480\"><label class=radio_pill for=r32><i class=\"fa fa-video-camera\" style=\"transform: scale(0.8)\"></i> VGA</label>";
1433
-    configWindow += "<input name=Settings_Quality id=r33 type=radio value=\"720\"><label class=radio_pill for=r33><i class=\"fa fa-video-camera\" style=\"transform: scale(1)\"></i> HD</label>";
1434
-    configWindow += "<input name=Settings_Quality id=r34 type=radio value=\"\"><label class=radio_pill for=r34><i class=\"fa fa-trash\"></i></label>";
1435
-    configWindow += "</div>";
1436
-    configWindow += "<br><br><div class=UiText>"+ lang.image_orientation +":</div>";
1437
-    configWindow += "<div class=pill-nav>";
1438
-    configWindow += "<input name=Settings_Oriteation id=r20 type=radio value=\"rotateY(0deg)\"><label class=radio_pill for=r20><i class=\"fa fa-address-card\" style=\"transform: rotateY(0deg)\"></i> Normal</label>";
1439
-    configWindow += "<input name=Settings_Oriteation id=r21 type=radio value=\"rotateY(180deg)\"><label class=radio_pill for=r21><i class=\"fa fa-address-card\" style=\"transform: rotateY(180deg)\"></i> Mirror</label>";
1440
-    configWindow += "</div>";
1441
-    configWindow += "<br><br><div class=UiText>"+ lang.aspect_ratio +":</div>";
1442
-    configWindow += "<div class=pill-nav>";
1443
-    configWindow += "<input name=Settings_AspectRatio id=r10 type=radio value=\"1\"><label class=radio_pill for=r10><i class=\"fa fa-square-o\" style=\"transform: scaleX(1); margin-left: 7px; margin-right: 7px\"></i> 1:1</label>";
1444
-    configWindow += "<input name=Settings_AspectRatio id=r11 type=radio value=\"1.33\"><label class=radio_pill for=r11><i class=\"fa fa-square-o\" style=\"transform: scaleX(1.33); margin-left: 5px; margin-right: 5px;\"></i> 4:3</label>";
1445
-    configWindow += "<input name=Settings_AspectRatio id=r12 type=radio value=\"1.77\"><label class=radio_pill for=r12><i class=\"fa fa-square-o\" style=\"transform: scaleX(1.77); margin-right: 3px;\"></i> 16:9</label>";
1446
-    configWindow += "<input name=Settings_AspectRatio id=r13 type=radio value=\"\"><label class=radio_pill for=r13><i class=\"fa fa-trash\"></i></label>";
1447
-    configWindow += "</div>";
1448
-    configWindow += "<br><br><div class=UiText>"+ lang.preview +":</div>";
1449
-    configWindow += "<div style=\"text-align:center; margin-top:10px\"><video id=\"local-video-preview\" class=\"previewVideo\"></video></div>";
1450
-    configWindow += "<br><div class=UiText>"+ lang.video_conference_extension +":</div>";
1451
-    configWindow += "<div><input id=Video_Conf_Extension class=UiInputText type=text placeholder='"+ lang.video_conference_extension_example +"' value='"+ getDbItem("VidConfExtension", "") +"'></div>";
1452
-    configWindow += "<br><div class=UiText>"+ lang.video_conference_window_width +":</div>";
1453
-    configWindow += "<div><input id=Video_Conf_Window_Width class=UiInputText type=text placeholder='"+ lang.video_conf_window_width_explanation +"' value='"+ getDbItem("VidConfWindowWidth", "") +"'></div>";
1454
-    if (getDbItem("userrole", "") == "superadmin") {
1455
-
1456
-	configWindow += "<div id=confTableSection>"+ lang.external_conf_users +"</div>";
1457
-        configWindow += "<div class=confTable><table id=vidConfExternalTable>";
1458
-        configWindow += "<tr class=btnTableRow><td><label for=extConfExtension id=extensionThLabel class=confExtLabels>Extension</label></td><td><label for=extConfExtensionPass id=extPassThLabel class=confExtLabels>SIP Password</label></td><td><label for=extConfExtensionLink id=extLinkThLabel class=confExtLabels>Link</label></td></tr>";
1459
-
1460
-        for (var cqt = 0; cqt < getDbItem("externalUserConfElem", ""); cqt++) {
1461
-	     configWindow += "<tr class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension value='"+ getDbItem('extUserExtension-'+cqt, '') +"' disabled=\"disabled\" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass value='"+ getDbItem('extUserExtensionPass-'+cqt, '') +"' disabled=\"disabled\"/></td><td><input type=text class=extConfExtensionLink name=extConfExtensionLink value='"+ getDbItem('confAccessLink-'+cqt, '') +"' /></td><td><span class=\"copyToClipboard\"><i class=\"fa fa-clipboard\" aria-hidden=\"true\" title=\"Copy link to clipboard.\"></i></span></td><td><span class=\"deleteExtRow\" title=\"Delete extension data from database.\">X</span></td><td><input type=submit class=saveExtConfExtension value=\"Edit\" title=\"Edit this row.\" /></td></tr>";
1462
-        }
1463
-
1464
-	configWindow += "<tr id=emptyExtRow class=btnTableRow><td><input type=text class=extConfExtension name=extConfExtension placeholder=\"Eg: 711\" /></td><td><input type=password class=extConfExtensionPass name=extConfExtensionPass placeholder=\"Eg: d5?W?9q?8rg*R9!eFrVth?9\" /></td><td><input type=text class=extConfExtensionLink name=extConfExtensionLink placeholder=\"Generated on 'Save'\"  disabled=\"disabled\" /></td><td><span class=\"copyToClipboard\"><i class=\"fa fa-clipboard\" aria-hidden=\"true\" title=\"Copy link to clipboard.\"></i></span></td><td><span class=\"deleteExtRow deleteExtRowDisabled\" title=\"Delete extension data from database.\">X</span></td><td><input type=submit class=saveExtConfExtension value=Save title=\"Save this row.\" /></td></tr>";
1465
-        configWindow += "</table></div>";
1466
-	configWindow += "<button id=add_New_External_User>Add External User</button>";
1467
-    }
1468
-    configWindow += "<br><br></div>";
1469
-
1470
-    configWindow += "<div id=\"AppearanceHtml\" class=\"settingsSubSection\" style=\"display:none;\">";
1471
-    configWindow += "<div id=ImageCanvas style=\"width:150px; height:150px;\"></div>";
1472
-    configWindow += "<label for=fileUploader class=customBrowseButton style=\"margin-left: 200px; margin-top: -2px;\">Select File</label>";
1473
-    configWindow += "<div><input id=fileUploader type=file></div>";
1474
-    configWindow += "<div style=\"margin-top: 50px\"></div>";
1475
-    configWindow += "</div>";
1476
-
1477
-    configWindow += "<div id=\"NotificationsHtml\" class=\"settingsSubSection\" style=\"display:none;\">";
1478
-    configWindow += "<div class=UiText>"+ lang.notifications +":</div>";
1479
-    configWindow += "<div id=\"notificationsCheck\"><input type=checkbox id=Settings_Notifications><label for=Settings_Notifications> "+ lang.enable_onscreen_notifications +"<label></div>";
1480
-    configWindow += "</div>";
1481
-
1482
-    configWindow += "<div id=\"RoundcubeEmailHtml\" class=\"settingsSubSection\" style=\"display:none;\">";
1483
-    configWindow += "<div class=UiText>"+ lang.email_integration +":</div>";
1484
-    configWindow += "<div id=\"enableRCcheck\"><input id=emailIntegration type=checkbox ><label for=emailIntegration> "+ lang.enable_roundcube_integration +"<label></div>";
1485
-    configWindow += "<div class=UiText>"+ lang.roundcube_domain +":</div>";
1486
-    configWindow += "<div><input id=RoundcubeDomain class=UiInputText type=text placeholder='Roundcube domain (Eg: mail.example.com).' value='"+ getDbItem("rcDomain", "") +"'></div>";
1487
-    configWindow += "<div class=UiText>"+ lang.roundcube_user +":</div>";
1488
-    configWindow += "<div><input id=RoundcubeUser class=UiInputText type=text placeholder='Roundcube login user (Eg: john.doe@example.com or john_doe).' value='"+ getDbItem("RoundcubeUser", "") +"'></div>";
1489
-    configWindow += "<div class=UiText>"+ lang.roundcube_password +":</div>";
1490
-    configWindow += "<div><input id=RoundcubePass class=UiInputText type=password placeholder='Roundcube login password.' value='"+ getDbItem("RoundcubePass", "") +"'></div>";
1491
-    configWindow += "<div class=UiText>"+ lang.rc_basic_auth_user +":</div>";
1492
-    configWindow += "<div><input id=rcBasicAuthUser class=UiInputText type=text placeholder='If you have a Roundcube basic auth user, enter it here.' value='"+ getDbItem("rcBasicAuthUser", "") +"'></div>";
1493
-    configWindow += "<div class=UiText>"+ lang.rc_basic_auth_password +":</div>";
1494
-    configWindow += "<div><input id=rcBasicAuthPass class=UiInputText type=password placeholder='If you have a Roundcube basic auth password, enter it here.' value='"+ getDbItem("rcBasicAuthPass", "") +"'></div>";
1495
-
1496
-    configWindow += "<br><br></div>";
1497
-
1498
-    configWindow += "<div id=\"ChangePasswordHtml\" class=\"settingsSubSection\" style=\"display:none;\">";
1499
-    configWindow += "<div class=UiText>"+ lang.current_user_password +":</div>";
1500
-    configWindow += "<div><input id=Current_User_Password class=UiInputText type=password placeholder='Enter your current Roundpin user password.' value=''></div>";
1501
-    configWindow += "<div class=UiText>"+ lang.new_user_password +":</div>";
1502
-    configWindow += "<div><input id=New_User_Password class=UiInputText type=password placeholder='Enter your new Roundpin user password.' value=''></div>";
1503
-    configWindow += "<div class=UiText>"+ lang.repeat_new_user_password +":</div>";
1504
-    configWindow += "<div><input id=Repeat_New_User_Password class=UiInputText type=password placeholder='Enter your new Roundpin user password again.' value=''></div><br>";
1505
-    configWindow += "<div><input id=Save_New_User_Password type=button value='Save New Password' onclick='saveNewUserPassword()' ></div>";
1506
-    configWindow += "<br><br></div>";
1507
-
1508
-    configWindow += "<div id=\"ChangeEmailHtml\" class=\"settingsSubSection\" style=\"display:none;\">";
1509
-    configWindow += "<div class=UiText>"+ lang.current_user_email +":</div>";
1510
-    configWindow += "<div><input id=Current_User_Email class=UiInputText type=text placeholder='Enter your current Roundpin email address.' value=''></div>";
1511
-    configWindow += "<div class=UiText>"+ lang.new_user_email +":</div>";
1512
-    configWindow += "<div><input id=New_User_Email class=UiInputText type=text placeholder='Enter your new email address.' value=''></div>";
1513
-    configWindow += "<div class=UiText>"+ lang.repeat_new_user_email +":</div>";
1514
-    configWindow += "<div><input id=Repeat_New_User_Email class=UiInputText type=text placeholder='Enter your new email address again.' value=''></div><br>";
1515
-    configWindow += "<div><input id=Save_New_User_Email type=button value='Save New Email' onclick='saveNewUserEmail()' ></div>";
1516
-    configWindow += "<br><br></div>";
1517
-
1518
-    configWindow += "<div id=\"CloseAccountHtml\" class=\"settingsSubSection\" style=\"display:none;\">";
1519
-    configWindow += "<div class=UiText>"+ lang.if_you_want_to_close_account +":</div><br><br>";
1520
-    configWindow += "<div><input id=Close_User_Account type=button value='Close User Account' onclick='closeUserAccount()' ></div>";
1521
-    configWindow += "<br><br></div>";
1522
-
1523
-    configWindow += "</div></div></div>";
1524
-
1525
-    var settingsSections = "<table id=leftPanelSettings cellspacing=14 cellpadding=0 style=\"width:184px;margin-left:8px;margin-top:14px;font-size:15px;\">";
1526
-    settingsSections += "<tr id=ConnectionSettingsRow><td class=SettingsSection>Connection Settings</td></tr>";
1527
-    settingsSections += "<tr id=AudioAndVideoRow><td class=SettingsSection>Audio & Video</td></tr>";
1528
-    settingsSections += "<tr id=ProfilePictureRow><td class=SettingsSection>Profile Picture</td></tr>";
1529
-    settingsSections += "<tr id=NotificationsRow><td class=SettingsSection>Notifications</td></tr>";
1530
-    settingsSections += "<tr id=RoundcubeEmailRow><td class=SettingsSection>Email Integration</td></tr>";
1531
-    settingsSections += "<tr id=ChangePasswordRow><td class=SettingsSection>Change Password</td></tr>";
1532
-    settingsSections += "<tr id=ChangeEmailRow><td class=SettingsSection>Change Email</td></tr>";
1533
-    settingsSections += "<tr id=CloseAccountRow><td class=SettingsSection>Close Account</td></tr></table>";
1534
-
1535
-    $.jeegoopopup.open({
1536
-                title: '<span id=settingsTitle>Settings</span>',
1537
-                html: configWindow,
1538
-                width: '520',
1539
-                height: '500',
1540
-                center: true,
1541
-                scrolling: 'no',
1542
-                skinClass: 'jg_popup_basic',
1543
-                contentClass: 'configPopup',
1544
-                overlay: true,
1545
-                opacity: 50,
1546
-                draggable: true,
1547
-                resizable: false,
1548
-                fadeIn: 0
1549
-    });
1550
-
1551
-    $("#jg_popup_b").append('<div id="bottomButtonsConf"><button id="save_button_conf">Save</button><button id="cancel_button_conf">Cancel</button></div>');
1552
-    $("#jg_popup_l").append(settingsSections);
1553
-
1554
-    if (getDbItem("useRoundcube", "") == 1) { $("#emailIntegration").prop("checked", true); } else { $("#emailIntegration").prop("checked", false); }
1555
-
1556
-    $("#ConnectionSettingsRow td").addClass("selectedSettingsSection");
1557
-
1558
-    $("#ConnectionSettingsRow").click(function() {
1559
-        $(".settingsSubSection").each(function() { $(this).css("display", "none"); });
1560
-        $("#AccountHtml").css("display", "block");
1561
-        $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); });
1562
-        $("#ConnectionSettingsRow td").addClass("selectedSettingsSection");
1563
-    });
1564
-
1565
-    $("#ProfilePictureRow").click(function() {
1566
-        $(".settingsSubSection").each(function() { $(this).css("display", "none"); });
1567
-        $("#AppearanceHtml").css("display", "block");
1568
-        $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); });
1569
-        $("#ProfilePictureRow td").addClass("selectedSettingsSection");
1570
-    });
1571
-
1572
-    $("#NotificationsRow").click(function() {
1573
-        $(".settingsSubSection").each(function() { $(this).css("display", "none"); });
1574
-        $("#NotificationsHtml").css("display", "block");
1575
-        $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); });
1576
-        $("#NotificationsRow td").addClass("selectedSettingsSection");
1577
-    });
1578
-
1579
-    $("#RoundcubeEmailRow").click(function() {
1580
-        $(".settingsSubSection").each(function() { $(this).css("display", "none"); });
1581
-        $("#RoundcubeEmailHtml").css("display", "block");
1582
-        $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); });
1583
-        $("#RoundcubeEmailRow td").addClass("selectedSettingsSection");
1584
-    });
1585
-
1586
-    $("#ChangePasswordRow").click(function() {
1587
-        $(".settingsSubSection").each(function() { $(this).css("display", "none"); });
1588
-        $("#ChangePasswordHtml").css("display", "block");
1589
-        $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); });
1590
-        $("#ChangePasswordRow td").addClass("selectedSettingsSection");
1591
-    });
1592
-
1593
-    $("#ChangeEmailRow").click(function() {
1594
-        $(".settingsSubSection").each(function() { $(this).css("display", "none"); });
1595
-        $("#ChangeEmailHtml").css("display", "block");
1596
-        $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); });
1597
-        $("#ChangeEmailRow td").addClass("selectedSettingsSection");
1598
-    });
1599
-
1600
-    $("#CloseAccountRow").click(function() {
1601
-        $(".settingsSubSection").each(function() { $(this).css("display", "none"); });
1602
-        $("#CloseAccountHtml").css("display", "block");
1603
-        $(".SettingsSection").each(function() { $(this).removeClass("selectedSettingsSection"); });
1604
-        $("#CloseAccountRow td").addClass("selectedSettingsSection");
1605
-    });
1606
-
1607
-    var maxWidth = $(window).width() - 192;
1608
-    var maxHeight = $(window).height() - 98;
1609
-
1610
-    if (maxWidth < 520 || maxHeight < 500) { 
1611
-       $.jeegoopopup.width(maxWidth).height(maxHeight);
1612
-       $.jeegoopopup.center();
1613
-       $("#maximizeImg").hide();
1614
-       $("#minimizeImg").hide();
1615
-    } else { 
1616
-       $.jeegoopopup.width(520).height(500);
1617
-       $.jeegoopopup.center();
1618
-       $("#minimizeImg").hide();
1619
-       $("#maximizeImg").show();
1620
-    }
1621
-
1622
-    $(window).resize(function() {
1623
-       maxWidth = $(window).width() - 192;
1624
-       maxHeight = $(window).height() - 98;
1625
-       $.jeegoopopup.center();
1626
-       if (maxWidth < 520 || maxHeight < 500) { 
1627
-           $.jeegoopopup.width(maxWidth).height(maxHeight);
1628
-           $.jeegoopopup.center();
1629
-           $("#maximizeImg").hide();
1630
-           $("#minimizeImg").hide();
1631
-       } else { 
1632
-           $.jeegoopopup.width(520).height(500);
1633
-           $.jeegoopopup.center();
1634
-           $("#minimizeImg").hide();
1635
-           $("#maximizeImg").show();
1636
-       }
1637
-    });
1638
-
1639
-    $("#minimizeImg").click(function() { $.jeegoopopup.width(520).height(500); $.jeegoopopup.center(); $("#maximizeImg").show(); $("#minimizeImg").hide(); });
1640
-    $("#maximizeImg").click(function() { $.jeegoopopup.width(maxWidth).height(maxHeight); $.jeegoopopup.center(); $("#minimizeImg").show(); $("#maximizeImg").hide(); });
1641
-
1642
-
1643
-    // Output
1644
-    var selectAudioScr = $("#playbackSrc");
1645
-
1646
-    var playButton = $("#preview_output_play");
1647
-
1648
-    var playRingButton = $("#preview_ringer_play");
1649
-
1650
-    var pauseButton = $("#preview_output_pause");
1651
-
1652
-    // Microphone
1653
-    var selectMicScr = $("#microphoneSrc");
1654
-    $("#Settings_AutoGainControl").prop("checked", AutoGainControl);
1655
-    $("#Settings_EchoCancellation").prop("checked", EchoCancellation);
1656
-    $("#Settings_NoiseSuppression").prop("checked", NoiseSuppression);
1657
-
1658
-    // Webcam
1659
-    var selectVideoScr = $("#previewVideoSrc");
1660
-
1661
-    // Orientation
1662
-    var OrientationSel = $("input[name=Settings_Oriteation]");
1663
-    OrientationSel.each(function(){
1664
-        if(this.value == MirrorVideo) $(this).prop("checked", true);
1665
-    });
1666
-    $("#local-video-preview").css("transform", MirrorVideo);
1667
-
1668
-    // Frame Rate
1669
-    var frameRateSel = $("input[name=Settings_FrameRate]");
1670
-    frameRateSel.each(function(){
1671
-        if(this.value == maxFrameRate) $(this).prop("checked", true);
1672
-    });
1673
-
1674
-    // Quality
1675
-    var QualitySel = $("input[name=Settings_Quality]");
1676
-    QualitySel.each(function(){
1677
-        if(this.value == videoHeight) $(this).prop("checked", true);
1678
-    });
1679
-
1680
-    // Aspect Ratio
1681
-    var AspectRatioSel = $("input[name=Settings_AspectRatio]");
1682
-    AspectRatioSel.each(function(){
1683
-        if(this.value == videoAspectRatio) $(this).prop("checked", true);
1684
-    });
1685
-
1686
-    // Ring Tone
1687
-    var selectRingTone = $("#ringTone");
1688
-
1689
-    // Ring Device
1690
-    var selectRingDevice = $("#ringDevice");
1691
-
1692
-    // Handle Aspect Ratio Change
1693
-    AspectRatioSel.change(function(){
1694
-        console.log("Call to change Aspect Ratio ("+ this.value +")");
1695
-
1696
-        var localVideo = $("#local-video-preview").get(0);
1697
-        localVideo.muted = true;
1698
-        localVideo.playsinline = true;
1699
-        localVideo.autoplay = true;
1700
-
1701
-        var tracks = localVideo.srcObject.getTracks();
1702
-        tracks.forEach(function(track) {
1703
-            track.stop();
1704
-        });
1705
-
1706
-        var constraints = {
1707
-            audio: false,
1708
-            video: {
1709
-                deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default"
1710
-            }
1711
-        }
1712
-        if($("input[name=Settings_FrameRate]:checked").val() != ""){
1713
-            constraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val();
1714
-        }
1715
-        if($("input[name=Settings_Quality]:checked").val() != ""){
1716
-            constraints.video.height = $("input[name=Settings_Quality]:checked").val();
1717
-        }
1718
-        if(this.value != ""){
1719
-            constraints.video.aspectRatio = this.value;
1720
-        }        
1721
-        console.log("Constraints:", constraints);
1722
-        var localStream = new MediaStream();
1723
-        if(navigator.mediaDevices){
1724
-            navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){
1725
-                var videoTrack = newStream.getVideoTracks()[0];
1726
-                localStream.addTrack(videoTrack);
1727
-                localVideo.srcObject = localStream;
1728
-                localVideo.onloadedmetadata = function(e) {
1729
-                    localVideo.play();
1730
-                }
1731
-            }).catch(function(e){
1732
-                console.error(e);
1733
-                AlertConfigExtWindow(lang.alert_error_user_media, lang.error);
1734
-            });
1735
-        }
1736
-    });
1737
-
1738
-    // Handle Video Height Change
1739
-    QualitySel.change(function(){    
1740
-        console.log("Call to change Video Height ("+ this.value +")");
1741
-
1742
-        var localVideo = $("#local-video-preview").get(0);
1743
-        localVideo.muted = true;
1744
-        localVideo.playsinline = true;
1745
-        localVideo.autoplay = true;
1746
-
1747
-        var tracks = localVideo.srcObject.getTracks();
1748
-        tracks.forEach(function(track) {
1749
-            track.stop();
1750
-        });
1751
-
1752
-        var constraints = {
1753
-            audio: false,
1754
-            video: {
1755
-                deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" ,
1756
-            }
1757
-        }
1758
-        if($("input[name=Settings_FrameRate]:checked").val() != ""){
1759
-            constraints.video.frameRate = $("input[name=Settings_FrameRate]:checked").val();
1760
-        }
1761
-        if(this.value){
1762
-            constraints.video.height = this.value;
1763
-        }
1764
-        if($("input[name=Settings_AspectRatio]:checked").val() != ""){
1765
-            constraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val();
1766
-        } 
1767
-        console.log("Constraints:", constraints);
1768
-        var localStream = new MediaStream();
1769
-        if(navigator.mediaDevices){
1770
-            navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){
1771
-                var videoTrack = newStream.getVideoTracks()[0];
1772
-                localStream.addTrack(videoTrack);
1773
-                localVideo.srcObject = localStream;
1774
-                localVideo.onloadedmetadata = function(e) {
1775
-                    localVideo.play();
1776
-                }
1777
-            }).catch(function(e){
1778
-                console.error(e);
1779
-                AlertConfigExtWindow(lang.alert_error_user_media, lang.error);
1780
-            });
1781
-        }
1782
-    });    
1783
-
1784
-    // Handle Frame Rate Change 
1785
-    frameRateSel.change(function(){
1786
-        console.log("Call to change Frame Rate ("+ this.value +")");
1787
-
1788
-        var localVideo = $("#local-video-preview").get(0);
1789
-        localVideo.muted = true;
1790
-        localVideo.playsinline = true;
1791
-        localVideo.autoplay = true;
1792
-
1793
-        var tracks = localVideo.srcObject.getTracks();
1794
-        tracks.forEach(function(track) {
1795
-            track.stop();
1796
-        });
1797
-
1798
-        var constraints = {
1799
-            audio: false,
1800
-            video: {
1801
-                deviceId: (selectVideoScr.val() != "default")? { exact: selectVideoScr.val() } : "default" ,
1802
-            }
1803
-        }
1804
-        if(this.value != ""){
1805
-            constraints.video.frameRate = this.value;
1806
-        }
1807
-        if($("input[name=Settings_Quality]:checked").val() != ""){
1808
-            constraints.video.height = $("input[name=Settings_Quality]:checked").val();
1809
-        }
1810
-        if($("input[name=Settings_AspectRatio]:checked").val() != ""){
1811
-            constraints.video.aspectRatio = $("input[name=Settings_AspectRatio]:checked").val();
1812
-        } 
1813
-        console.log("Constraints:", constraints);
1814
-        var localStream = new MediaStream();
1815
-        if(navigator.mediaDevices){
1816
-            navigator.mediaDevices.getUserMedia(constraints).then(function(newStream){
1817
-                var videoTrack = newStream.getVideoTracks()[0];
1818
-                localStream.addTrack(videoTrack);
1819
-                localVideo.srcObject = localStream;
1820
-                localVideo.onloadedmetadata = function(e) {
1821
-                    localVideo.play();
1822
-                }
1823
-            }).catch(function(e){
1824
-                console.error(e);
1825
-                AlertConfigExtWindow(lang.alert_error_user_media, lang.error);
1826
-            });
1827
-        }
1828
-    });
1829
-
1830
-    // Handle Audio Source changes (Microphone)
1831
-    selectMicScr.change(function(){
1832
-        console.log("Call to change Microphone ("+ this.value +")");
1833
-
1834
-        // Change and update visual preview
1835
-        try{
1836
-            var tracks = window.SettingsMicrophoneStream.getTracks();
1837
-            tracks.forEach(function(track) {
1838
-                track.stop();
1839
-            });
1840
-            window.SettingsMicrophoneStream = null;
1841
-        }
1842
-        catch(e){}
1843
-
1844
-        try{
1845
-            soundMeter = window.SettingsMicrophoneSoundMeter;
1846
-            soundMeter.stop();
1847
-            window.SettingsMicrophoneSoundMeter = null;
1848
-        }
1849
-        catch(e){}
1850
-
1851
-        // Get Microphone
1852
-        var constraints = { 
1853
-            audio: {
1854
-                deviceId: { exact: this.value }
1855
-            }, 
1856
-            video: false 
1857
-        }
1858
-        var localMicrophoneStream = new MediaStream();
1859
-        navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream){
1860
-            var audioTrack = mediaStream.getAudioTracks()[0];
1861
-            if(audioTrack != null){
1862
-                // Display Microphone Levels
1863
-                localMicrophoneStream.addTrack(audioTrack);
1864
-                window.SettingsMicrophoneStream = localMicrophoneStream;
1865
-                window.SettingsMicrophoneSoundMeter = MeterSettingsOutput(localMicrophoneStream, "Settings_MicrophoneOutput", "width", 50);
1866
-            }
1867
-        }).catch(function(e){
1868
-            console.log("Failed to getUserMedia", e);
1869
-        });
1870
-    });
1871
-
1872
-    // Handle output change (speaker)
1873
-    selectAudioScr.change(function(){
1874
-        console.log("Call to change Speaker ("+ this.value +")");
1875