puvox-library 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2744 @@
1
+ /**
2
+ *
3
+ * ####################################################################################
4
+ * ################################# Our JS Library ################################
5
+ * ####### Here we collect frequently used methods across our JS applications. #######
6
+ * ####### (Some of them are generic javascript functions, some are for NodeJS) #######
7
+ * ####################################################################################
8
+ *
9
+ * ########## Example usage: ##########
10
+ * const helpers = new PuvoxLibrary();
11
+ * console.log ( helpers.get_last_child_of_array(array) );
12
+ * console.log ( helpers.get_visitor_ip() );
13
+ * ... etc
14
+ *
15
+ */
16
+
17
+ const puvox_library =
18
+ {
19
+ // ########## ARRAY ########## //
20
+ arrayValue(obj_arr, key, default_){
21
+ return (key in obj_arr ? obj_arr[key] : default_);
22
+ },
23
+ case(val, case_upper_lower){
24
+ let case_ = case_upper_lower || null;
25
+ if (case_ == null) return val;
26
+ else return ( case_ ? val.toUpperCase() : val.toLowerCase() );
27
+ },
28
+ arrayValueCased(obj_arr, key, default_, case_upper_lower){
29
+ let res = this.arrayValue(obj_arr, key, default_);
30
+ return ( res==null ? null : this.case(res, case_upper_lower) );
31
+ },
32
+ stringToArray(str, splitChar){
33
+ var splitChar= splitChar || '|';
34
+ let parts = str.split(splitChar);
35
+ return parts;
36
+ },
37
+ arrayColumn(array, columnName) {
38
+ return array.map(function(value,index) {
39
+ return value[columnName];
40
+ })
41
+ },
42
+ arrayUnique(array, removeEmpties){
43
+ //let uniqueItems = [...new Set(items)]
44
+ let res = array.filter(function(item, pos) {
45
+ return array.indexOf(item) == pos;
46
+ });
47
+ return (removeEmpties ? this.arrayRemoveEmpty(res) : res);
48
+ },
49
+ arrayMerge(ar1,ar2){
50
+ return ar1.concat(ar2);
51
+ },
52
+ objectsArrayTill(arrayBlocks, key, value)
53
+ {
54
+ let newArr = this.isObject(arrayBlocks) ? {} : [];
55
+ for(let [key_1,obj_1] of Object.entries(arrayBlocks))
56
+ {
57
+ if (key in obj_1 && obj_1[key]===value)
58
+ {
59
+ break;
60
+ }
61
+ newArr[key_1] = obj_1;
62
+ }
63
+ return newArr;
64
+ },
65
+ arrayRemoveEmpty(array){ return array.filter(item => item); },
66
+ arrayLastMember(arr){ return arr[arr.length-1]; },
67
+ arrayLastItem(arr){ return this.arrayLastMember(arr); },
68
+ removeKeys(obj, keysArr){
69
+ let newObj ={};
70
+ for (let [key,val] of Object.entries(obj)){
71
+ if (!this.inArray(keysArr,key))
72
+ newObj[key]=val;
73
+ }
74
+ return newObj;
75
+ },
76
+ removeKeysExcept (obj, keysArr){
77
+ let newObj ={};
78
+ for (let [key,val] of Object.entries(obj)){
79
+ if (this.inArray(keysArr,key))
80
+ newObj[key]=val;
81
+ }
82
+ return newObj;
83
+ },
84
+ arrayDiff(source, comparedTo){
85
+ return source.filter(x => !comparedTo.includes(x));
86
+ },
87
+ arrayIntersect(source, comparedTo){
88
+ return source.filter(x => comparedTo.includes(x));
89
+ },
90
+ arrayDiffFull(o1,o2) {
91
+ const self = this;
92
+ const typeObject = function(o){
93
+ return typeof o === 'object';
94
+ };
95
+ const bothAreObjects = (o1,o2) =>{
96
+ return (typeObject(o1) && typeObject(o2));
97
+ };
98
+ const bothAreArrays = (o1,o2) =>{
99
+ return (this.isArray(o1) && this.isArray(o2));
100
+ };
101
+ const diff = function (o1, o2) {
102
+ const result = {};
103
+ // if first is item is not object
104
+ if (!typeObject(o1) && typeObject(o2)) {
105
+ return o2;
106
+ }
107
+ // if second is item is not object
108
+ else if (typeObject(o1) && !typeObject(o2)) {
109
+ return undefined;
110
+ }
111
+ // if they are equal
112
+ else if (Object.is(o1, o2)) {
113
+ return undefined;
114
+ } else if (bothAreArrays(o1,o2)){
115
+ return self.arrayDiff(o1,o2);
116
+ }
117
+ const keys = Object.keys(o2);
118
+ for (let i=0; i<keys.length; i++) {
119
+ const key = keys[i];
120
+ // if both are objects
121
+ if ( bothAreObjects(o1[key],o2[key])) {
122
+ // if equal, return nothing
123
+ if ( Object.is(o1[key], o2[key]) ) {
124
+ // do nothing
125
+ } else if (o1[key] === o2[key]) {
126
+ // do nothing
127
+ } else {
128
+ result[key] = diff(o1[key],o2[key]);
129
+ }
130
+ } else if (bothAreArrays(o1[key],o2[key])) {
131
+ result[key] = diff(o1[key],o2[key]);
132
+ } else if (o1[key] !== o2[key]) {
133
+ result[key] = o2[key];
134
+ } else {
135
+ // do nothing
136
+ }
137
+ }
138
+ return result;
139
+ };
140
+ return [
141
+ diff(o1,o2),
142
+ diff(o2,o1),
143
+ ];
144
+ },
145
+ sortKeys (x, out = {}) {
146
+ for (const k of Object.keys (x).sort ()) {
147
+ out[k] = x[k]
148
+ }
149
+ return out
150
+ },
151
+ stringArrayToNumeric(arr){
152
+ let newArr = [];
153
+ for(let i=0; i<arr.length; i++){
154
+ newArr.push( parseFloat(arr[i]) );
155
+ }
156
+ return newArr;
157
+ },
158
+ stringToArrayToNumeric(arr){
159
+ return this.stringArrayToNumeric(this.stringToArray(arr));
160
+ },
161
+
162
+ // https://stackoverflow.com/a/44782052/2377343
163
+ cloneObjectDestructuve(orig){
164
+ return Object.assign(Object.create(Object.getPrototypeOf(orig)), orig);
165
+ },
166
+ // https://stackoverflow.com/a/41474987/2377343
167
+ cloneObjectWithPrototype(orig){
168
+ const clone = Object.assign( Object.create(orig), orig );
169
+ Object.setPrototypeOf( clone, Blah.prototype );
170
+ return clone;
171
+ },
172
+ getKeyByValue (object, value) {
173
+ const keys = Object.keys (object);
174
+ for (let i = 0; i < keys.length; i++) {
175
+ const key = keys[i];
176
+ if (object[key] === value) {
177
+ return key;
178
+ }
179
+ }
180
+ return undefined;
181
+ },
182
+ hasChildWithKeyValue (obj, targetKey, targetValue) {
183
+ const keys = Object.keys (obj);
184
+ for (let i = 0; i < keys.length; i++) {
185
+ const currentKey = keys[i];
186
+ const childMember = obj[currentKey];
187
+ const value = this.safeInteger (childMember, targetKey, undefined);
188
+ if (value === targetValue) {
189
+ return true;
190
+ }
191
+ }
192
+ return false;
193
+ },
194
+
195
+
196
+
197
+
198
+
199
+ trigger_on_load(callerr, onInteractionInsteadComplete)
200
+ {
201
+ var stage=stage || 1;
202
+ if (onInteractionInsteadComplete || true){
203
+ document.addEventListener('readystatechange', event => {
204
+ if (event.target.readyState === "interactive") { //same as: document.addEventListener("DOMContentLoaded"
205
+ callerr(); //"All HTML DOM elements are accessible"
206
+ }
207
+ });
208
+ }
209
+ else{
210
+ document.addEventListener('readystatechange', event => {
211
+ if (event.target.readyState === "complete") {
212
+ callerr(); //"Now external resources are loaded too, like css,src etc... "
213
+ }
214
+ });
215
+ }
216
+ },
217
+
218
+ // setTimeout( window[arguments.callee.name.toString() ], 500);
219
+
220
+ // lazyload images
221
+ imagesLazyLoad(el_tag){
222
+ jQuery(el_tag).each( function(){
223
+ // set the img src from data-src
224
+ jQuery( this ).attr( 'src', jQuery( this ).attr( 'data-src' ) );
225
+ }
226
+ );
227
+ },
228
+
229
+ move_to_top_in_parent (el_tag)
230
+ {
231
+ $(el_tag).each(function() {
232
+ $(this).parent().prepend(this);
233
+ });
234
+ },
235
+
236
+ //window.onload REPLACEMENT Both methods are used to achieve the same goal of attaching an event to an element.
237
+ // ttachEvent can only be used on older trident rendering engines ( IE5+ IE5-8*) and addEventListener is a W3 standard that is implemented in the majority of other browsers (FF, Webkit, Opera, IE9+).
238
+ // window.addEventListener ? window.addEventListener("load",yourFunction,false) : window.attachEvent && window.attachEvent("onload",yourFunction);
239
+
240
+
241
+ // Append Style/Script In Head
242
+ Append_To_Head2(elemntType, content){
243
+ // if provided conent is "link" or "inline codes"
244
+ var Is_Link = content.split(/\r\n|\r|\n/).length <= 1 && content.indexOf("/") > -1 && (content.substring(0, 4)=='http' || content.substring(0, 2)=='//' || content.substring(0, 2)=='./' || content.substring(0, 1)=='/' );
245
+ if(Is_Link){
246
+ //assign temporary id
247
+ var id= encodeURI( content.split('/').reverse()[0] ); //encodeURI(content.replace(/[\W_]+/g,"-"));
248
+ if (!document.getElementById(id)){
249
+ if (elemntType=='script') { var x=document.createElement('script');x.id=id; x.src=content; x.type='text/javascript'; }
250
+ else if (elemntType=='style'){ var x=document.createElement('link'); x.id=id; x.href=content; x.type='text/css'; x.rel = 'stylesheet'; }
251
+ }
252
+ }
253
+ else{
254
+ var x = document.createElement(elemntType);
255
+ if (elemntType=='script') { x.type='text/javascript'; x.innerHTML = content; }
256
+ else if (elemntType=='style'){ x.type='text/css'; if (x.styleSheet){ x.styleSheet.cssText=content; } else { x.appendChild(document.createTextNode(content)); } }
257
+ }
258
+ //append in head
259
+ (document.head || document.getElementsByTagName('head')[0]).appendChild(x);
260
+ },
261
+ Append_To_Head(elemntType, content) {
262
+ var Is_Link = content.split(/\r\n|\r|\n/).length <= 1 && content.indexOf("/") > -1 && (content.substring(0, 4) == 'http' || content.substring(0, 2) == '//' || content.substring(0, 2) == './' || content.substring(0, 1) == '/');
263
+ if (Is_Link) {
264
+ var id = encodeURI(content.replace(/[\W_]+/g,"-"));
265
+ if (!document.getElementById(id)) {
266
+ if (elemntType == 'script') {
267
+ var x = document.createElement('script');
268
+ x.id = id;
269
+ document.head.appendChild(x);
270
+ x.onload = function () {};
271
+ x.src = content;
272
+ } else if (elemntType == 'style') {
273
+ var x = document.createElement('link');
274
+ x.id = id;
275
+ x.href = content;
276
+ x.type = 'text/css';
277
+ x.rel = 'stylesheet';
278
+ document.head.appendChild(x);
279
+ }
280
+ }
281
+ } else {
282
+ var x = document.createElement(elemntType);
283
+ if (elemntType == 'script') {
284
+ x.type = 'text/javascript';
285
+ x.innerHTML = content;
286
+ } else if (elemntType == 'style') {
287
+ x.type = 'text/css';
288
+ if (x.styleSheet) {
289
+ x.styleSheet.cssText = content;
290
+ } else {
291
+ x.appendChild(document.createTextNode(content));
292
+ }
293
+ }
294
+ document.head.appendChild(x);
295
+ }
296
+ },
297
+ // loadScript
298
+ appendScript(url, callback, defer=false){
299
+ var script = document.createElement('script');
300
+ script.onload = (callback || function(){});
301
+ script.src = url;
302
+ if (defer)
303
+ script.defer = true;
304
+ document.head.appendChild(script);
305
+ },
306
+ appendScript2(url){
307
+ var script = document.createElement('script');
308
+ document.head.appendChild(script);
309
+ script.onload = function () { };
310
+ script.src = url;
311
+ },
312
+
313
+ blackground2(){
314
+ var innerDiv = document.createElement("div"); innerDiv.id = "my_black_backgr";
315
+ innerDiv.setAttribute("style", "background:black; height:4000px; left:0px; opacity:0.9; position:fixed; top:0px; width:100%; z-index:9990;");
316
+ var BODYYY = document.body; BODYYY.insertBefore(innerDiv, BODYYY.childNodes[0]);
317
+ },
318
+
319
+ getFileExtension(filename){
320
+ var ext = filename.split('.').pop();
321
+ return (ext===filename) ? '' : ext;
322
+ },
323
+
324
+ // stackoverflow -best foreach
325
+ forEach(collection, callback, scope) {
326
+ if (Object.prototype.toString.call(collection) === '[object Object]') {
327
+ for (var prop in collection) {
328
+ if (Object.prototype.hasOwnProperty.call(collection, prop)) {
329
+ callback.call(scope, collection[prop], prop, collection);
330
+ }
331
+ }
332
+ } else {
333
+ for (var i = 0, len = collection.length; i < len; i++) {
334
+ callback.call(scope, collection[i], i, collection);
335
+ }
336
+ }
337
+ },
338
+
339
+ // ################
340
+ sanitize(str){ return str.trim().replace( /[^a-zA-Z0-9_\-]/g, "_"); },
341
+ sanitize_key(str, use_dash){ return str.trim().toLowerCase().replace( /[^a-z0-9_\-]/g, (use_dash===true ? '_' : (use_dash ? use_dash :'')) ); }, //same as wp
342
+ sanitize_key_dashed(str){ return this.sanitize_key(str, true).replace(/__/g,'_'); },
343
+ sanitize_variable_name(str)
344
+ {
345
+ return this.strip_non_word(str).replace(/-/g,"_");
346
+ },
347
+ sanitize_text(str, use_dash=false) { return str.trim().replace(/[^a-zA-Z0-9]+/g, (use_dash ? "_":"") ); },
348
+
349
+ //nonword
350
+ strip_non_word(str)
351
+ {
352
+ return str.replace(/[\W_]+/g,"-");
353
+ },
354
+ removeAllWhitespaces(content){ return content.replace(/\s/g,''); },
355
+
356
+ // ####################### TYPE ##############################
357
+
358
+ getVariableType(x) {
359
+ if (this.isInteger(x)) return "integer";
360
+ else if (this.isDecimal(x)) return "float";
361
+ else if (this.isBoolean(x)) return "boolean"; //at first, priority to bool, because of "true" and "false" strings
362
+ else if (this.isString(x)) return "string";
363
+ else if (this.isArray(x)) return "array";
364
+ else if (this.isObject(x)) return "object";
365
+ return typeof x;
366
+ },
367
+ isInteger(x) { return Number.isInteger(x); },
368
+ isNumeric(x) { return Number.isFinite(x); },
369
+ isDecimal(x) { return this.isNumeric(x) && (!isNaN(parseFloat(x))); }, // avoid occasions like "1abc"
370
+ isBoolean(x) { return this.isBooleanReal(x) || (this.isString(x) && (x.toLowerCase() =="true" || x.toLowerCase() =="false")); },
371
+ isBooleanReal(x) { return x === true || x === false || toString.call(x) === '[object Boolean]'; },
372
+ isString(x) { return Object.prototype.toString.call(x) === "[object String]"; }, // return (typeof content === 'string' || content instanceof String);
373
+ // https://stackoverflow.com/questions/8834126/
374
+ isObject(x) { return ( !Array.isArray(x) && Object.prototype.toString.call(x) !== '[object Array]' ) && ( (typeof x === 'object' && x !== null ) || ( (!!x) && (x.constructor === Object) ) || (typeof x === 'function' || typeof x === 'object' && !!x) ) ; },
375
+ // https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
376
+ isJsonObject(data){
377
+ // doesnt work for string return data!="" && (data=={} || JSON.stringify(data)!='{}');
378
+ return false;
379
+ },
380
+ isArray(x) { return ( (!!x) && (x.constructor === Array) ) || (Array.isArray(x)); },
381
+
382
+ isSimpleVariableType(obj){ return this.isSimpleVariableTypeName(typeof obj); },
383
+ isSimpleVariableTypeName(type_){ return this.inArray( [ "boolean", "integer", "float", "double", "decimal", "string"], type_); },
384
+ isNumericVariableTypeName(type_){ return this.inArray( [ "integer", "float", "double", "decimal"], type_); },
385
+
386
+ stringToBoolean(string){
387
+ switch(string.toLowerCase().trim()){
388
+ case "true": case "yes": case "1": return true;
389
+ case "false": case "no": case "0": case null: return false;
390
+ default: return Boolean(string);
391
+ }
392
+ },
393
+ isException(e){
394
+ return e && e.stack && e.message;
395
+ },
396
+ objectCopy(obj){
397
+ return JSON.parse(JSON.stringify(obj));
398
+ },
399
+ IsJsonString (str) {
400
+ try {
401
+ JSON.parse(str);
402
+ } catch (e) {
403
+ return false;
404
+ }
405
+ return true;
406
+ },
407
+ is_object(variable){
408
+ return typeof variable === 'object' && variable !== null;
409
+ },
410
+ formItemsToJson(FormElement){
411
+ let formDataEntries = new FormData(FormElement).entries();
412
+ const handleChild = function (obj,keysArr,value){
413
+ let firstK = keysArr.shift();
414
+ firstK=firstK.replace(']','');
415
+ if (keysArr.length==0){
416
+ if (firstK=='') {
417
+ if (!Array.isArray(obj)) obj=[];
418
+ obj.push(value);
419
+ }
420
+ else obj[firstK] = value;
421
+ }
422
+ else{
423
+ if (firstK=='') obj.push(value);
424
+ else {
425
+ if ( ! ( firstK in obj) ) obj[firstK]={};
426
+ obj[firstK] = handleChild(obj[firstK],keysArr,value);
427
+ }
428
+ }
429
+ return obj;
430
+ };
431
+ let result = {};
432
+ for (const [key, value] of formDataEntries )
433
+ result= handleChild(result, key.split(/\[/), value);
434
+ return result;
435
+ },
436
+
437
+ hasEmptyChild(obj){
438
+ let hasEmpty = false;
439
+ if(this.isObject(obj)) {
440
+ for (let [key,val] of Object.entries(obj)){
441
+ if (val === null || val === undefined){
442
+ hasEmpty = true;
443
+ }
444
+ }
445
+ }
446
+ return hasEmpty;
447
+ },
448
+
449
+ filterObject(obj, callback) {
450
+ return Object.fromEntries(Object.entries(obj).
451
+ filter(([key, val]) => callback(val, key)));
452
+ },
453
+ // #####################################$$$$$################
454
+
455
+
456
+ isBetween(a,b,c) { return a< b && b< c; },
457
+ isBetweenEq(a,b,c) { return a<=b && b<=c; },
458
+ startsWithWhiteSpace(content){
459
+ return (/^\s/).test(content);
460
+ },
461
+ trimOnlyFromEnd(content){
462
+ return content.replace(/\s*$/,"");
463
+ },
464
+ startsWithArray(content,array){
465
+ array.forEach(function(val){
466
+ if (content.startsWith(val)) return true;
467
+ })
468
+ return false;
469
+ },
470
+ endsWithArray(content,array){
471
+ array.forEach(function(val){
472
+ if (content.endsWith(val)) return true;
473
+ })
474
+ return false;
475
+ },
476
+ startLetters(str, amountOfLetters){
477
+ return str.substr(0, amountOfLetters);
478
+ },
479
+ endLetters(str, amountOfLetters){
480
+ return str.substr(str.length - amountOfLetters);
481
+ },
482
+
483
+ ConvertNumbToRoman(num){
484
+ num= num.replace('40','XXXX'); num= num.replace('39','XXXIX'); num= num.replace('38','XXXVIII'); num= num.replace('37','XXXVII');
485
+ num= num.replace('36','XXXVI'); num= num.replace('35','XXXV'); num= num.replace('34','XXXIV'); num= num.replace('33','XXXII');
486
+ num= num.replace('32','XXXII'); num= num.replace('31','XXXI'); num= num.replace('30','XXX'); num= num.replace('29','XXIX');
487
+ num= num.replace('28','XXVIII');num= num.replace('27','XXVII'); num= num.replace('26','XXVI'); num= num.replace('25','XXV');
488
+ num= num.replace('24','XXIV'); num= num.replace('23','XXIII'); num= num.replace('22','XXII'); num= num.replace('21','XXI');
489
+ num= num.replace('20','XX'); num= num.replace('19','XIX'); num= num.replace('18','XVIII'); num= num.replace('17','XVII');
490
+ num= num.replace('16','XVI'); num= num.replace('15','XV'); num= num.replace('14','XIV'); num= num.replace('13','XIII');
491
+ num= num.replace('12','XII'); num= num.replace('11','XI'); num= num.replace('10','X'); num= num.replace('9','IX');
492
+ num= num.replace('8','VIII'); num= num.replace('7','VII'); num= num.replace('6','VI'); num= num.replace('5','V');
493
+ num= num.replace('4','IV'); num= num.replace('3','III'); num= num.replace('2','II'); num= num.replace('1','I'); return num;
494
+ },
495
+
496
+ // encrypt decrypt: http://jsfiddle.net/kein1945/M9K2c/ | https://stackoverflow.com/questions/18279141/ | https://stackoverflow.com/questions/51531021/x
497
+
498
+
499
+ //to check whenever element is loaded
500
+ when_element_is_loaded(Id_or_class,functionname){
501
+ Id_or_class=Id_or_class.trim(); var eName = Id_or_class.substr(1); if('#'==Id_or_class.charAt(0)){var x=document.getElementById(eName);} else{var x=document.getElementsByClassName(eName)[0];}
502
+ if(x) { functionname(); } else { setTimeout(when_element_is_loaded, 100, Id_or_class, functionname); }
503
+ },
504
+
505
+ // set document title
506
+ SetTitlee(title) { document.getElementsByTagName('title')[0].innerHTML = title; },
507
+
508
+ setUrl(urlPath, title) {
509
+ var title= title || false;
510
+ window.history.pushState( ( title ? {"pageTitle":title} : ""),"", urlPath); //{"html":...,"pageTitle":....}
511
+ },
512
+
513
+ requestUri(url){
514
+ var url = url || location.href;
515
+ return url.replace(origin,'');
516
+ },
517
+ // check if key exists in array
518
+ ArrayKeyExistss(keyname,array) {
519
+ return typeof array[keyname] !== 'undefined';
520
+ },
521
+
522
+ hashtageChangeOnClick(e) {
523
+ function MyCallbackTemp (e)
524
+ {
525
+ var e = window.e || e; var t=e.target;
526
+ if (t.tagName !== 'A') return;
527
+ else{
528
+ var link=t.href;
529
+ if( link.indexOf('#') >-1) { //found hashtag
530
+ var hashtag= link.split('#')[1]; //var match = url.match(/#.*[?&]locale=([^&]+)(&|$)/); return(match ? match[1] : "");(^|\s)(#[a-z\d-]+)
531
+ var sanitized_link= link.replace( location.href.split('#')[0] ,"");
532
+ if(link.indexOf(location.href) >-1 || sanitized_link.charAt(0)=='#') { //if conains current link, or starts with #
533
+ location.hash=hashtag;
534
+ }
535
+ }
536
+ }
537
+ }
538
+
539
+ if (document.addEventListener) document.addEventListener('click', MyCallbackTemp, false);
540
+ else document.attachEvent('onclick', MyCallbackTemp);
541
+ },
542
+
543
+ capitalizeFirstLetter(string) {
544
+ return string.charAt(0).toUpperCase() + string.slice(1);
545
+ },
546
+
547
+ addQueryArg(name,value, url)
548
+ {
549
+ var url = url || location.href;
550
+ return url + (url.indexOf("?")<0 ? "?":"&") +escape(name)+"="+escape(value);
551
+ },
552
+ buildQueryString(params){
553
+ if (!params) return '';
554
+ return Object.entries(params)
555
+ .map(([key, value]) => {
556
+ return `${key}=${encodeURIComponent(value)}`;
557
+ })
558
+ .join('&');
559
+ },
560
+
561
+ // find home url (in wordpress)
562
+ wpHomeUrl (){
563
+ var matches = /(href|src)\=\"(.*?)wp-content\//.exec(document.getElementsByTagName('head')[0].innerHTML);
564
+ if (typeof matches !== 'undefined' && matches != null && matches.length > 1 ){
565
+ homeURL = matches[2];
566
+ }
567
+ },
568
+
569
+
570
+ LoadYoutubeApi(callback)
571
+ {
572
+ // This code loads the IFrame Player API code asynchronously.
573
+ var tag = document.createElement('script');
574
+ tag.src = "https://www.youtube.com/iframe_api";
575
+ var firstScriptTag = document.getElementsByTagName('script')[0];
576
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
577
+ window.onYouTubeIframeAPIReady= function(){
578
+ callback();
579
+ };
580
+ },
581
+
582
+ argvsString(){ return process.argv[2]; },
583
+ argvsArray(){ return process.argv.slice(2); },
584
+ argv(which, def = undefined){
585
+ var which = which || undefined;
586
+ let argvs= this.argvsArray();
587
+ if (argvs.length <= 0)
588
+ {
589
+ return def;
590
+ }
591
+ else{
592
+ let KeyValues= {};
593
+ for (let i=0; i<argvs.length; i++){
594
+ let argumentString = argvs[i]; // each argument
595
+ let pair = {};
596
+ if ( argumentString.includes('=') ){
597
+ pair = this.parseQuery(argumentString);
598
+ } else {
599
+ pair[argumentString] = undefined;
600
+ }
601
+ let pairKey= Object.keys(pair)[0];
602
+ // if member already exists (i.e: cli key1=val1 key2=val2 key1=xyz..)
603
+ if (pairKey in KeyValues){
604
+ // if not array yet
605
+ if (!Array.isArray(KeyValues[pairKey]))
606
+ {
607
+ KeyValues[pairKey] = [ KeyValues[pairKey], pair[pairKey]];
608
+ }
609
+ // if already array-ed
610
+ else {
611
+ KeyValues[pairKey] = KeyValues[pairKey].concat([pair[pairKey]]);
612
+ }
613
+ } else {
614
+ KeyValues = Object.assign (KeyValues, pair);
615
+ }
616
+ }
617
+ return (which==undefined ? KeyValues : (which in KeyValues ? KeyValues[which] : undefined) );
618
+ }
619
+ },
620
+ argvIsSet(which){
621
+ return this.inArray(this.argvsString, which) || this.argv(which)!=undefined;
622
+ },
623
+
624
+
625
+ parseQuery(queryString) {
626
+ let query = {};
627
+ let pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
628
+ for (let i = 0; i < pairs.length; i++) {
629
+ let pair = pairs[i].split('=');
630
+ let p2 =decodeURIComponent(pair[1] || '');
631
+ try {
632
+ p2=JSON.parse(p2);
633
+ }
634
+ catch(ex){
635
+ p2=p2;
636
+ }
637
+ query[decodeURIComponent(pair[0])] = p2;
638
+ }
639
+ return query;
640
+ },
641
+
642
+ //https://stackoverflow.com/questions/123999/how-can-i-tell-if-a-dom-element-is-visible-in-the-current-viewport
643
+ // $(window).on('DOMContentLoaded load resize scroll', handler);
644
+ //function myHandler(el) {
645
+ // var visible = isElementInViewport(el);
646
+ //}
647
+
648
+ isElementInViewport (el) {
649
+ // Special bonus for those using jQuery
650
+ if (typeof jQuery === "function" && el instanceof jQuery) {
651
+ el = el[0];
652
+ }
653
+
654
+ var rect = el.getBoundingClientRect();
655
+
656
+ return (
657
+ rect.top >= 0 &&
658
+ rect.left >= 0 &&
659
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
660
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
661
+ );
662
+ },
663
+
664
+
665
+ //state url change
666
+ //function processAjaxData(response, urlPath){
667
+ // document.getElementById("content").innerHTML = response.html;
668
+ // document.title = response.pageTitle;
669
+ // window.history.pushState({"html":response.html,"pageTitle":response.pageTitle},"", urlPath);
670
+ //}
671
+ //window.onpopstate = function(e){
672
+ // if(e.state){
673
+ // document.getElementById("content").innerHTML = e.state.html;
674
+ // document.title = e.state.pageTitle;
675
+ // }
676
+ //};
677
+
678
+ autoSizeTextareas(className)
679
+ {
680
+ let tx = document.querySelector(className);
681
+ for (let i = 0; i < tx.length; i++) {
682
+ tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
683
+ var oninput = function () {
684
+ this.style.height = 'auto';
685
+ this.style.height = (this.scrollHeight) + 'px';
686
+ };
687
+ tx[i].addEventListener("input", OnInput, false);
688
+ }
689
+ },
690
+
691
+ getAllMethods(obj, inherited_too)
692
+ {
693
+ var methods = [];
694
+ for (var m in obj) {
695
+ if (typeof obj[m] == "function" && ( inherited_too || obj.hasOwnProperty(m)) ) {
696
+ methods.push(m);
697
+ }
698
+ }
699
+ return methods;
700
+ },
701
+
702
+ hasMethod(obj, funcName, inherited_too)
703
+ {
704
+ if (obj==null) return null;
705
+
706
+ for (var m in obj) {
707
+ if (typeof obj[m] == "function" && ( inherited_too || obj.hasOwnProperty(m)) ) {
708
+ if (funcName==m) return true;
709
+ }
710
+ }
711
+ return false;
712
+ },
713
+
714
+
715
+ ConvertToHourMinSec(time){ //Output like "1:01" or "4:03:59" or "123:03:59"
716
+ var hrs = ~~(time / 3600); var mins = ~~((time % 3600) / 60); var secs = time % 60;
717
+ var hms=""; hms +=""+hrs+":"+(mins< 10 ? "0":""); hms +=""+mins+":"+(secs<10 ? "0":""); hms +=""+secs; return hms;
718
+ },
719
+
720
+ // =========== get device sizes ==========//
721
+ // http://ryanve.com/lab/dimensions/
722
+ getWindowSize(){
723
+ return {x:document.documentElement.clientWidth, y:document.documentElement.clientHeight} ;
724
+ },
725
+
726
+ removeItem(arr, value) {
727
+ var i = 0;
728
+ while (i < arr.length) {
729
+ if(arr[i] === value) {
730
+ arr.splice(i, 1);
731
+ } else {
732
+ ++i;
733
+ }
734
+ }
735
+ return arr;
736
+ },
737
+ removeItemOnce(arr, value) {
738
+ var index = arr.indexOf(value);
739
+ if (index > -1) {
740
+ arr.splice(index, 1);
741
+ }
742
+ return arr;
743
+ },
744
+ toggleItemInArray(array, value, condition)
745
+ {
746
+ if (condition) array.push(value);
747
+ else this.removeItemOnce(array,value);
748
+ return array;
749
+ },
750
+
751
+
752
+
753
+ getScrollbarWidth() {
754
+ var outer = document.createElement("div");
755
+ outer.style.visibility = "hidden";
756
+ outer.style.width = "100px";
757
+ outer.style.msOverflowStyle = "scrollbar";
758
+ document.body.appendChild(outer);
759
+ var widthNoScroll = outer.offsetWidth;
760
+ outer.style.overflow = "scroll";
761
+ var inner = document.createElement("div");
762
+ inner.style.width = "100%";
763
+ outer.appendChild(inner);
764
+ var widthWithScroll = inner.offsetWidth;
765
+ outer.parentNode.removeChild(outer);
766
+ return widthNoScroll - widthWithScroll;
767
+ },
768
+
769
+ // animation-css https://codepen.io/AKGD/pen/yvwQYZ
770
+ animationClick(element, animation, removeOrNot){
771
+ var $=jQuery;
772
+ element = $(element);
773
+ element.click(
774
+ function() {
775
+ element.addClass('animated ' + animation);
776
+ //wait for animation to finish before removing classes
777
+ if(removeOrNot){
778
+ window.setTimeout( function(){
779
+ element.removeClass('animated ' + animation);
780
+ }, 2000);
781
+ }
782
+ }
783
+ );
784
+ },
785
+
786
+ animationClickTarget(element, target, animation, removeOrNot){
787
+ var $=jQuery;
788
+ element = $(element);
789
+ element.click(
790
+ function() {
791
+ target.addClass('animated ' + animation);
792
+ //wait for animation to finish before removing classes
793
+ if(removeOrNot){
794
+ window.setTimeout( function(){
795
+ element.removeClass('animated ' + animation);
796
+ }, 2000);
797
+ }
798
+ }
799
+ );
800
+ },
801
+
802
+
803
+ dateUtils : {
804
+ // 0940 type time-ints
805
+ isBetweenHMS(target, start, end, equality) { }, // datetime, int/datetime, int/datetime, bool
806
+ equalDays(d1,d2) {
807
+ return d1.getYear()==d2.getyear() && d1.getMonth()==d2.getMonth() && d1.getDate()==d2.getDate();
808
+ }, // DateTime, DateTime
809
+ IsTodayStart(dt) { }, // DateTime
810
+ GetWeekOfMonth(dt) { }, // DateTime
811
+ GetWeekOfYear(dt) { }, // DateTime
812
+ GetQuarter(dt) { }, // DateTime
813
+ NumberToHMSstring(hhmmss) { }, // int
814
+ // ZZ incorrect, need LOCAL/UTC: DatetimeToHMSstring(dt) { }, // DateTime
815
+ // HMSToTimeSpan(hhmmss) { }, // int
816
+ addNumberToHMS(hhmmss, added_or_subtracted) { }, // int, int
817
+ DatetimeToStringUtc(dt, withMS = true, withTZ = true) {
818
+ var str = (new Date( dt || new Date() )).toISOString();
819
+ let finalStr = (withTZ ? str : str.replace("T", " ").replace("Z", ""));
820
+ return withMS ? finalStr : finalStr.split('.')[0]; //2022-07-09 15:25:00.276
821
+ },
822
+ DatetimeToStringLocal(dt, withMS = true, withT = false) {
823
+ const str = (dt || new Date()).toLocaleString('sv', {year:'numeric', month:'numeric', day:'numeric', hour:'numeric', minute:'numeric', second:'numeric', fractionalSecondDigits: 3}).replace(',', '.');
824
+ let finalStr = (withT ? str.replace(' ', 'T') : str);
825
+ return withMS ? finalStr : finalStr.split('.')[0]; //2022-07-09 19:25:00.276
826
+ },
827
+ // in some langs, the date object has distinctions, so the two below needs separated methods
828
+ StringToDatetimeUtc(str, format, culture) { return new Date(str); }, // DateTime, bool, str
829
+ StringToDatetimeLocal(str, format, culture) { return new Date(str); }, // DateTime, bool, str
830
+ UtcDatetime() {
831
+ var now = new Date();
832
+ var utc = new Date(now.getTime()); // + now.getTimezoneOffset() * 60000 is not needed !!!!!!
833
+ return utc;
834
+ },
835
+ UtcDatetimeFrom(dt) { }, // DateTime
836
+ // UTC
837
+ UtcTimestamp() {
838
+ return Math.floor(new Date().getTime());
839
+ },
840
+ //i.e. input: "2021-03-08 11:59:00" | output : 1650000000000 (milliseconds)
841
+ // [DONT CHANGE THIS FUNC, I'VE REVISED]
842
+ UtcTimestampFrom(dt) {
843
+ let offset = this.getOffsetFromUtc();
844
+ return ((((new Date( dt )).getTime()) / 1000) + 14400 - offset * 60* 60) * 1000;
845
+ },
846
+ UtcTimestampToUtcDatetime(ts) {
847
+ var d = new Date(ts);
848
+ d.setHours(d.getHours());
849
+ return d;
850
+ },
851
+ // shorthands
852
+ MaxDate(d1, d2, d3=null) {},
853
+ MinDate(d1, d2, d3=null) {},
854
+ localDatetimeToUtcString(dt){ },
855
+ areSameDays(d1, d2){ },
856
+
857
+
858
+ // #######################
859
+ // ##### added to JS #####
860
+ // #######################
861
+ StringToUtcString(str) {
862
+ return str.indexOf ('Z') > -1 || str.indexOf ('GMT') > -1 ? str : str + ' GMT+0000';
863
+ },
864
+ //i.e. input: 1650000000000 (milliseconds) | output : "2021-03-08 11:59:00"
865
+ UtcTimestampToLocalDatetime(ts) {
866
+ var d = new Date(ts);
867
+ d.setHours(d.getHours()); // + (offset==null) offset = this.getOffsetFromUtc();
868
+ return d;
869
+ // if (offset==null) offset = this.getOffsetFromUtc();
870
+ // var d = new Date(time);
871
+ // var utc = d.getTime() + (d.getTimezoneOffset() * 60000); //This converts to UTC 00:00
872
+ // var nd = new Date(utc + (3600000*offset));
873
+ // return nd; return nd.toLocaleString();
874
+ },
875
+ //i.e. input: 1650000000000 (milliseconds) | output : "2021-07-14T21:08:00.000Z"
876
+ // [DONT CHANGE THIS FUNC, I'VE REVISED]
877
+ UtcTimestampToUtcDatetimeString_OLD_CORRECT(epochtime, withTZ){
878
+ let d = new Date(epochtime);
879
+ let str =d.toISOString();
880
+ return (withTZ ? str : str.replace("T", " ").replace("Z", ""));
881
+ },
882
+ UtcTimestampToUtcDatetimeString(epochtime, withTZ){
883
+ let d = this.UtcTimestampToUtcDatetime(epochtime);
884
+ return this.DatetimeToStringUtc(d, true, withTZ);
885
+ },
886
+ getOffsetFromUtc(){
887
+ var dt = new Date();
888
+ return -dt.getTimezoneOffset()/60;
889
+ },
890
+ // https://stackoverflow.com/questions/8579861/how-to-convert-milliseconds-into-a-readable-date
891
+ stringToDate(str){ // i.. "2021-04-05 15:59:55 GMT+4"
892
+ return new Date( Date.parse(str) );
893
+ },
894
+ msGoneAfter(date){
895
+ return (new Date()-date);
896
+ },
897
+ getYMDHISFfromDate(dt){
898
+ return [1900 + dt.getYear(), dt.getMonth()+1, dt.getDate(), dt.getHours(), dt.getMinutes(), dt.getSeconds(), dt.getMilliseconds()];
899
+ },
900
+ prefixWithZero(num, digits){
901
+ return (digits===1 ? num : (digits===2 ? (num < 10 ? "0"+num : num ) : (digits===3 ? (num < 10 ? "00"+num : (num < 100 ? "0"+num : num ) ) : num ) ) ).toString();
902
+ },
903
+ currentDatetimeIs(targetDate){ //"2021-03-30 13:33:45 GMT+0300"
904
+ var curr_dt = new Date( Date.now() );
905
+ var target_dt= new Date( Date.parse(targetDate) );
906
+ return curr_dt.getYear() ==target_dt.getYear() && curr_dt.getMonth() ==target_dt.getMonth() && curr_dt.getDate() ==target_dt.getDate() && curr_dt.getHours() ==target_dt.getHours() && curr_dt.getMinutes() ==target_dt.getMinutes() && curr_dt.getSeconds() ==target_dt.getSeconds();
907
+ },
908
+ dateCompare(date1, date2){
909
+ var date1 = puvox_library.isString(date1) ? Date.parse(date1) : date1;
910
+ date1 = new Date( date1 );
911
+ var date2 = date2 || new Date(Date.now());
912
+ return (+date1 > +date2 ? 1 : +date1 < +date2 ? -1 : 0);
913
+ },
914
+ dateTill(date1, date2){
915
+ var date1 = puvox_library.isString(date1) ? Date.parse(date1) : date1;
916
+ date1 = new Date( date1 );
917
+ var date2 = date2 || new Date(Date.now());
918
+ var diff = new Date(date1.getTime()-date2.getTime());
919
+ return diff;
920
+ },
921
+ secondsTill(date1, date2){
922
+ var date1 = puvox_library.isString(date1) ? Date.parse(date1) : date1;
923
+ date1 = new Date( date1 );
924
+ var date2 = date2 || new Date(Date.now());
925
+ var diffS = date1.getTime()-date2.getTime();
926
+ var seconds = Math.round(diffS/1000);
927
+ return seconds;
928
+ },
929
+
930
+ /**
931
+ * Adds time to a date. Modelled after MySQL DATE_ADD function.
932
+ * Example: dateAdd(new Date(), 'minute', 30) //returns 30 minutes from now.
933
+ * https://stackoverflow.com/a/1214753/18511
934
+ *
935
+ * @param date Date to start with
936
+ * @param interval One of: year, quarter, month, week, day, hour, minute, second
937
+ * @param units Number of units of the given interval to add.
938
+ */
939
+ add(date, interval, units) {
940
+ if(!(date instanceof Date))
941
+ return undefined;
942
+ var ret = new Date(date); //don't change original date
943
+ var checkRollover = function() { if(ret.getDate() != date.getDate()) ret.setDate(0);};
944
+ switch(String(interval).toLowerCase()) {
945
+ case 'year' : ret.setFullYear(ret.getFullYear() + units); checkRollover(); break;
946
+ case 'quarter': ret.setMonth(ret.getMonth() + 3*units); checkRollover(); break;
947
+ case 'month' : ret.setMonth(ret.getMonth() + units); checkRollover(); break;
948
+ case 'week' : ret.setDate(ret.getDate() + 7*units); break;
949
+ case 'day' : ret.setDate(ret.getDate() + units); break;
950
+ case 'hour' : ret.setTime(ret.getTime() + units*3600000); break;
951
+ case 'minute' : ret.setTime(ret.getTime() + units*60000); break;
952
+ case 'second' : ret.setTime(ret.getTime() + units*1000); break;
953
+ default : ret = undefined; break;
954
+ }
955
+ return ret;
956
+ },
957
+ // this approach is correct, the other one: https://pastebin_com/GwsScXx1 has strange bug in node, might relate to: https://stackoverflow.com/a/19691491/2377343
958
+ addSeconds(date, seconds){
959
+ return new Date( Date.parse(date) + seconds*1000 );
960
+ },
961
+ addDays(date, days){
962
+ var result = new Date(date);
963
+ result.setDate(result.getDate() + days);
964
+ return result;
965
+ }
966
+ },
967
+
968
+
969
+
970
+ spinner(action)
971
+ {
972
+ var spinner_id = "puvox_spinner";
973
+ if(action)
974
+ {
975
+ var div=
976
+ '<div id="'+spinner_id+'" style="background:black; position:fixed; height:100%; width:100%; opacity:0.9; z-index:9990; display: flex; justify-content: center; align-items: center;">'+
977
+ '<div style="">Please Wait...</div>'+
978
+ '</div>';
979
+ document.body.insertAdjacentHTML("afterbegin", div);
980
+ }
981
+ else
982
+ {
983
+ var el = document.getElementById(spinner_id);
984
+ if (el) {
985
+ el.parentNode.removeChild(el);
986
+ }
987
+ }
988
+ },
989
+
990
+
991
+
992
+ contains(string, pattern){
993
+ var re = new RegExp(pattern);
994
+ return (re.test(string));
995
+ },
996
+
997
+ hide_show_transprent(el, hide){
998
+ if(hide){
999
+ el.css("opacity", 0.3);
1000
+ el.css("z-index", -1);
1001
+ }
1002
+ else if(!hide){
1003
+ el.css("opacity", 1);
1004
+ el.css("z-index", 0);
1005
+ }
1006
+ },
1007
+
1008
+ get_extension_from_url( url ) {
1009
+ return url.split(/\#|\?/)[0].split('.').pop().trim();
1010
+ },
1011
+
1012
+
1013
+ oneSpace(cc){
1014
+ return cc.replace(/\s\s+/g, ' ');
1015
+ },
1016
+ removeFirstAndLastChar(cc){
1017
+ return this.oneSpace( cc.substring(1, cc.length-1 ) );
1018
+ },
1019
+ getWithin_X(cc, x){
1020
+ return this.oneSpace( cc.replace(new RegExp('(.*?)'+x+'(.*)'+x+'(.*)', 'g'), '$2') );
1021
+ },
1022
+ getWithin_XY(cc, x, y){
1023
+ return this.oneSpace( cc.replace(new RegExp('(.*?)'+x+'(.*)'+y+'(.*)', 'g'), '$2') );
1024
+ },
1025
+ // https://stackoverflow.com/q/6462578/2377343
1026
+ removeIfOutsideQuotes(content, replaceWhat, replaceWith){
1027
+ var regex = new RegExp('"[^"]+"|('+replaceWhat+')','g');
1028
+ let replaced = content.replace(regex, function(m, group1) {
1029
+ if (!group1) return m;
1030
+ else return replaceWith;
1031
+ });
1032
+ return replaced;
1033
+ },
1034
+ // https://stackoverflow.com/questions/19414193/regex-extract-string-not-between-two-brackets
1035
+ // https://stackoverflow.com/questions/62616023/regex-split-if-not-inside-the-two-characters
1036
+ splitBy_X_NotInside_Y(str, x, y) //x: split by; y: not inside
1037
+ {
1038
+ return str.split( RegExp(x+'+(?=(?:(?:[^'+y+']*"){2})*[^'+y+']*$)', 'g' ) );
1039
+ },
1040
+ splitBy_X_NotInside_YZ(str, by, y, z) //x: split by; y&z: not inside
1041
+ {
1042
+ return str.split( RegExp(by+'+(?=(?:(?:[^'+y+']*"){2})*[^'+z+']*$)', 'g' ) );
1043
+ },
1044
+ splitOnlyFirstOccurence(str, what){
1045
+ return str.split(new RegExp(what+'(.+)'));
1046
+ },
1047
+ //equal
1048
+ splitByEqualNotInsideDoubleQuotes(str)
1049
+ {
1050
+ return str.split(/\=+(?=(?:(?:[^"]*"){2})*[^"]*$)/g);
1051
+ },
1052
+ //double equals
1053
+ splitByEqualNotInsideDoubleQuotesAndDoubleEquals(str)
1054
+ {
1055
+ let newStr = str.replace(/==/g, "__DOUBLE_EQUAL__RAND294393494__");
1056
+ return newStr.split(/\=+(?=(?:(?:[^"]*"){2})*[^"]*$)/g).map(x=> x.replace(/__DOUBLE_EQUAL__RAND294393494__/g,"==") );
1057
+ },
1058
+
1059
+ splitByNotInside2(str, splitChar,notInsideCharStart,notInsideCharEnd)
1060
+ {
1061
+ var str = 'a:0 b:1 moo:"foo bar" c:2';
1062
+ var parts = [];
1063
+ var currentPart = "";
1064
+ var isInQuotes= false;
1065
+
1066
+ for (var i = 0; i < str.length; i++) {
1067
+ var char = str.charAt(i);
1068
+ if (char === " " && !isInQuotes) {
1069
+ parts.push(currentPart);
1070
+ currentPart = "";
1071
+ } else {
1072
+ currentPart += char;
1073
+ }
1074
+ if (char === '"') {
1075
+ isInQuotes = !isInQuotes;
1076
+ }
1077
+ }
1078
+
1079
+ if (currentPart) parts.push(currentPart);
1080
+ },
1081
+
1082
+ // i.e. if you want to get from first to last correct brackets
1083
+ // start ( "a1)" "b1)" 'c1)' ) aaaaa ) bbbbb ) cccccc)
1084
+ getFromX_tillY_ExcudingQuotes(content, from, till, regex_index) {
1085
+ let from_ = from; //this.escapeRegExp(from);
1086
+ let matches= content.match( new RegExp(from_+"(.*)", 's'));
1087
+ let result = "";
1088
+ let till_strlen= till.length;
1089
+ if (matches != null )
1090
+ {
1091
+ let foundPart= matches[regex_index];
1092
+ let lettersArray = foundPart.split('');
1093
+ //
1094
+ let dQuote = '"'; let dQuote_active = false;
1095
+ let sQuote = '\''; let sQuote_active = false;
1096
+ //
1097
+ let lastChar_='';
1098
+ let escapeChar_='\\';
1099
+ let currentStr ='';
1100
+ let currentStr_last ='';
1101
+ for(let char_ of lettersArray)
1102
+ {
1103
+ currentStr += char_;
1104
+ //if last char was escape, we can ignore current one
1105
+ if (lastChar_ != escapeChar_)
1106
+ {
1107
+ if (char_ == dQuote)
1108
+ {
1109
+ dQuote_active = !dQuote_active;
1110
+ }
1111
+ else if (char_ == sQuote)
1112
+ {
1113
+ sQuote_active = !sQuote_active;
1114
+ }
1115
+ //
1116
+ if (!sQuote_active && !dQuote_active)
1117
+ {
1118
+ let currLength = currentStr.length;
1119
+ let lastPossibleStr = currentStr.substring(currLength-till_strlen);
1120
+ if ( lastPossibleStr == till )
1121
+ {
1122
+ result = currentStr_last;
1123
+ break;
1124
+ }
1125
+ }
1126
+ }
1127
+ currentStr_last = currentStr;
1128
+ lastChar_ = char_;
1129
+ }
1130
+ }
1131
+ return result;
1132
+ },
1133
+
1134
+ // https://stackoverflow.com/questions/9621825/escape-a-variable-within-a-regular-expression
1135
+ preg_quote(str, delimiter) {
1136
+ return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
1137
+ },
1138
+ escapeRegExp(string) {
1139
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
1140
+ },
1141
+
1142
+ splitStringIntoChars(str){
1143
+ return str.split(/(?=[\s\S])/u);
1144
+ },
1145
+
1146
+ empty(MyVar){ return this.is_empty_or_undefined(MyVar);},
1147
+ is_empty_or_undefined (MyVar)
1148
+ {
1149
+ return (
1150
+ (typeof MyVar== 'undefined')
1151
+ ||
1152
+ (MyVar == null)
1153
+ ||
1154
+ (MyVar == false)
1155
+ ||
1156
+ (!MyVar)
1157
+ ||
1158
+ (MyVar.length == 0)
1159
+ ||
1160
+ (MyVar == "")
1161
+ ||
1162
+ (MyVar.replace(/\s/g,"") == "")
1163
+ ||
1164
+ (!/[^\s]/.test(MyVar))
1165
+ ||
1166
+ (/^\s*$/.test(MyVar))
1167
+ );
1168
+ },
1169
+ isEmptyValue(input){
1170
+ //input is considered empty value: falsy value (like null, undefined, '', except false and 0),
1171
+ // string with white space characters only, empty array, empty object
1172
+ return (!input && input !== false && input !== 0) ||
1173
+ ((input instanceof String || typeof input === 'string') && !input.trim()) ||
1174
+ (Array.isArray(input) && !input.length) ||
1175
+ (input instanceof Object && !Object.keys(input).length);
1176
+ },
1177
+ removeEmptyValue (obj) {
1178
+ if (!(obj instanceof Object))
1179
+ return {};
1180
+ Object.keys(obj).forEach(key => this.isEmptyValue(obj[key]) && delete obj[key]);
1181
+ return obj;
1182
+ },
1183
+ isIterable(obj) {
1184
+ if (obj == null) { return false; }
1185
+ return typeof obj[Symbol.iterator] === 'function';
1186
+ },
1187
+ insertRedErrorLine(array_){
1188
+ var array = array_;
1189
+ array["position"] = array["position"] || "before";
1190
+ array["duration"] = array["duration"] || 2500;
1191
+ array["fadeout"] = array["fadeout"] || 1000;
1192
+ var mid_parent= $('<div/>');
1193
+ mid_parent.html(array["element"]);
1194
+ mid_parent.addClass("ui-state-error");
1195
+ if(array["position"]=="before" ) { mid_parent.prependTo(array["parent"]); }
1196
+ else { mid_parent.appendTo(array["parent"]);}
1197
+ mid_parent.attr("style", "display:inline-block; padding:8px; margin:10px; text-align:center;");
1198
+ mid_parent.delay(array["duration"]).fadeOut( array["fadeout"] , function() {
1199
+ $(this).hide();
1200
+ }
1201
+ );
1202
+ } ,
1203
+
1204
+
1205
+ jquery_popup(element, isModal, params){
1206
+ var isModal = isModal || true;
1207
+ var params = params || {};
1208
+ var width = params.hasOwnProperty('width') ? params.width : 340;
1209
+ var height = params.hasOwnProperty('height') ? params.height : 210;
1210
+
1211
+ return $(element).clone().dialog(
1212
+ {
1213
+ width : width,
1214
+ height : height,
1215
+ modal: isModal,
1216
+ open: function() {
1217
+ $('.ui-widget-overlay').addClass('custom-overlay');
1218
+ $('body').append('<div id="custom_overlay"><style>.ui-widget-overlay {opacity:0.8; font-size: 0.95em; }</style></div>');
1219
+ //$('body').append('<div id="custom_overlay1"><style>#custom_overlay1{background:black; position:absolute; top:0; left:0; width:100%; height:100%; min-height:2000px;}</style></div>');
1220
+ $(this).parent().focus(); //remove focus from first input
1221
+ },
1222
+ close: function(event, ui)
1223
+ {
1224
+ $(this).dialog("close");
1225
+ $(this).remove();
1226
+ $("#custom_overlay").remove();
1227
+ }
1228
+ });
1229
+ },
1230
+ jquery_popup_once(cookiename, key, text, duration, onComplete){
1231
+ var text = text;
1232
+ var cookieVal = this.Cookies.getOption(cookiename, "popup_shown_"+key, "true");
1233
+ var onComplete = onComplete || function(){};
1234
+ if(cookieVal=="true")
1235
+ {
1236
+ text = '<div>'+text+'</div>';
1237
+ var pp = this.jquery_popup(text, true, {});
1238
+ this.Cookies.setOption(cookiename, "popup_shown_"+key, "false");
1239
+ var duration = (duration || 99999);
1240
+ window.setTimeout( function() { onComplete();}, duration ); //
1241
+ }
1242
+ else{
1243
+ onComplete();
1244
+ }
1245
+ },
1246
+
1247
+ jquery_popup_one_time_checkbox(cookiename, key, text, callable_func, defaultCheckboxTxt){
1248
+ var defaultCheckboxTxt = defaultCheckboxTxt || '<div class="dialog_dont_show_again" style=" bottom:0; right:0; font-size:0.7em; background:#e7e7e7; width:100%; margin: 2px; padding: 2px; display: inline-block;"><input type="checkbox" onclick="PuvoxLibrary.dialog_dont_show_again(event, \''+key+'\', \''+cookiename+'\')" /><span class="dont_show_again_inner">Don\'t show this window again</span></div>';
1249
+ var text = '<div class="popup_container" style="position:relative"><div class="popupMainText">'+text+'</div>'+ defaultCheckboxTxt+'</div>';
1250
+ var cookieVal = this.Cookies.getOption(cookiename, "popup_checkbox_"+key, "true");
1251
+ if(cookieVal=="true")
1252
+ {
1253
+ text = '<div>'+text+'</div>';
1254
+ var pp = this.jquery_popup(text, true, {});
1255
+ window.setTimeout( function() { $(".dialog_dont_show_again" ).focus();}, 1500); //
1256
+ }
1257
+ else
1258
+ {
1259
+ callable_func();
1260
+ }
1261
+ },
1262
+ dialog_dont_show_again(event, key, cookiename)
1263
+ {
1264
+ this.Cookies.setOption(cookiename, "popup_checkbox_"+key, (event.target.checked ? "false" : "true") );
1265
+ },
1266
+
1267
+ dialogClose(){
1268
+ window.parent.$('.ui-dialog-content:visible').dialog('close');
1269
+ },
1270
+
1271
+
1272
+
1273
+
1274
+ mergeObjects(obj1, obj2){
1275
+ for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
1276
+ return obj1;
1277
+ },
1278
+
1279
+
1280
+ fancyTimeFormat(time)
1281
+ {
1282
+ var time = time.toFixed(0);
1283
+ // Hours, minutes and seconds
1284
+ var hrs = ~~(time / 3600);
1285
+ var mins = ~~((time % 3600) / 60);
1286
+ var secs = Math.floor((time-0.01) % 60).toFixed(0);
1287
+
1288
+ // Output like "1:01" or "4:03:59" or "123:03:59"
1289
+ var ret = "";
1290
+
1291
+ if (hrs > 0) {
1292
+ ret += "" + hrs + ":" + (mins < 10 ? "0" : "");
1293
+ }
1294
+ ret += "" + mins + ":" + (secs < 10 ? "0" : "");
1295
+ ret += "" + secs;
1296
+ return ret;
1297
+ },
1298
+
1299
+ getYtIdFromURL(URL_or_ID){
1300
+ var id;
1301
+ var URL_or_ID= URL_or_ID.trim();
1302
+ if(URL_or_ID.length == 11){
1303
+ id= URL_or_ID;
1304
+ }
1305
+ else{
1306
+ var r=URL_or_ID.match(/^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/);
1307
+ id = r[1];
1308
+ }
1309
+ return id;
1310
+ },
1311
+
1312
+ //
1313
+ jsonToArray(json_data){
1314
+ var result = [];
1315
+ //for(var i in json_data) result.push([i, json_data[i]]);
1316
+ result = Object.keys(json_data).map((key) => [key, json_data[key]]);
1317
+ return result;
1318
+ },
1319
+
1320
+ fixEntitiedJson(json_data){
1321
+ return json_data.replace(/&#34;/g,'"');
1322
+ },
1323
+
1324
+
1325
+ setSelectByOptionName(selectEl, optName){
1326
+ selectEl.find('option').filter(function () { var txt=$(this).html(); return (txt==optName); }).prop('selected', true);
1327
+ },
1328
+ ScrollTo(el, func, offset_distance) //setHashInAddress
1329
+ {
1330
+ var offset_distance= offset_distance || 0;
1331
+ //document.querySelector(el).scrollIntoView({ behavior: 'smooth' });
1332
+ $('html, body').animate({
1333
+ scrollTop: $(el).offset().top - offset_distance
1334
+ }, 1000, func);
1335
+ },
1336
+ sleep(ms) {
1337
+ return new Promise(resolve => this.setTimeout_safe(resolve, ms));
1338
+ },
1339
+ // immitating ccxt setTimeout
1340
+ setTimeout_safe (done, ms) {
1341
+ const self = this; const targetTime = Date.now() + ms; if (ms >= 2147483647) { throw new Error ('setTimeout() function was called with unrealistic value of ' + ms.toString ()); } let clearInnerTimeout = () => {}; let active = true; const id = setTimeout (() => { active = true; const rest = targetTime - Date.now (); if (rest > 0) { clearInnerTimeout = self.setTimeout_safe (done, rest, setTimeout, targetTime); } else { done (); } }, ms); return function clear () { if (active) { active = false; clearTimeout (id); } clearInnerTimeout (); };
1342
+ },
1343
+
1344
+ scrollToBottom2(el) //setHashInAddress
1345
+ {
1346
+ if (el && el[0])
1347
+ el.scrollTop(el[0].scrollHeight - el.height());
1348
+ },
1349
+ scrollToBottom(el_or_id) {
1350
+ var el = this.isObject(el_or_id) ? el_or_id : document.querySelector(el_or_id);
1351
+ el.scrollTop = el.scrollHeight - el.clientHeight;
1352
+ },
1353
+
1354
+ scrollToBottom3(el_or_id) {
1355
+ var el = this.isObject(el_or_id) ? el_or_id : document.querySelector(el_or_id);
1356
+ el.scrollTop(el.scrollHeight - el.height());
1357
+ },
1358
+
1359
+
1360
+ // scroll to
1361
+ smooth_scroll_to(selector)
1362
+ {
1363
+ $('html, body').animate({
1364
+ scrollTop: $(selector).offset().top-100
1365
+ }, 1000);
1366
+ },
1367
+
1368
+
1369
+ addLine(selector, text, first_or_last){
1370
+ let elem = this.isObject(selector) ? selector : document.querySelector(selector);
1371
+ elem.insertAdjacentHTML("beforeend", "\r\n - "+text);
1372
+ },
1373
+ removeLine(selector, first_or_last, ifMoreThanXlines) {
1374
+ let elem = this.isObject(selector) ? selector : document.querySelector(selector);
1375
+ //c( "a"+this.removeLineFromText(elem.innerHTML, first_or_last, ifMoreThanXlines));
1376
+ elem.innerHTML = this.removeElementFromElement(elem.innerHTML, first_or_last, ifMoreThanXlines);
1377
+ },
1378
+
1379
+ removeElementIfMoreThan(el, amount, first_or_last){
1380
+ let childs = el.children;
1381
+ if (childs.length>amount)
1382
+ {
1383
+ el.children[0].remove();
1384
+ }
1385
+ },
1386
+
1387
+ removeElementIfMoreThanNEW(el, amount, first_or_last){
1388
+ let newEl = el.cloneNode(true);
1389
+ this.removeElementIfMoreThan(newEl, amount, first_or_last);
1390
+ return newEl;
1391
+ },
1392
+
1393
+ // if(setHashInAddress) { window.location.hash = id_or_Name; }
1394
+ removeLine_old(selector, first_or_last, ifMoreThanXlines) {
1395
+ let elem = document.querySelector(selector);
1396
+ let text = elem.value;
1397
+
1398
+ let splited= text.split(/\n/g);
1399
+ let val = splited.filter(function(n){
1400
+ return n;
1401
+ });
1402
+ var ifMoreThanXlines= ifMoreThanXlines || false;
1403
+ if (!ifMoreThanXlines || splited.length>ifMoreThanXlines) {
1404
+ if(first_or_last) val.shift();
1405
+ else val.pop();
1406
+ }
1407
+ elem.value=val.join('\n') + '\r\n';
1408
+ },
1409
+
1410
+ removeLineFromTextarea(selector, first_or_last, ifMoreThanXlines) {
1411
+ let elem = document.querySelector(selector);
1412
+ elem.value = this.removeLineFromText(elem.value, first_or_last, ifMoreThanXlines);
1413
+ },
1414
+ removeLineFromText(text, first_or_last, ifMoreThanXlines)
1415
+ {
1416
+ var ifMoreThanXlines= ifMoreThanXlines || 0;
1417
+ let splited= text.split(/\n/g);
1418
+ if (ifMoreThanXlines && splited.length<ifMoreThanXlines) {
1419
+ return text;
1420
+ }
1421
+ if (first_or_last)
1422
+ return text.substring(lines.indexOf("\n") + 1);
1423
+ else{
1424
+ let val = splited; //.filter(function(n){ return n; });
1425
+ if(first_or_last) val.shift();
1426
+ else val.pop();
1427
+ return val.join('\n') + '\r\n';
1428
+ }
1429
+ },
1430
+
1431
+
1432
+ arrayColumn(array, col)
1433
+ {
1434
+ return array.map(function(value,index) { return value[col]; });
1435
+ },
1436
+ arrayPart(array_, amount_, from)
1437
+ {
1438
+ var from = from || 'start'; //start|end
1439
+ let count = array_.length;
1440
+ return count<=amount_ ? array_ : ( from=='start' ? array_.slice(0, amount_) : array_.slice(-amount_) );
1441
+ },
1442
+ arrayInsertAt(array, index, value){
1443
+ return array.splice(index, 0, value);
1444
+ },
1445
+ executeAfterTry(el, func, num)
1446
+ {
1447
+ var num=num || 0;
1448
+ if (num>20) return;
1449
+ else
1450
+ {
1451
+ var this_ = this;
1452
+ if( $(el).length ) func();
1453
+ else setTimeout( function(){ this_.executeAfterTry(el, func, num+1); }, 100 );
1454
+ }
1455
+ },
1456
+
1457
+ waitExecute(el, func)
1458
+ {
1459
+ var this_ = this;
1460
+ if( jQuery(el).length ) func();
1461
+ else setTimeout( function(){ this_.waitExecute(el, func); }, 700 );
1462
+ },
1463
+
1464
+ // https://stackoverflow.com/a/41407246/2377343
1465
+ consoleLogColor (text, color, backgroundOrForeground = false) {
1466
+ const prefix = '\x1b[';
1467
+ const suffix = 'm';
1468
+ const objectTree = {
1469
+ types: { reset: "0", bright: "1", dim: "2", underscore: "4", blink: "5", reverse: "7", hidden: "8", },
1470
+ foreground: { black: "30", red: "31", green: "32", yellow: "33", blue: "34", magenta: "35", cyan: "36", white: "37", },
1471
+ background: { black: "40", red: "41", green: "42", yellow: "43", blue: "44", magenta: "45", cyan: "46", white: "47", }
1472
+ };
1473
+ const bfKeyname = backgroundOrForeground ? 'background' : 'foreground';
1474
+ console.log (prefix + objectTree[bfKeyname][color] + suffix + "%s" + prefix + objectTree.types.reset + suffix, text);
1475
+ },
1476
+
1477
+ toggleWindowsMessages_WindowConfirm() { return window.confirm },
1478
+ toggleWindowsMessages_WindowAlert() { return window.alert },
1479
+ toggleWindowsMessages(enable){
1480
+ if (enable)
1481
+ {
1482
+ window.confirm = this.toggleWindowsMessages_WindowConfirm();
1483
+ window.alert = this.toggleWindowsMessages_WindowAlert();
1484
+ }
1485
+ else
1486
+ {
1487
+ window.confirm = function() { return true; };
1488
+ window.alert = function() {};
1489
+ }
1490
+ },
1491
+ suspressMessagesExecution(func){
1492
+ var alert_ = window.alert;
1493
+ var confirm_= window.confirm;
1494
+ window.confirm = function() { return true; };
1495
+ window.alert = function() {};
1496
+ func();
1497
+ window.confirm = alert_;
1498
+ window.alert = confirm_;
1499
+ },
1500
+
1501
+
1502
+ MakeIframeFullHeight (iframeElement, cycling, overwrite_margin){
1503
+ cycling= cycling || false;
1504
+ overwrite_margin= overwrite_margin || false;
1505
+ iframeElement.style.width = "100%";
1506
+ var ifrD = iframeElement.contentDocument || iframeElement.contentWindow.document;
1507
+ var mHeight = parseInt( window.getComputedStyle( ifrD.documentElement).height ); // Math.max( ifrD.body.scrollHeight, .. offsetHeight, ....clientHeight,
1508
+ var margins = ifrD.body.style.margin + ifrD.body.style.padding + ifrD.documentElement.style.margin + ifrD.documentElement.style.padding;
1509
+ if(overwrite_margin) { if(margins=="") { margins=0; ifrD.body.style.margin="0px"; } }
1510
+ (function(){
1511
+ var interval = setInterval(function(){
1512
+ if(ifrD.readyState == 'complete' ){
1513
+ setTimeout( function(){
1514
+ if(!cycling) { setTimeout( function(){ clearInterval(interval);}, 500); }
1515
+ iframeElement.style.height = (parseInt(window.getComputedStyle( ifrD.documentElement).height) + parseInt(margins)+1) +"px";
1516
+ }, 200 );
1517
+ }
1518
+ },200)
1519
+ })();
1520
+ //var funcname= arguments.callee.name;
1521
+ //window.setTimeout( function(){ console.log(funcname); console.log(cycling); window[funcname](iframeElement, cycling); }, 500 );
1522
+ },
1523
+
1524
+ in_array(needle, haystack) {
1525
+ for(var i in haystack) {
1526
+ if(haystack[i] == needle) return true;
1527
+ }
1528
+ return false;
1529
+ },
1530
+
1531
+ CreateFrameIn(targetEl, frameContent, MakeItfullWH){
1532
+ var MakeItfullWH = MakeItfullWH || false;
1533
+ var iframe = document.createElement('iframe');
1534
+ iframe.className="innerFrame innerFrame"+this.RandomNum(999999);
1535
+ iframe.style.padding="0px";
1536
+ targetEl.innerHTML = "";
1537
+ targetEl.appendChild(iframe);
1538
+ var ifr = iframe.contentWindow.document;
1539
+ ifr.open(); ifr.write("<body>"+frameContent+"</body>"); ifr.close(); //!!! dont use: ifr.body.insertAdjacentHTML("afterBegin", frameContent);
1540
+ if(MakeItfullWH){
1541
+ this.MakeIframeFullHeight(iframe);
1542
+ }
1543
+ return iframe;
1544
+ },
1545
+
1546
+ makeAllATargetBlank(el){
1547
+ if(!el) return;
1548
+ var els=el.getElementsByTagName("a");
1549
+ for(var i=0; i<els.length; i++){
1550
+ if(els[i]){
1551
+ els[i].setAttribute("target", "_blank");
1552
+ }
1553
+ }
1554
+ },
1555
+
1556
+ createDropdownFrom(arr, elementId, jqueriUi, appendToElement){
1557
+ var jqueriUi = jqueriUi || false;
1558
+ var appendToElement = appendToElement || false;
1559
+ var html= '<select id="'+elementId+'">';
1560
+ // if(arr instanceof Object){
1561
+ for(var i in arr ){
1562
+ html += '<option value="'+arr[i]+'">'+arr[i]+'</option>';
1563
+ }
1564
+ html += '</select>';
1565
+ if(appendToElement && jqueriUi){
1566
+ appendToElement.append( html );
1567
+ $(elementId).selectmenu();
1568
+ }
1569
+ return html;
1570
+ },
1571
+
1572
+ //=====
1573
+
1574
+ b64EncodeUnicode(str) {
1575
+ // first we use encodeURIComponent to get percent-encoded UTF-8,
1576
+ // then we convert the percent encodings into raw bytes which
1577
+ // can be fed into btoa.
1578
+ return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
1579
+ function toSolidBytes(match, p1) {
1580
+ return String.fromCharCode('0x' + p1);
1581
+ }));
1582
+ },
1583
+
1584
+ b64DecodeUnicode(str) {
1585
+ // Going backwards: from bytestream, to percent-encoding, to original string.
1586
+ return decodeURIComponent(atob(str).split('').map(function(c) {
1587
+ return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
1588
+ }).join(''));
1589
+ },
1590
+
1591
+ round(num,decimals){
1592
+ let v=Math.pow(10,decimals); return Math.round((num + Number.EPSILON) * v) / v; //toFixed
1593
+ },
1594
+
1595
+
1596
+
1597
+
1598
+ // ================= get basename of url =================
1599
+ basename(path) { return path.split('/').reverse()[0]; },
1600
+
1601
+
1602
+ // ========= simple POPUP =========== https://github.com/ttodua/useful-javascript/ =====================
1603
+ show_my_popup(TEXTorID, AdditionalStyles ){
1604
+ TEXTorID=TEXTorID.trim(); var FirstChar= TEXTorID.charAt(0); var eName = TEXTorID.substr(1); if ('#'==FirstChar || '.'==FirstChar){ if('#'==FirstChar){var x=document.getElementById(eName);} else{var x=document.getElementsByClassName(eName)[0];}} else { var x=document.createElement('div');x.innerHTML=TEXTorID;} var randm_id=Math.floor((Math.random()*100000000));
1605
+ var DivAA = document.createElement('div'); DivAA.id = "blkBackgr_"+randm_id; DivAA.className = "MyJsBackg"; DivAA.setAttribute("style", 'background:black; height:5000px; left:0px; opacity:0.9; position:fixed; top:0px; width:100%; z-index:99995;'); document.body.appendChild(DivAA); AdditionalStyles= AdditionalStyles || '';
1606
+ var DivBB = document.createElement('div'); DivBB.id = 'popupp_'+randm_id; DivBB.className = "MyJsPopup"; DivBB.setAttribute("style",'background-color:white; border:6px solid white; border-radius:10px; display:block; min-height:1%; min-width:350px; width:auto; overflow:auto; max-height:80%; max-width:800px; padding:15px; position:fixed; text-align:left; top:10%; z-index:99995; left:0px; right:0px; margin-left:auto; margin-right:auto; width:80%;'+ AdditionalStyles); DivBB.innerHTML = '<div style="background-color:#C0BCBF; border-radius:55px; padding:5px; font-family:arial; float:right; font-weight:700; margin:-15px -10px 0px 0px; z-index: 88; " class="CloseButtn" ><a href="javascript:my_popup_closee('+randm_id+');" style="display:block;margin:-5px 0 0 0;font-size:1.6em;">x</a></div>'; document.body.appendChild(DivBB);z=x.cloneNode(true);DivBB.appendChild(z); if(z.style.display=="none"){z.style.display="block";} },
1607
+ my_popup_closee(RandomIDD) { var x=document.getElementById("blkBackgr_"+RandomIDD); x.parentNode.removeChild(x); var x=document.getElementById('popupp_'+RandomIDD); x.parentNode.removeChild(x);
1608
+ },
1609
+ // =========================================================================================================
1610
+
1611
+
1612
+
1613
+
1614
+ // ===================== "PLEASE WAIT" popup =============== https://github.com/ttodua/useful-javascript/ ===============
1615
+ loaderImage(circleColor){
1616
+ var circlecolor=circleColor || '#ffffff';
1617
+ return '<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="90px" height="90px" viewBox="0 0 128 128" xml:space="preserve"><g><circle cx="16" cy="64" r="16" fill="'+circlecolor+'" fill-opacity="1"/><circle cx="16" cy="64" r="16" fill="'+circlecolor+'" fill-opacity="0.67" transform="rotate(45,64,64)"/><circle cx="16" cy="64" r="16" fill="#ffffff" fill-opacity="0.42" transform="rotate(90,64,64)"/><circle cx="16" cy="64" r="16" fill="'+circlecolor+'" fill-opacity="0.2" transform="rotate(135,64,64)"/><circle cx="16" cy="64" r="16" fill="'+circlecolor+'" fill-opacity="0.12" transform="rotate(180,64,64)"/><circle cx="16" cy="64" r="16" fill="'+circlecolor+'" fill-opacity="0.12" transform="rotate(225,64,64)"/><circle cx="16" cy="64" r="16" fill="'+circlecolor+'" fill-opacity="0.12" transform="rotate(270,64,64)"/><circle cx="16" cy="64" r="16" fill="'+circlecolor+'" fill-opacity="0.12" transform="rotate(315,64,64)"/><animateTransform attributeName="transform" type="rotate" values="0 64 64;315 64 64;270 64 64;225 64 64;180 64 64;135 64 64;90 64 64;45 64 64" calcMode="discrete" dur="720ms" repeatCount="indefinite"></animateTransform></g></svg>';
1618
+ },
1619
+ Loader(ShowOrHide, style, content_To_show)
1620
+ {
1621
+ var elementID = 'waiter_box_p';
1622
+ if (ShowOrHide)
1623
+ {
1624
+ var b=document.body;
1625
+ var content_To_show= (content_To_show || "") + '<br/>' +this.loaderImage();
1626
+ var x = document.createElement('div'); x.id = elementID; x.setAttribute("style","height:120%; width:120%; position:fixed; top:-10%; left:-10%; z-index:9900; overflow:hidden;");
1627
+
1628
+ x.innerHTML =
1629
+ '<div id="'+elementID+'_background" style="background-color: black; height: 100%; position: absolute; opacity: 0.9; width: 100%;' + (style || '') + '">'+
1630
+ '<div id="'+elementID+'_content" style="height: 100%;">'+
1631
+ '<div align="center" style="text-align:center;position:relative;top:50%;transform:translateY(-50%);color:#adb109;font-size:1.2em;"> '+ content_To_show + '</div>' +
1632
+ '</div>'+
1633
+ '</div>';
1634
+ b.insertBefore(x, b.childNodes[0]);
1635
+ }
1636
+ else{
1637
+ var x =document.getElementById(elementID); if (x) x.parentNode.removeChild(x);
1638
+ }
1639
+ },
1640
+ // ====================================================================================
1641
+
1642
+
1643
+
1644
+ // =================================== AJAX EXAMPLES =============== https://github.com/ttodua/useful-javascript/ ===============
1645
+ myyAjaxRequest(parameters, url, method, func, ShowBlackground){ ShowBlackground= ShowBlackground || false;
1646
+ method = method.toLowerCase() || "post"; if (method == "get") {url=url+'?'+parameters+'&MakeRandomValuedLinkToAvoidCache=' + Math.random();}
1647
+ if(ShowBlackground) {Loader(true);} try{try{var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");} catch( e ){var xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");}}catch(e){var xmlhttp = new XMLHttpRequest();}
1648
+ xmlhttp.onreadystatechange=function(){ if (xmlhttp.readyState==4){ if(ShowBlackground) {Loader(false);} responseee = xmlhttp.responseText; //xmlhttp.readyState + xmlhttp.status//
1649
+ func(); //execute any codes
1650
+ }};
1651
+ xmlhttp.open(method,url, true);
1652
+ if (method == "post"){xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");xmlhttp.send(parameters);}
1653
+ else if (method == "get"){xmlhttp.send(null);}
1654
+ },
1655
+ // ====================================================================================
1656
+
1657
+
1658
+ //all divs, which has a classname "My_TARGET_Hiddens", will be automatically hidden on page load...
1659
+ hide_popuping_divs(classnameee){
1660
+ var elmnts = document.getElementsByClassName(classnameee); var index;
1661
+ for (index = 0; index < elmnts.length; ++index) {
1662
+ elmnts[index].style.display= "none"; //elmnts[index].className = elmnts[index].className + " my_css_hide_class";
1663
+ }
1664
+ },
1665
+ //window.onload = function(){ if(typeof MyTargetHideClass ==='String') hide_popuping_divs(MyTargetHideClass); };
1666
+
1667
+ get(url, parameters) {
1668
+ // Return a new promise.
1669
+ return new Promise(function(resolve, reject) {
1670
+ // Do the usual XHR stuff
1671
+ var req = new XMLHttpRequest();
1672
+ req.open('POST', url);
1673
+
1674
+ req.onload = function() {
1675
+ // This is called even on 404 etc
1676
+ // so check the status
1677
+ if (req.status == 200) {
1678
+ // Resolve the promise with the response text
1679
+ resolve(req.response);
1680
+ }
1681
+ else {
1682
+ // Otherwise reject with the status text
1683
+ // which will hopefully be a meaningful error
1684
+ reject(Error(req.statusText));
1685
+ }
1686
+ };
1687
+
1688
+ // Handle network errors
1689
+ req.onerror = function() {
1690
+ reject(Error("Network Error"));
1691
+ };
1692
+ let parameters_ = parameters || {};
1693
+ params_ = Object.keys(parameters_).map(function (key) {
1694
+ return encodeURIComponent(key) + '=' + encodeURIComponent(parameters_[key]);
1695
+ }).join('&');
1696
+ // Make the request
1697
+ req.send(params_);
1698
+ });
1699
+ },
1700
+ getJSON(url, parameters) {
1701
+ return this.get(url, parameters).then(JSON.parse);
1702
+ },
1703
+
1704
+ post(url, params, callback_1, callback_2){
1705
+ return fetch(url, {
1706
+ method: 'post',
1707
+ body:JSON.stringify(params)
1708
+ }).then(function(response) {
1709
+ return response.text().then(function(text) {
1710
+ callback_1(text);
1711
+ });
1712
+ }); // .then(function(data) { callback_error(data); });
1713
+ },
1714
+
1715
+
1716
+ stringifyPretty(obj){
1717
+ return JSON.stringify(obj, null, 2);
1718
+ },
1719
+
1720
+ responseStringify(obj_or_text){
1721
+ return ! this.is_object(obj_or_text) ? obj_or_text : ( 'responseText' in obj_or_text ? obj_or_text.responseText : JSON.stringify(obj_or_text) );
1722
+ },
1723
+ // =========================== getElementById from parent_node ========== http://stackoverflow.com/a/5683184/2377343 ==========
1724
+ //Element.prototype.getElementById_FROM_PARENT = function(req) {
1725
+ getElementById_FROM_PARENT(req) {
1726
+ var elem = this, children = elem.childNodes, i, len, id;
1727
+ for (i = 0, len = children.length; i < len; i++) {
1728
+ elem = children[i]; // current element
1729
+ if (elem.nodeType !== 1 ) continue; // we only want real elements
1730
+ id = elem.id || elem.getAttribute('id'); // get ID
1731
+ if (id === req) { return elem; } // If it was found, then return
1732
+ else {id=elem.getElementById_FROM_PARENT(req); if(id) return id;} // otherwise, search recursively within the child
1733
+ }
1734
+ return null; // if no match found
1735
+ },
1736
+ // ====================================================================================
1737
+
1738
+
1739
+ inArray(haystack, needle) {
1740
+ var length = haystack.length;
1741
+ for(var i = 0; i < length; i++) {
1742
+ //if(typeof haystack[i] == 'object') {
1743
+ // if(arrayCompare(haystack[i], needle)) return true;
1744
+ //} else
1745
+ {
1746
+ if(haystack[i] == needle) return true;
1747
+ }
1748
+ }
1749
+ return false;
1750
+ },
1751
+
1752
+ partialObject(object_, array_) {
1753
+ let newObj ={};
1754
+ for (let [key, value] of Object.entries(object_)) {
1755
+ if( this.inArray(array_, key)){
1756
+ newObj[key] = value;
1757
+ }
1758
+ }
1759
+ return newObj;
1760
+ },
1761
+
1762
+
1763
+ array_column_with_keys(object_, keyName_) {
1764
+ let new_ ={};
1765
+ for (let [key_, value_] of Object.entries(object_)) {
1766
+ if( keyName_ in value_)
1767
+ new_[key_] = value_[keyName_];
1768
+ }
1769
+ return new_;
1770
+ },
1771
+
1772
+
1773
+ // =========================== URL parameters ===========================
1774
+ // executed below
1775
+ GetQueryParams(url) {
1776
+ // This function is anonymous, is executed immediately and
1777
+ // the return value is assigned to QueryString!
1778
+ var url= url || window.location.href;
1779
+ var query_string = {};
1780
+ var query = url.substr(url.indexOf("?") + 1) ;
1781
+ var vars = query.split("&");
1782
+ for (var i=0;i<vars.length;i++) {
1783
+ var pair = vars[i].split("=");
1784
+ // If first entry with this name
1785
+ var value= pair[0];
1786
+ if(pair.length>1){
1787
+ value = pair[1].indexOf("#") >-1 ? pair[1].split("#")[0] : pair[1];
1788
+ }
1789
+ if (typeof query_string[pair[0]] === "undefined") {
1790
+ query_string[pair[0]] = decodeURIComponent(value);
1791
+ // If second entry with this name
1792
+ } else if (typeof query_string[pair[0]] === "string") {
1793
+ var arr = [ query_string[pair[0]],decodeURIComponent(value) ];
1794
+ query_string[pair[0]] = arr;
1795
+ // If third or later entry with this name
1796
+ } else {
1797
+ query_string[pair[0]].push(decodeURIComponent(value));
1798
+ }
1799
+ }
1800
+ return query_string;
1801
+ },
1802
+
1803
+ // executed below
1804
+ URLParser(url){
1805
+ var url= url || window.location.href;
1806
+ var path="",query="",hash="",params;
1807
+ if(url.indexOf("#") > 0){
1808
+ hash = url.substr(url.indexOf("#") + 1);
1809
+ url = url.substr(0 , url.indexOf("#"));
1810
+ }
1811
+ if(url.indexOf("?") > 0){
1812
+ path = url.substr(0 , url.indexOf("?"));
1813
+ query = url.substr(url.indexOf("?") + 1);
1814
+ params= query.split('&');
1815
+ }else
1816
+ path = url;
1817
+ let obj= {
1818
+ getHost: function(){
1819
+ var hostexp = /\/\/([\w.-]*)/;
1820
+ var match = hostexp.exec(path);
1821
+ if (match != null && match.length > 1)
1822
+ return match[1];
1823
+ return "";
1824
+ },
1825
+ getHostName: function(){
1826
+ let domain = this.getHost();
1827
+ let parts = domain.split('.');
1828
+ return parts[parts.length-2];
1829
+ },
1830
+ getPath: function(){
1831
+ var pathexp = /\/\/[\w.-]*(?:\/([^?]*))/;
1832
+ var match = pathexp.exec(path);
1833
+ if (match != null && match.length > 1)
1834
+ return match[1];
1835
+ return "";
1836
+ },
1837
+ getHash: function(){
1838
+ return hash;
1839
+ },
1840
+ getParams: function(){
1841
+ return params
1842
+ },
1843
+ getQuery: function(){
1844
+ return query;
1845
+ },
1846
+ setHash: function(value){
1847
+ if(query.length > 0)
1848
+ query = "?" + query;
1849
+ if(value.length > 0)
1850
+ query = query + "#" + value;
1851
+ return path + query;
1852
+ },
1853
+ setParam: function(name, value){
1854
+ if(!params){
1855
+ params= new Array();
1856
+ }
1857
+ params.push(name + '=' + value);
1858
+ for (var i = 0; i < params.length; i++) {
1859
+ if(query.length > 0)
1860
+ query += "&";
1861
+ query += params[i];
1862
+ }
1863
+ if(query.length > 0)
1864
+ query = "?" + query;
1865
+ if(hash.length > 0)
1866
+ query = query + "#" + hash;
1867
+ return path + query;
1868
+ },
1869
+ getParam: function(name){
1870
+ if(params){
1871
+ for (var i = 0; i < params.length; i++) {
1872
+ var pair = params[i].split('=');
1873
+ if (decodeURIComponent(pair[0]) == name)
1874
+ return decodeURIComponent(pair[1]);
1875
+ }
1876
+ }
1877
+ console.log('Query variable %s not found', name);
1878
+ },
1879
+ hasParam: function(name){
1880
+ if(params){
1881
+ for (var i = 0; i < params.length; i++) {
1882
+ var pair = params[i].split('=');
1883
+ if (decodeURIComponent(pair[0]) == name)
1884
+ return true;
1885
+ }
1886
+ }
1887
+ console.log('Query variable %s not found', name);
1888
+ },
1889
+ removeParam: function(name){
1890
+ query = "";
1891
+ if(params){
1892
+ var newparams = new Array();
1893
+ for (var i = 0;i < params.length;i++) {
1894
+ var pair = params[i].split('=');
1895
+ if (decodeURIComponent(pair[0]) != name)
1896
+ newparams .push(params[i]);
1897
+ }
1898
+ params = newparams;
1899
+ for (var i = 0; i < params.length; i++) {
1900
+ if(query.length > 0)
1901
+ query += "&";
1902
+ query += params[i];
1903
+ }
1904
+ }
1905
+ if(query.length > 0)
1906
+ query = "?" + query;
1907
+ if(hash.length > 0)
1908
+ query = query + "#" + hash;
1909
+ return path + query;
1910
+ }
1911
+ };
1912
+ if (typeof window != 'undefined') {
1913
+ obj = Object.assign( obj, {
1914
+ href : window.location.href,
1915
+ protocol: window.location.protocol,
1916
+ hostname: window.location.hostname,
1917
+ host : window.location.host,
1918
+ port : window.location.port,
1919
+ pathname: window.location.pathname,
1920
+ hash : window.location.hash,
1921
+ search : window.location.search,
1922
+ href_ : window.location.href.replace(window.location.protocol+"//"+window.location.host,""),
1923
+ href_after_home : window.location.href.replace(window.location.protocol+"//"+window.location.host,"").replace( typeof BASE_PATH != "undefined" ? BASE_PATH : "", "")
1924
+ });
1925
+ }
1926
+ return obj;
1927
+ },
1928
+ /*
1929
+ http://www.example.com:8082/index.php#tab2?foo=789
1930
+
1931
+ Property Result
1932
+ ------------------------------------------
1933
+ href http://www.example.com:8082/index.php#tab2
1934
+ protocol http:
1935
+ hostname www.example.com
1936
+ host www.example.com:8082
1937
+ port 8082
1938
+ pathname index.php
1939
+ search ?foo=789
1940
+ hash #tab2
1941
+ */
1942
+ // =========================== ###### URL parameters ===========================
1943
+
1944
+
1945
+
1946
+ // PuvoxLibrary.parsePOST( request, (stringData)=>{})
1947
+ parsePOST(request, callback)
1948
+ {
1949
+ if (request.method == 'POST') {
1950
+ let name='querystring';
1951
+ var qs = require(name);
1952
+ let stringData = '';
1953
+ request.on('data', function (data) {
1954
+ stringData += data;
1955
+ // Too much POST data, kill the connection! 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
1956
+ if (stringData.length > 1e6)
1957
+ request.connection.destroy();
1958
+ });
1959
+ request.on('end', function(){ callback(qs.parse(stringData)); } );
1960
+ }
1961
+ },
1962
+
1963
+
1964
+
1965
+ // ===== in special occasions, i need to change share urls =======
1966
+ ChangeSocialShareUrls(elemnt, newurl, title){
1967
+ ShareUrlForCurrentSession= newurl;
1968
+ TitleForCurrentSession = title || false;
1969
+ $(elemnt).each(function(e, elemnt ){
1970
+ var el = $(this);
1971
+ var current_share_url = el.attr("href");
1972
+ var new_url = encodeURIComponent(ShareUrlForCurrentSession);
1973
+
1974
+ var CurrentUrlReplaced = current_share_url;
1975
+ var queryParams = GetQueryParams(current_share_url);
1976
+
1977
+ CurrentUrlReplaced = ReplaceParameterInQuery(CurrentUrlReplaced, 'u', new_url);
1978
+ CurrentUrlReplaced = ReplaceParameterInQuery(CurrentUrlReplaced, 'url', new_url);
1979
+
1980
+ if(title){
1981
+ var new_title = encodeURIComponent(TitleForCurrentSession);
1982
+ CurrentUrlReplaced = ReplaceParameterInQuery(CurrentUrlReplaced, 'text', new_title);
1983
+ CurrentUrlReplaced = ReplaceParameterInQuery(CurrentUrlReplaced, 'title', new_title);
1984
+ }
1985
+
1986
+ el.attr("href", CurrentUrlReplaced);
1987
+ });
1988
+ },
1989
+
1990
+
1991
+ //replace parameter in query string
1992
+ ReplaceParameterInQuery(url, param_name, param_new_val){
1993
+ var queryParams = GetQueryParams(url);
1994
+ var param_name=param_name.replace('"','').replace("'","");
1995
+ var variations = {'a': queryParams[param_name], b:encodeURIComponent(queryParams[param_name]) };
1996
+ for(var eachProp in variations){
1997
+ var part= param_name+'='+variations[eachProp]; if (url.indexOf(part) >= 0){url = url.replace(part, param_name+'='+param_new_val); }
1998
+ }
1999
+ return url;
2000
+ },
2001
+
2002
+
2003
+
2004
+ //if referrer is from same domain
2005
+ refferer_is_same_domain(){ return document.referrer.indexOf(location.host) > -1;} ,
2006
+ //prevent default, better function
2007
+ DoPrevent(e) { e.preventDefault(); e.stopPropagation(); },
2008
+ preventDefaultForAll(instantly){
2009
+ var func = function(){ document.querySelectorAll('.preventDefault').forEach( function(item){ item.addEventListener('click', function(e){ e.preventDefault(); }); } ); };
2010
+ if (instantly || false) func();
2011
+ else this.trigger_on_load(func);
2012
+ },
2013
+
2014
+ //add hovered class on element
2015
+ addHovered(elem){ if( elem.hasClass("hoveredd")) { elem.removeClass("hoveredd");} else { elem.addClass("hoveredd"); } },
2016
+ // ========================================================================================================
2017
+
2018
+
2019
+ // hide content if chosen radio box not chosen
2020
+ // radiobox_onchange_hider('[name="xyz[optName]"]', "optValue", "#targetHide", true);
2021
+ radiobox_onchange_hider(selector, desiredvalue, target_hidding_selector, SHOW_or_hide){
2022
+ var SHOW_or_hide= SHOW_or_hide || false;
2023
+ if( typeof roh_dropdown_objs ==='undefined') { roh_dropdown_objs = {}; }
2024
+ if( typeof roh_dropdown_objs[selector] ==='undefined' ){
2025
+ roh_dropdown_objs[selector] = true ; var funcname= arguments.callee.name;
2026
+ jQuery(selector).change(function() { window[funcname](selector, desiredvalue, target_hidding_selector, SHOW_or_hide); });
2027
+ }
2028
+ var x = jQuery(target_hidding_selector);
2029
+ if( jQuery(selector+':checked').val() == desiredvalue) {if(SHOW_or_hide) x.show(); else x.hide();}
2030
+ else {if(SHOW_or_hide) x.hide(); else x.show();}
2031
+ },
2032
+
2033
+ // string.containss(smth)
2034
+ // if (window.String && String.prototype && !String.prototype.containss) String.prototype.containss = function(arg) { return (this.indexOf(arg) > -1); }
2035
+
2036
+ // get random from array
2037
+ GetRandomFromArray(my_array){
2038
+ return my_array[this.random_number_minmax(0, my_array.length-1)];
2039
+ },
2040
+ // make array random
2041
+ array_shuffle(array) {
2042
+ var currentIndex = array.length, temporaryValue, randomIndex;
2043
+ // While there remain elements to shuffle...
2044
+ while (0 !== currentIndex) {
2045
+ // Pick a remaining element...
2046
+ randomIndex = Math.floor(Math.random() * currentIndex);
2047
+ currentIndex -= 1;
2048
+ // And swap it with the current element.
2049
+ temporaryValue = array[currentIndex];
2050
+ array[currentIndex] = array[randomIndex];
2051
+ array[randomIndex] = temporaryValue;
2052
+ }
2053
+ return array;
2054
+ },
2055
+
2056
+
2057
+ //======================== yooutube modal popup ======================
2058
+ showYtVideo(options) {
2059
+ options = $.extend({ content:0, url:0, videoId: '', modalSize: 'm', shadowOpacity: 0.5, shadowColor: '#000', clickOutside: 1, closeButton: 1, autoplay: 0, start: 0, oncall: '' }, options);
2060
+ var styleee = $('<style> .modal { box-shadow: 0px 0px 40px white; padding: 0px; left: 50%; top: 50%; position: fixed; z-index: 500; background: #fff; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .modal{max-width:80%;max-height:80%;} .modal.size-m { width: 600px; height: 400px; } .modal.size-l { width: 700px; height: 500px; } .modal.size-s { width: 500px; height: 300px; } .modal-bg { position: fixed; height: 100%; width: 100%; opacity: 0.5; top: 0; left: 0; z-index: 100; } .modal-close { color: #b1b0ac; font-size: 30px; line-height: .5; position: absolute; top: -18px; right: -18px; font-weight: bold; cursor: pointer; } .modal-close:hover { color: #e72626; }</style>'); styleee.appendTo('body');
2061
+ modal = $('<div class="modal yt-modal size-' + options.modalSize + '"></div>'); modal.appendTo('body');
2062
+
2063
+ if (options.closeButton) {
2064
+ var closeButton = $('<div class="modal-close">&#215;</div>');
2065
+ closeButton.appendTo(modal);
2066
+ closeButton.on('click', function(){
2067
+ ThisVideoClosed=true;
2068
+ FadeOut_modalpp();
2069
+ });
2070
+ }
2071
+ var modalBg = $('<div class="modal-bg"></div>'); modalBg.appendTo('body');
2072
+ var vidWidth=modal.width(); var vidHeight=modal.height(); var modalWidth = modal.outerWidth(); var modalHeight = modal.outerHeight();
2073
+ var elemnt;
2074
+ if(options.content) { elemnt = $(options.content); }
2075
+ else if(options.url || options.videoId){
2076
+ if(options.url) { var url = options.url; }
2077
+ else if(options.videoId){ var url = 'https://www.youtube.com/embed/'+ options.videoId + '?autoplay='+ options.autoplay + '&start='+ options.start; }
2078
+ elemnt = $('<iframe style="width:'+ vidWidth+'px; height:'+ vidHeight+'px;" src="'+url+'" frameborder="0" allowfullscreen></iframe>');
2079
+ }
2080
+ else { console.error('showYtVideo plugin error: videoId not specified'); }
2081
+ elemnt.appendTo(modal);
2082
+ modal.css({ marginLeft: -modalWidth/2, marginTop: -modalHeight/2 });
2083
+ modalBg.css({ opacity: options.shadowOpacity, backgroundColor: options.shadowColor });
2084
+
2085
+ if (options.clickOutside) {
2086
+ $(document).mouseup(function(e) {
2087
+ if (!modal.is(e.target) && modal.has(e.target).length === 0) { FadeOut_modalpp(); }
2088
+ });
2089
+ }
2090
+ if(options.oncall != ''){ window[options.oncall](); }
2091
+ },
2092
+
2093
+ FadeOut_modalpp(){
2094
+ $(".yt-modal").fadeOut(350, function() {
2095
+ $(this).remove();
2096
+ $(".modal-bg").remove();
2097
+ });
2098
+ },
2099
+ // ================================ Youtube popup =======================================
2100
+
2101
+
2102
+ forEachDefine(){
2103
+ Object.foreEach2 = function(obj, func){
2104
+ for (var key in obj) {
2105
+ if (obj.hasOwnProperty(key)) {
2106
+ func(key, obj[key]);
2107
+ }
2108
+ }
2109
+ };
2110
+ },
2111
+ forEachDefine2(){
2112
+ if (!Object.prototype.forEach2) {
2113
+ Object.defineProperty(Object.prototype, 'forEach2', {
2114
+ value: function (callback, thisArg) {
2115
+ if (this == null) {
2116
+ throw new TypeError('Not an object');
2117
+ }
2118
+ thisArg = thisArg || window;
2119
+ for (var key in this) {
2120
+ if (this.hasOwnProperty(key)) {
2121
+ callback.call(thisArg, key, this[key], this);
2122
+ }
2123
+ }
2124
+ }
2125
+ });
2126
+ }
2127
+ },
2128
+ filterDefine(){
2129
+ Object.filter2 = function( obj, predicate) {
2130
+ let result = {}, key;
2131
+
2132
+ for (key in obj) {
2133
+ if (obj.hasOwnProperty(key) && predicate(key, obj[key])) {
2134
+ result[key] = obj[key];
2135
+ }
2136
+ }
2137
+
2138
+ return result;
2139
+ };
2140
+ },
2141
+ filterDefine2(){
2142
+ if (!Object.prototype.filter2) {
2143
+ Object.defineProperty(Object.prototype, 'filter2', {
2144
+ value: function (callback, thisArg) {
2145
+ if (this == null) {
2146
+ throw new TypeError('Not an object');
2147
+ }
2148
+
2149
+ thisArg = thisArg || window;
2150
+
2151
+ let result = {};
2152
+ for (var key in this) {
2153
+ if (this.hasOwnProperty(key) && callback.call(thisArg, key, this[key], this) ) {
2154
+ result[key] = this[key];
2155
+ }
2156
+ }
2157
+
2158
+ return result;
2159
+
2160
+ }
2161
+ });
2162
+ }
2163
+ },
2164
+
2165
+
2166
+ var_dump(array){ var o=""; for (x in array) { o += x + ": " + array[x]+"; "; } window.console && console.log(o); },
2167
+
2168
+ // =================================== POST REQUEST SEND (LIVE FORM CREATION) ======================================
2169
+ //USAGE: postForm( {deletecityy:'hihi', surname: 'blabla'}, 'Are you sure?' , 'http://yoursite.com' , '_blank');
2170
+ postForm(params,ConfirmMessage, path, method, targett) {
2171
+ if (typeof ConfirmMessage != 'undefined' && ConfirmMessage != '') { if(!confirm(ConfirmMessage)){return;}}
2172
+
2173
+ method = method || "POST";
2174
+ path = path || "";
2175
+ targett = targett || "";
2176
+ var form = document.createElement("form");form.setAttribute("method", method);form.setAttribute("action", path); form.setAttribute("target", targett);
2177
+ for(var key in params) {
2178
+ if(params.hasOwnProperty(key))
2179
+ {
2180
+ var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden");
2181
+ hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]);
2182
+ form.appendChild(hiddenField);
2183
+ }
2184
+ }
2185
+ document.body.appendChild(form); form.submit();
2186
+ },
2187
+ //============================================================================================================
2188
+
2189
+
2190
+ // =================================== Show Hint On MouseOver ======================================
2191
+ SetShowHint(elemnt,text, left, top){
2192
+ elemnt.onmouseover = function(e){ Hinttttt = document.createElement('div'); Hinttttt.className="myHintClass"; Hinttttt.innerHTML = text; document.body.appendChild(Hinttttt); this.SetPoistion(e,element); };
2193
+ elemnt.onmousemove = function(e){ this.SetPoistion(e,element) };
2194
+ elemnt.onmouseleave = function(e){ var all = document.getElementsByClassName("myHintClass"); for(i=0;i< all.length;i++){ all[i].parentNode.removeChild(all[i]);} };
2195
+ var NewClass = document.createElement('div');NewClass.innerHTML='.myHintClass{position:absolute; background:#eeeeee; z-index: 9999;}'; document.body.appendChild(NewClass);
2196
+ //
2197
+ this.SetPoistion=function(e){ e.target.style.top= parseInt(e.pageY+top)+'px'; e.target.style.left= parseInt(e.pageX + left) + 'px'; };
2198
+ },
2199
+ //============================================================================================================
2200
+
2201
+
2202
+ // ==========================================================================================//
2203
+ // ===================================== IMAGE PROPORTIONS =================================//
2204
+ // ==========================================================================================//
2205
+
2206
+
2207
+ Balance_Target_Image(img, widthh, heightt){
2208
+ if (img) { var Initial_is_larger_than_target = false;
2209
+ // ORIGINAL SIZES
2210
+ var W_1=img.naturalWidth; var H_1=img.naturalHeight;
2211
+ // DESIRED SIZES
2212
+ var W_2=widthh; var H_2=heightt;
2213
+ var proportion_1= W_1/H_1; var proportion_2= W_2/H_2;
2214
+
2215
+ var Initial_is_larger_than_target = (proportion_1 > proportion_2 ) ? true : false;
2216
+ if (Initial_is_larger_than_target) { var HowManyTimesReduced = H_1/H_2;
2217
+ img.style.height="100%"; img.style.width="auto"; img.style.margin="0 0 0 -"+ ((W_1/HowManyTimesReduced - W_2 ) /2) +"px";
2218
+ }
2219
+ else { var HowManyTimesReduced = W_1/W_2;
2220
+ img.style.height="auto"; img.style.width="100%"; img.style.margin="-"+ ((W_1/HowManyTimesReduced - W_2 )/2) +"px 0 0 0";
2221
+ }
2222
+
2223
+ //IF original image is smaller than desired
2224
+ if (W_1 < W_2){ img.style.height = parseInt( H_1/ (W_1/W_2) )+"px"; }
2225
+ if (H_1 < H_2){ img.style.width = parseInt( W_1/ (H_1/H_2) )+"px"; }
2226
+
2227
+ }
2228
+ else{ window.console && console.log("img not defined.. error28475 in script"); }
2229
+ },
2230
+
2231
+
2232
+ Balanced_Image_proportions (classname, widthh, heightt, parentClassname){ var LOAD_Result; var myImages; var FinalWidth=widthh; var FinalHeight=heightt;
2233
+ myImages = document.getElementsByClassName(classname);
2234
+ for (var i=0; i < myImages.length; i++) {
2235
+ //if parent was entered
2236
+ if (parentClassname != ""){
2237
+ var found=false; var TargetSizer;
2238
+
2239
+ // if parent found
2240
+ if (myImages[i].parentNode.className.indexOf(parentClassname) >= 0) {found=true; TargetSizer=myImages[i].parentNode;}
2241
+ else if (myImages[i].parentNode.parentNode.className.indexOf(parentClassname) >= 0) {found=true; TargetSizer=myImages[i].parentNode.parentNode;}
2242
+ else if (myImages[i].parentNode.parentNode.parentNode.className.indexOf(parentClassname) >= 0) {found=true; TargetSizer=myImages[i].parentNode.parentNode.parentNode;}
2243
+
2244
+ // if parent not found, then jump to next cycle
2245
+ if (!found) { continue;}
2246
+ else{
2247
+ //if they was set to auto, then set them to parents width
2248
+ if(widthh=="0" && heightt=="0"){
2249
+ FinalWidth = TargetSizer.offsetWidth;
2250
+ FinalHeight = TargetSizer.offsetHeight;
2251
+ }
2252
+ }
2253
+ }
2254
+ //if we continue
2255
+ myImages[i].DesiredW=FinalWidth; myImages[i].DesiredH=FinalHeight;
2256
+ if( !myImages[i].complete || (myImages[i].naturalWidth === 0) ) { //typeof myImages[i].naturalWidth !== "undefined" &&
2257
+ LOAD_Result=false; myImages[i].onload = function() {Balance_Target_Image(this, this.DesiredW, this.DesiredH); };
2258
+ }
2259
+ else{ LOAD_Result=true; Balance_Target_Image(myImages[i], FinalWidth, FinalHeight); }
2260
+ if(typeof Show_JS_image_load_result != "undefined") { window.console && console.log(LOAD_Result) && console.log(myImages[i]); }
2261
+
2262
+ // 1)
2263
+ // $("#photo").load(function() { alert("Hello from Image"); });
2264
+ // 2)
2265
+ // $('img.mustLoad').on('load',function(){ });
2266
+ // 3)
2267
+ // document.querySelector("img").addEventListener("load", function() { alert('onload!'); });
2268
+
2269
+ // 4)
2270
+ //objImg = new Image();
2271
+ //objImg.onload = function() { }
2272
+ //objImg.src = 'photo.gif';
2273
+
2274
+
2275
+ }
2276
+ },
2277
+
2278
+ // ====================================================================================//
2279
+ // ========================================== ### IMAGE PROPORTIONS ===========================================//
2280
+ // ====================================================================================//
2281
+
2282
+ show_after_pageload(el){
2283
+ var el = el || '.show_after_pageload';
2284
+ this.Append_To_Head("style", 'body '+el+' {opacity:1;}');
2285
+ },
2286
+ hide_after_pageload(el){
2287
+ var el = el || '.hide_after_pageload';
2288
+ this.Append_To_Head("style", 'body '+el+' {display:none;}');
2289
+ },
2290
+
2291
+ // =================================== Position =================================================//
2292
+ Highlight_Current_Menu_link(Added_class_name, Ancestor_to_search_in, link_to_find){
2293
+ var Added_class_name = Added_class_name || "current_item__from_JS";
2294
+ var link_to_find = link_to_find || window.location.pathname;
2295
+ var Ancestor_to_search_in = typeof Ancestor_to_search_in === "undefined" ? document.body : getElementById(Ancestor_to_search_in);
2296
+ var A_elements = Ancestor_to_search_in.getElementsByTagName("a");
2297
+ for(var i=0; i<A_elements.length; i++){
2298
+ var condition=false;
2299
+ var href=A_elements[i].href.replace(window.location.origin,"");
2300
+ if(href.indexOf('#')>-1 && href==link_to_find) {condition=true;}
2301
+ else if( RemoveHashString(link_to_find).indexOf(RemoveHashString(href)) >- 1 &&
2302
+ href.substring(0, href.lastIndexOf("/")).trim() == link_to_find.substring(0, link_to_find.lastIndexOf("/")).trim()
2303
+ ) {
2304
+ condition= true;
2305
+ }
2306
+ if (condition) { A_elements[i].className += " "+Added_class_name; }
2307
+ }
2308
+ },
2309
+ //remove # from location
2310
+ RemoveHashString(str){ var hash=str.split("#")[1]; return str.replace("#"+hash,''); },
2311
+ // ===========================================================================================//
2312
+
2313
+
2314
+ getCharsFromStart(str, amount){
2315
+ return str.substring(0, amount);
2316
+ },
2317
+ getCharsFromEnd(str, amount){
2318
+ return str.substring(str.length-amount, str.length);
2319
+ },
2320
+
2321
+ // ============================================= Position ============================================================//
2322
+ GetTopLeft(myyElement) {
2323
+ var offset = {x : 0, y : 0}; this.GetOffset (myyElement, offset);
2324
+ var scrolled = {x : 0, y : 0}; this.GetScrolled (myyElement.parentNode, scrolled);
2325
+ var posX = offset.x - scrolled.x; var posY = offset.y - scrolled.y;
2326
+ return {lefttt: posX , toppp: posY };
2327
+ },
2328
+ GetOffset(object, offset) {
2329
+ if (!object) return;
2330
+ offset.x += object.offsetLeft; offset.y += object.offsetTop;
2331
+ this.GetOffset (object.offsetParent, offset);
2332
+ },
2333
+ GetScrolled(object, scrolled) {
2334
+ if (!object) return;
2335
+ scrolled.x += object.scrollLeft; scrolled.y += object.scrollTop;
2336
+ if (object.tagName.toLowerCase () != "html") { this.GetScrolled (object.parentNode, scrolled); }
2337
+ },
2338
+ // ============================================== ##Position ==========================================================//
2339
+
2340
+ // ======================================== ## jQUery Fixed navigation ============================================//
2341
+ MakeFixed(selector, ExtraHeightToBody){
2342
+ var sticky = $(selector);
2343
+ var StickyHeight=parseInt(sticky.height());
2344
+ navPosition= sticky.offset();
2345
+ var this_ = this;
2346
+ this_.Append_To_Head("style", selector+ '.fixed_stickyy { position:fixed!important; top:0; margin:0 auto; width:inherit; z-index:99; height: '+sticky.height()+'px; }');
2347
+ $(window).scroll(function(){
2348
+ var navHeight =ExtraHeightToBody + StickyHeight || 0;
2349
+ if ($(window).scrollTop() > navPosition.top) { if(!sticky.hasClass('fixed_stickyy')){sticky.addClass('fixed_stickyy');} }
2350
+ else { if( sticky.hasClass('fixed_stickyy')){sticky.removeClass('fixed_stickyy');} }
2351
+ });
2352
+ },
2353
+ // ========================================================================================//
2354
+
2355
+ triggerWhenElementInView(el, func){
2356
+ var element_ = el;
2357
+ var function_ = func;
2358
+ $(document).ready(function(){
2359
+ $(window).scroll(function(){
2360
+ if ($(element_).isOnScreen()) {
2361
+ function_();
2362
+ } else {
2363
+ // The element is NOT visible, do something else
2364
+ }
2365
+ });
2366
+ });
2367
+
2368
+ $.fn.isOnScreen = function(){
2369
+
2370
+ var win = $(window);
2371
+
2372
+ var viewport = {
2373
+ top : win.scrollTop(),
2374
+ left : win.scrollLeft()
2375
+ };
2376
+ viewport.right = viewport.left + win.width();
2377
+ viewport.bottom = viewport.top + win.height();
2378
+
2379
+ var bounds = this.offset();
2380
+ bounds.right = bounds.left + this.outerWidth();
2381
+ bounds.bottom = bounds.top + this.outerHeight();
2382
+
2383
+ return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
2384
+
2385
+ };
2386
+ },
2387
+
2388
+ // random NUMBER or STRINGS
2389
+ RandomNum(maxNum) { return Math.floor((Math.random() * maxNum) + 1); },
2390
+
2391
+ random_number(length) { var length= length || 5; return Math.floor((Math.random() * Math.pow(10, length)) + 1);},
2392
+ random_number_minmax(min, max) { var min= min || 1; var max= max || 9999999999; return Math.floor(Math.random() * (max - min + 1)) + min;},
2393
+ randomString(length) { var length= length || 5; return Math.random().toString(36).substr(2, length);},
2394
+ //getRandomInt(max) { return Math.floor(Math.random() * Math.floor(max)); },
2395
+
2396
+ shuffle_Word(word){
2397
+ var shuffledWord = '';
2398
+ var charIndex = 0;
2399
+ word = word.split('');
2400
+ while(word.length > 0){
2401
+ charIndex = word.length * Math.random() << 0;
2402
+ shuffledWord += word[charIndex];
2403
+ word.splice(charIndex,1);
2404
+ }
2405
+ return shuffledWord;
2406
+ },
2407
+
2408
+ youtubeImage(id, quality) { return 'http://img.youtube.com/vi/'+id+'/'+ (quality || "mqdefault") +'.jpg'; } ,
2409
+
2410
+
2411
+
2412
+ // ================================ detect mobile device ==============================
2413
+ IsMobileDevice(simpleORfull){
2414
+ var simpleORfull = simpleORfull || "simple";
2415
+ var navigtr=navigator.userAgent||navigator.vendor||window.opera;
2416
+ if(simpleORfull=="simple"){
2417
+ this.IsMobileDevice= ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigtr) );
2418
+ }
2419
+ else if(simpleORfull=="full"){
2420
+ this.IsMobileDevice= (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(navigtr)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigtr.substr(0,4)));
2421
+ }
2422
+ return IsMobileDevice;
2423
+ },
2424
+
2425
+ backToTopBind(el){
2426
+ if ($(el).length) {
2427
+ $(el).on('click', function (e) {
2428
+ e.preventDefault();
2429
+ $('html,body').animate({
2430
+ scrollTop: 0
2431
+ }, 700);
2432
+ });
2433
+ }
2434
+ },
2435
+
2436
+ enable_jquery_errors()
2437
+ {
2438
+ $ = function(selector, context) {
2439
+ var elements = jQuery(selector, context); if( !elements.length ) { window.console && console.log("'" + selector + "' element(s) not found"); }
2440
+ return elements;
2441
+ }
2442
+ },
2443
+
2444
+
2445
+ openUrlInBrowser(url)
2446
+ {
2447
+ var cmd = (process.platform == 'darwin'? `open ${url}`: process.platform == 'win32'? `start ${url}`: `xdg-open ${url}`);
2448
+ let name='child_process';
2449
+ require(name).exec(cmd);
2450
+ },
2451
+
2452
+ stringify(obj_or_str){
2453
+ return this.isSimpleVariableType(obj_or_str) ? obj_or_str.toString() : JSON.stringify(obj_or_str);
2454
+ },
2455
+
2456
+ stringify_plain(data){
2457
+ var text='';
2458
+ if(this.isSimpleVariableType(data)){
2459
+ text = data;
2460
+ }
2461
+ if(this.isException(data)){
2462
+ text = ('stack' in data) ? data.stack.toString() : data.toString(); //JSON.stringify(data); <!---- doesnt work for i.e. "myclass.XYZ is not a function " exceptions
2463
+ }
2464
+ else if(this.isArray(data)){
2465
+ text = JSON.stringify(data);
2466
+ }
2467
+ else if(this.isObject(data)){
2468
+ text = JSON.stringify(data); //data.toString();
2469
+ }
2470
+ // zz missing: https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
2471
+ else{
2472
+ text = data;
2473
+ }
2474
+ return text;
2475
+ },
2476
+ CopyObject(obj) {
2477
+ return JSON.parse(JSON.stringify(obj));
2478
+ },
2479
+
2480
+ uniqId(obj_or_str){
2481
+ return this.md5( this.stringify(obj_or_str) );
2482
+ },
2483
+
2484
+ // https://gist.github.com/PixnBits/8811212
2485
+ //md5(str){ let name='crypto'; return require(name).createHash('md5').update(str).digest("hex"); }
2486
+ md5(str){var md5cycle=function(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936);d=ff(d,a,b,c,k[1],12,-389564586);c=ff(c,d,a,b,k[2],17,606105819);b=ff(b,c,d,a,k[3],22,-1044525330);a=ff(a,b,c,d,k[4],7,-176418897);d=ff(d,a,b,c,k[5],12,1200080426);c=ff(c,d,a,b,k[6],17,-1473231341);b=ff(b,c,d,a,k[7],22,-45705983);a=ff(a,b,c,d,k[8],7,1770035416);d=ff(d,a,b,c,k[9],12,-1958414417);c=ff(c,d,a,b,k[10],17,-42063);b=ff(b,c,d,a,k[11],22,-1990404162);a=ff(a,b,c,d,k[12],7,1804603682);d=ff(d,a,b,c,k[13],12,-40341101);c=ff(c,d,a,b,k[14],17,-1502002290);b=ff(b,c,d,a,k[15],22,1236535329);a=gg(a,b,c,d,k[1],5,-165796510);d=gg(d,a,b,c,k[6],9,-1069501632);c=gg(c,d,a,b,k[11],14,643717713);b=gg(b,c,d,a,k[0],20,-373897302);a=gg(a,b,c,d,k[5],5,-701558691);d=gg(d,a,b,c,k[10],9,38016083);c=gg(c,d,a,b,k[15],14,-660478335);b=gg(b,c,d,a,k[4],20,-405537848);a=gg(a,b,c,d,k[9],5,568446438);d=gg(d,a,b,c,k[14],9,-1019803690);c=gg(c,d,a,b,k[3],14,-187363961);b=gg(b,c,d,a,k[8],20,1163531501);a=gg(a,b,c,d,k[13],5,-1444681467);d=gg(d,a,b,c,k[2],9,-51403784);c=gg(c,d,a,b,k[7],14,1735328473);b=gg(b,c,d,a,k[12],20,-1926607734);a=hh(a,b,c,d,k[5],4,-378558);d=hh(d,a,b,c,k[8],11,-2022574463);c=hh(c,d,a,b,k[11],16,1839030562);b=hh(b,c,d,a,k[14],23,-35309556);a=hh(a,b,c,d,k[1],4,-1530992060);d=hh(d,a,b,c,k[4],11,1272893353);c=hh(c,d,a,b,k[7],16,-155497632);b=hh(b,c,d,a,k[10],23,-1094730640);a=hh(a,b,c,d,k[13],4,681279174);d=hh(d,a,b,c,k[0],11,-358537222);c=hh(c,d,a,b,k[3],16,-722521979);b=hh(b,c,d,a,k[6],23,76029189);a=hh(a,b,c,d,k[9],4,-640364487);d=hh(d,a,b,c,k[12],11,-421815835);c=hh(c,d,a,b,k[15],16,530742520);b=hh(b,c,d,a,k[2],23,-995338651);a=ii(a,b,c,d,k[0],6,-198630844);d=ii(d,a,b,c,k[7],10,1126891415);c=ii(c,d,a,b,k[14],15,-1416354905);b=ii(b,c,d,a,k[5],21,-57434055);a=ii(a,b,c,d,k[12],6,1700485571);d=ii(d,a,b,c,k[3],10,-1894986606);c=ii(c,d,a,b,k[10],15,-1051523);b=ii(b,c,d,a,k[1],21,-2054922799);a=ii(a,b,c,d,k[8],6,1873313359);d=ii(d,a,b,c,k[15],10,-30611744);c=ii(c,d,a,b,k[6],15,-1560198380);b=ii(b,c,d,a,k[13],21,1309151649);a=ii(a,b,c,d,k[4],6,-145523070);d=ii(d,a,b,c,k[11],10,-1120210379);c=ii(c,d,a,b,k[2],15,718787259);b=ii(b,c,d,a,k[9],21,-343485551);x[0]=add32(a,x[0]);x[1]=add32(b,x[1]);x[2]=add32(c,x[2]);x[3]=add32(d,x[3])};var cmn=function(q,a,b,x,s,t){a=add32(add32(a,q),add32(x,t));return add32(a<<s|a>>>32-s,b)};var ff=function(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)};var gg=function(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)};var hh=function(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)};var ii=function(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)};var md51=function(s){var txt="",n=s.length,state=[1732584193,-271733879,-1732584194,271733878],i;for(i=64;i<=s.length;i+=64){md5cycle(state,md5blk(s.substring(i-64,i)))}s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i<s.length;i++)tail[i>>2]|=s.charCodeAt(i)<<(i%4<<3);tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i++)tail[i]=0}tail[14]=n*8;md5cycle(state,tail);return state};var md5blk=function(s){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24)}return md5blks};var hex_chr="0123456789abcdef".split("");var rhex=function(n){var s="",j=0;for(;j<4;j++)s+=hex_chr[n>>j*8+4&15]+hex_chr[n>>j*8&15];return s};var hex=function(x){for(var i=0;i<x.length;i++)x[i]=rhex(x[i]);return x.join("")};var md5_=function(s){return hex(md51(s))};var add32=function(a,b){return a+b&4294967295};if(md5_("hello")!="5d41402abc4b2a76b9719d911017c592"){var add32=function(x,y){var lsw=(x&65535)+(y&65535),msw=(x>>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}}return md5_(str)},
2487
+
2488
+
2489
+ // ######## Cookies: https://github.com/ttodua/useful-javascript/blob/master/cookies-library.js ######## //
2490
+ Cookies : {
2491
+ get(a,b) { return this.cookies_instance().get(a,b); },
2492
+ set(a,b,c) { return this.cookies_instance().set(a,b); },
2493
+ remove(a, b) {return this.cookies_instance().remove(a,b); },
2494
+ append(name, value, attributes) {return this.cookies_instance().set((this.get(name) || '') + value, attributes); },
2495
+ isset(cookiename) {return this.get(cookiename)!="";}, // document.cookie.indexOf('; '+cookiename+'=');
2496
+ // WORKING WITH ARRAY/OBJECTS
2497
+ getOption(cookieName, key, defaultValue)
2498
+ {
2499
+ var existingValue = this.get(cookieName);
2500
+ if(existingValue)
2501
+ {
2502
+ var parsed = JSON.parse(existingValue);
2503
+ if(key in parsed)
2504
+ return parsed[key];
2505
+ }
2506
+ return defaultValue;
2507
+ },
2508
+ setOption(cookieName, key, value, attributes)
2509
+ {
2510
+ var cookie = this.get(cookieName);
2511
+ var parsed = {};
2512
+ if(cookie) parsed = JSON.parse(cookie);
2513
+ parsed[key] = value;
2514
+ var attributes = attributes || { expires: 99999 };
2515
+ this.set(cookieName, JSON.stringify(parsed), attributes);
2516
+ return parsed;
2517
+ },
2518
+ removeOption(cookieName, key, attributes)
2519
+ {
2520
+ var cookie = this.get(cookieName);
2521
+ var parsed = {};
2522
+ if(cookie) parsed = JSON.parse(cookie);
2523
+ if(key in parsed) delete parsed[key];
2524
+ var attributes = attributes || { expires: 99999 };
2525
+ this.set(cookieName, JSON.stringify(parsed), attributes);
2526
+ return parsed;
2527
+ },
2528
+ //sub-array
2529
+ getOptionObject(cookieName, key){
2530
+ return JSON.parse( this.getOption(cookieName, key, "{}") );
2531
+ },
2532
+ setOptionObject(cookieName, key, subKey, subValue){
2533
+ var existing = JSON.parse( this.getOption(cookieName, key, "{}") );
2534
+ if (subValue==null) delete existing[subKey];
2535
+ else existing[subKey]=subValue;
2536
+ this.setOption(cookieName, key, JSON.stringify(existing));
2537
+ },
2538
+ setOptionArray(cookieName, key, subValue, Add_or_remove)
2539
+ {
2540
+ var existing = JSON.parse( this.getOption(cookieName, key, "[]") );
2541
+ if (Add_or_remove && !existing.includes(subValue) )
2542
+ {
2543
+ existing.push(subValue);
2544
+ }
2545
+ else if(!Add_or_remove && existing.includes(subValue) )
2546
+ {
2547
+ existing = this.removeItem(existing, subValue);
2548
+ }
2549
+ this.setOption(cookieName, key, JSON.stringify(existing));
2550
+ },
2551
+ //
2552
+ cookies_instance(){ if (!this.cookies_inited) this.cookies_inited=this.cookies(); return this.cookies_inited; } ,
2553
+ cookies_inited: null,
2554
+ // https://cdn.jsdelivr.net/npm/js-cookie@rc/dist/js.cookie.min.js
2555
+ cookies : function(){"use strict";function e(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)e[r]=n[r]}return e}var t={read:function(e){return e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}};return function n(r,o){function i(t,n,i){if("undefined"!=typeof document){"number"==typeof(i=e({},o,i)).expires&&(i.expires=new Date(Date.now()+864e5*i.expires)),i.expires&&(i.expires=i.expires.toUTCString()),t=encodeURIComponent(t).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape),n=r.write(n,t);var c="";for(var u in i)i[u]&&(c+="; "+u,!0!==i[u]&&(c+="="+i[u].split(";")[0]));return document.cookie=t+"="+n+c}}return Object.create({set:i,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var n=document.cookie?document.cookie.split("; "):[],o={},i=0;i<n.length;i++){var c=n[i].split("="),u=c.slice(1).join("=");'"'===u[0]&&(u=u.slice(1,-1));try{var f=t.read(c[0]);if(o[f]=r.read(u,f),e===f)break}catch(e){}}return e?o[e]:o}},remove:function(t,n){i(t,"",e({},n,{expires:-1}))},withAttributes:function(t){return n(this.converter,e({},this.attributes,t))},withConverter:function(t){return n(e({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(o)},converter:{value:Object.freeze(r)}})}(t,{path:"/"})}
2556
+ },
2557
+
2558
+
2559
+
2560
+ jsonConcat(o1, o2) {
2561
+ if ( this.isObject(o1) ){
2562
+ for (var key in o2) {
2563
+ o1[key] = o2[key];
2564
+ }
2565
+ return o1;
2566
+ }
2567
+ else{
2568
+ for (var key in o2) {
2569
+ o1[key] = o2[key];
2570
+ }
2571
+ return o1;
2572
+ }
2573
+ },
2574
+
2575
+
2576
+
2577
+
2578
+
2579
+
2580
+
2581
+ // for node packs:
2582
+ _fs_instance :null,
2583
+ fs(){
2584
+ if (this._fs_instance){
2585
+ return this._fs_instance;
2586
+ }
2587
+ else {
2588
+ let name='fs';
2589
+ this._fs_instance = require(name);
2590
+ return this._fs_instance;
2591
+ }
2592
+ },
2593
+ async getRemoteData(url){
2594
+ return await (await fetch(url)).text();
2595
+ // return new Promise ((resolve, reject) => {
2596
+ // try {
2597
+ // // const https = require('https');
2598
+ // https.get (url, { 'agent': new https.Agent ({ 'rejectUnauthorized': false }) }, (res) => { let body = ''; res.setEncoding ('utf8'); res.on ('data', (data) => { body += data; }); res.on ('end', () => resolve (body)); res.on ('error', (e) => { reject (e); });
2599
+ // }).on ('error', (ex) => { reject (ex); });
2600
+ // } catch (ex) { reject (ex); }
2601
+ // });
2602
+ },
2603
+ writeFileAppendJson(filePath, jsonContent, callback){
2604
+ try{
2605
+ var callback = callback || function(){};
2606
+ var self = this;
2607
+ this.fs().readFile(filePath, 'utf8', function(err,data) {
2608
+ let json = {};
2609
+ if (typeof data !="undefined" && data!=''){
2610
+ json=JSON.parse(data);
2611
+ }
2612
+ let jsonNew = self.jsonConcat(json, jsonContent);
2613
+ let content = JSON.stringify(jsonNew);
2614
+ this.fs().writeFile(filePath, content, 'utf8', function(callback_) {
2615
+ });
2616
+ });
2617
+ }
2618
+ catch(e){
2619
+ console.log("writeFileAppendJson", e);
2620
+ }
2621
+ },
2622
+ // if(setHashInAddress) { window.location.hash = id_or_Name; }
2623
+
2624
+
2625
+
2626
+
2627
+ // ######## CACHE ITEMS (client-side JS) ########
2628
+ cacheStorageGet(itemName, defaultValue){
2629
+ let curr= window.localStorage.getItem('puvox_'+itemName);
2630
+ return (curr==null ? defaultValue : curr);
2631
+ },
2632
+ cacheStorageGetItem(arrayName, itemName, defaultValue){
2633
+ let curr = this.cacheStorageGet(arrayName, '{}' );
2634
+ let parsed = JSON.parse(curr);
2635
+ return (itemName in parsed ? parsed.itemName : defaultValue);
2636
+ },
2637
+ cacheStorageSet(itemName, value){
2638
+ try{ window.localStorage.setItem('puvox_'+itemName, value); return true; }
2639
+ catch(ex){ alert("Cache storage quote exceeded. can't save value. err598"); return false; }
2640
+ },
2641
+ cacheSetItem(arrayName, itemName, value){
2642
+ let curr = this.cacheGet(arrayName, '{}' );
2643
+ let parsed = JSON.parse(curr);
2644
+ parsed.itemName =defaultValue;
2645
+ return this.cacheSet( arrayName, JSON.stringify(parsed) );
2646
+ },
2647
+ // ################################################
2648
+
2649
+
2650
+ createDirIfNotExists(dirPath){
2651
+ if (!this.fs().existsSync(dirPath)){
2652
+ this.fs().mkdirSync(dirPath);
2653
+ }
2654
+ },
2655
+ fileExists(filePath){
2656
+ return this.fs().existsSync(filePath);
2657
+ },
2658
+ filemtime(filePath){
2659
+ return (this.fs().statSync(filePath)).mtime;
2660
+ },
2661
+ unlink(filePath){
2662
+ return (this.fs().unlinkSync(filePath));
2663
+ },
2664
+ fileGetContents(filePath, defaultt = ''){
2665
+ if (!this.fileExists(filePath)){
2666
+ return defaultt;
2667
+ }
2668
+ return (this.fs().readFileSync(filePath));
2669
+ },
2670
+ saveFile(filePath, content){ this.fs().writeFileSync(filePath,content, 'utf8', function(err){
2671
+ if (err) throw err;
2672
+ });
2673
+ },
2674
+
2675
+
2676
+
2677
+ // ########## CACHE DIRS (server-side JS) ##########
2678
+ getDirTempOS(){ let name='os'; return require(name).tmpdir(); },
2679
+ customCacheDir:null,
2680
+ cacheDirGet(appName){
2681
+ if (!this.customCacheDir){
2682
+ this.customCacheDir = this.getDirTempOS() + '/_cache_dir_px/';
2683
+ }
2684
+ let finaldir = this.customCacheDir + appName + '/';
2685
+ this.createDirIfNotExists(finaldir);
2686
+ return finaldir;
2687
+ },
2688
+ cacheFileLocation(uniqFileName){
2689
+ uniqFileName = this.isString(uniqFileName) || this.isNumeric(uniqFileName) ? uniqFileName : JSON.stringify(uniqFileName);
2690
+ uniqFileName = this.sanitize_key_dashed(this.getCharsFromStart(uniqFileName, 15)) + "_"+ this.md5($uniqFileName);
2691
+ filePath= this.cacheDirGet() + uniqFileName + "_tmp"; //"/".
2692
+ return filePath;
2693
+ },
2694
+ //
2695
+ cacheGetFile(uniqFileName, defaultt ='', expire_seconds=8640000, decode = true)
2696
+ {
2697
+ let filePath = this.cacheFileLocation(uniqFileName);
2698
+ if ( filePath.length < 3) return "too tiny filename";
2699
+
2700
+ if ( this.fileExists(filePath) ){
2701
+ if (this.filemtime(filePath)+expire_seconds<time() ){
2702
+ this.unlink(filePath);
2703
+ return defaultt;
2704
+ }
2705
+ else{
2706
+ cont = this.fileGetContents(filePath, null);
2707
+ // if specifically array, then on empty, reckon as array
2708
+ if (cont===null)
2709
+ {
2710
+ return defaultt;
2711
+ }
2712
+ if (decode){
2713
+ try{
2714
+ return JSON.parse(cont);
2715
+ }
2716
+ catch(ex){
2717
+ return cont;
2718
+ }
2719
+ }
2720
+ else{
2721
+ return cont;
2722
+ }
2723
+ }
2724
+ }
2725
+ else {
2726
+ return defaultt;
2727
+ }
2728
+ },
2729
+ cacheSetFile(uniqFileName, content, encode=true)
2730
+ {
2731
+ let filePath= this.cacheFileLocation(uniqFileName);
2732
+ let contentFinal = (encode && (this.isArray(content) || this.isObject(content)) ) ? JSON.stringify($content): content;
2733
+ return this.saveFile(filePath, contentFinal);
2734
+ }
2735
+ };
2736
+
2737
+
2738
+ // export to outside world
2739
+ if (typeof module != "undefined" && module.hasOwnProperty("exports")) {
2740
+ module.exports = puvox_library;
2741
+ }
2742
+ if (window != undefined) {
2743
+ window['PuvoxLibrary'] = puvox_library;
2744
+ }