PageSourceSearch

https://www.birrastelvio.com/lib/ueppy/Utils.Class.js?v=78f640

js birrastelvio.com collected 2026-10-05 18:08:28 UTC 27,172 bytes, 1,031 lines download raw bytes

1/**
2 * @copyright Ueppy S.R.L.
3 */
4
5Utility = {};
6
7Utility.log = function (data, options) {
8    var opts = {
9        level: "info",
10        trace: false,
11        groupTitle: "TRACE",
12    };
13
14    if (typeof options !== "undefined") {
15        opts = $.extend({}, opts, options);
16    }
17
18    if (debug && typeof console != "undefined") {
19        if (opts.trace) {
20            console.group(opts.groupTitle);
21            console.trace();
22        }
23
24        switch (opts.level) {
25            case "error":
26                console.error(data);
27                break;
28            case "warn":
29                console.warn(data);
30                break;
31            default:
32                console.info(data);
33        }
34        if (opts.trace) {
35            console.groupEnd();
36        }
37    }
38};
39
40Utility.getLang = function (module, key) {
41    if (typeof Lang[module] == "undefined") {
42        var str =
43            "Lang Module " + module + " not found (" + module + "." + key + ")";
44        Utility.log(str, {level: "error"});
45        Utility.createLangEntry(module, key);
46        return module + "." + key;
47    } else {
48        if (typeof Lang[module][key] == "undefined") {
49            var str = "Key " + key + " not found in module " + module;
50            Utility.log(str, {level: "error"});
51            Utility.createLangEntry(module, key);
52            return module + "." + key;
53        } else {
54            if (Lang[module][key] != "") {
55                return Lang[module][key];
56            } else {
57                return module + "." + key;
58            }
59        }
60    }
61};
62
63Utility.createLangEntry = function (module, key) {
64    // disabled
65    return;
66};
67
68Utility.templateCache = {};
69Utility.template = function (options) {
70    var opts = {
71        name: "",
72        jqObj: false,
73        path: "",
74        callback: "",
75        elem: false,
76        typeofinjection: "html", // append, prepend, html
77        data: false,
78    };
79
80    opts = $.extend({}, opts, options);
81
82    if (typeof Handlebars == "undefined") {
83        alert(
84            "Handlebars non incluso, includere il file /public_html/lib/handlebars.js"
85        );
86    } else {
87        if (typeof Utility.templateCache[opts.name] == "undefined") {
88            if (opts.jqObj) {
89                Utility.templateCache[opts.name] = Handlebars.compile(
90                    opts.jqObj.text()
91                );
92                var mixedReturn = Utility.templateCache[opts.name];
93                if (opts.data) {
94                    mixedReturn = Utility.templateCache[opts.name](opts.data);
95                }
96                return mixedReturn;
97            } else {
98                $.ajax({
99                    dataType: "html",
100                    method: "GET",
101                    url: opts.path + opts.name + ".jstpl",
102                }).done(function (data) {
103                    Utility.templateCache[opts.name] = Handlebars.compile(data);
104                    if (opts.data) {
105                        markup = Utility.templateCache[opts.name](opts.data);
106                        if (opts.elem) {
107                            switch (opts.typeofinjection) {
108                                case "replace":
109                                    opts.elem.replaceWith(markup);
110                                    break;
111                                case "html":
112                                    opts.elem.html(markup);
113                                    break;
114                                case "append":
115                                    $(markup).appendTo(opts.elem);
116                                    break;
117                                case "prepend":
118                                    $(markup).prependTo(opts.elem);
119                                    break;
120                            }
121                            if (opts.callback) {
122                                opts.callback(markup);
123                            }
124                        } else {
125                            if (opts.callback) {
126                                opts.callback(markup);
127                            }
128                        }
129                    } else {
130                        if (opts.callback) {
131                            opts.callback(Utility.templateCache[opts.name]);
132                        }
133                    }
134                });
135            }
136        } else {
137            if (opts.data) {
138                markup = Utility.templateCache[opts.name](opts.data);
139                if (opts.elem) {
140                    switch (opts.typeofinjection) {
141                        case "replace":
142                            opts.elem.replaceWith(markup);
143                            break;
144                        case "html":
145                            opts.elem.html(markup);
146                            break;
147                        case "append":
148                            $(markup).appendTo(opts.elem);
149                            break;
150                        case "prepend":
151                            $(markup).prependTo(opts.elem);
152                            break;
153                    }
154                    if (opts.callback) {
155                        opts.callback(markup);
156                    }
157                } else {
158                    if (opts.jqObj) {
159                        //Utility.log(opts.data, {trace: true});
160                        return markup;
161                    } else {
162                        if (opts.callback) {
163                            if (opts.data) {
164                                opts.callback(
165                                    Utility.templateCache[opts.name](opts.data)
166                                );
167                            } else {
168                                opts.callback(Utility.templateCache[opts.name]);
169                            }
170                        }
171                    }
172                }
173            } else {
174                if (opts.jqObj) {
175                    return Utility.templateCache[opts.name];
176                } else {
177                    if (opts.callback) {
178                        opts.callback(Utility.templateCache[opts.name]);
179                    }
180                }
181            }
182        }
183    }
184};
185
186Utility.thankyou = function (options) {
187    var opts = {
188        title: Utility.getLang("default", "THANKYOU"),
189        message: "Messaggio vuoto",
190        size: "",
191        type: "danger",
192        btnlbl: Utility.getLang("default", "HOCAPITO"),
193        callback: false,
194    };
195
196    opts = $.extend({}, opts, options);
197
198    opts.message = html_entity_decode(opts.message, "ENT_QUOTES", "UTF-8");
199
200    var opzioniTemplateCallback = function (markup) {
201        //Utility.log(markup, {'trace': true});
202        var $modal = $(markup);
203        $modal.appendTo($("body"));
204        $modal.modal("show");
205        $modal.on("hidden.bs.modal", function (e) {
206            $modal.remove();
207            if (typeof opts.callback === "function") {
208                opts.callback();
209            }
210        });
211    };
212
213    if (opts.size) {
214        opts.size = " " + opts.size;
215    }
216
217    var data = {
218        title: opts.title,
219        message: opts.message,
220        close: opts.btnlbl,
221        type: opts.type,
222        size: opts.size,
223    };
224
225    if (typeof $("<div></div>").modal != "undefined") {
226        var opzioniTemplate = {
227            name: "thankyou",
228            path: main_host + "/public/common/",
229            callback: opzioniTemplateCallback,
230            data: data,
231        };
232
233        Utility.template(opzioniTemplate);
234    } else {
235        alert(
236            opts.message
237        );
238    }
239};
240
241Utility.alert = function (options) {
242    var opts = {
243        title: Utility.getLang("base", "WARNING"),
244        message: "Messaggio vuoto",
245        size: "",
246        type: "danger",
247        btnlbl: Utility.getLang("default", "HOCAPITO"),
248        callback: false,
249        decode: true,
250    };
251
252    opts = $.extend({}, opts, options);
253
254    if (opts.decode) {
255        opts.message = html_entity_decode(opts.message, "ENT_QUOTES", "UTF-8");
256    }
257
258    var opzioniTemplateCallback = function (markup) {
259        //Utility.log(markup, {'trace': true});
260        var $modal = $(markup);
261        $modal.appendTo($("body"));
262        $modal.modal("show");
263        $modal.on("hidden.bs.modal", function (e) {
264            $modal.data("bs.modal", null);
265            $modal.remove();
266            if (typeof opts.callback === "function") {
267                opts.callback($modal);
268            }
269        });
270    };
271
272    if (opts.size) {
273        opts.size = " " + opts.size;
274    }
275
276    var data = {
277        title: opts.title,
278        message: opts.message,
279        close: opts.btnlbl,
280        type: opts.type,
281        size: opts.size,
282    };
283
284    if (typeof $("<div></div>").modal != "undefined") {
285        var opzioniTemplate = {
286            name: "alert",
287            path: main_host + "/public/common/",
288            callback: opzioniTemplateCallback,
289            data: data,
290        };
291
292        Utility.template(opzioniTemplate);
293    } else {
294        alert(
295            opts.message
296        );
297    }
298};
299
300Utility.alertAdmin = function (options) {
301    var opts = {
302        title: Utility.getLang("base", "WARNING"),
303        message: "Messaggio vuoto",
304        size: "",
305        type: "danger",
306        btnlbl: Utility.getLang("default", "HOCAPITO"),
307        callback: false,
308        decode: true,
309    };
310
311    opts = $.extend({}, opts, options);
312
313    if (opts.decode) {
314        opts.message = html_entity_decode(opts.message, "ENT_QUOTES", "UTF-8");
315    }
316
317    var opzioniTemplateCallback = function (markup) {
318        //Utility.log(markup, {'trace': true});
319        var $modal = $(markup);
320        $modal.appendTo($("body"));
321        $modal.modal("show");
322        $modal.on("hidden.bs.modal", function (e) {
323            $modal.data("bs.modal", null);
324            $modal.remove();
325            if (typeof opts.callback === "function") {
326                opts.callback($modal);
327            }
328        });
329    };
330
331    if (opts.size) {
332        opts.size = " " + opts.size;
333    }
334
335    var data = {
336        title: opts.title,
337        message: opts.message,
338        close: opts.btnlbl,
339        type: opts.type,
340        size: opts.size,
341    };
342
343    if (typeof $("<div></div>").modal != "undefined") {
344        var opzioniTemplate = {
345            name: "alertAdmin",
346            path: main_host + "/public/common/",
347            callback: opzioniTemplateCallback,
348            data: data,
349        };
350
351        Utility.template(opzioniTemplate);
352    } else {
353        alert(
354            opts.message
355        );
356    }
357};
358
359Utility.getUrlParam = function (strParamNumber, rel_root) {
360    href = location.href.replace(location.protocol + "//" + location.host, "");
361
362    if (href.charAt(0) == "/") {
363        href = href.substr(1);
364    }
365
366    if (href.charAt(href.length - 1) == "/") {
367        href = href.substr(0, href.length - 1);
368    }
369
370    href = href.split("/");
371
372    strParamNumber = parseInt(strParamNumber, 10);
373
374    if (href[0] == "admin") {
375        href.shift();
376    }
377
378    if (typeof href[strParamNumber] == "undefined") {
379        return null;
380    } else {
381        return href[strParamNumber];
382    }
383
384    return href[strParam];
385};
386
387Utility.lockScreenPre = function () {
388};
389
390Utility.unlockScreenPost = function () {
391};
392
393Utility.lockScreen = function (options) {
394    var opts = {
395        message: "Messaggio vuoto",
396        zindex: 1000,
397        bgcolor: "#000000",
398        opacity: "0.6",
399        messageWidth: "50%",
400        textColor: false,
401        classes: "alert alert-info",
402        messageBgColor: "trasparent",
403        type: "wait",
404        icons: ["fa-refresh fa-spin"],
405    };
406
407    var setOption = function (key, value) {
408        opts[key] = value;
409    };
410
411    Utility.unlockScreen();
412
413    opts = $.extend({}, opts, options);
414
415    $("body").css({overflow: "hidden"});
416
417    $('<div class="overlay"></div>')
418        .css({
419            position: "absolute",
420            "background-color": opts.bgcolor,
421            opacity: opts.opacity,
422            width: "100%",
423            height: "100%",
424            top: $(window).scrollTop(),
425            left: 0,
426            "z-index": opts.zindex,
427        })
428        .appendTo("body");
429
430    var m = "<p>";
431    for (var i = 0; i < opts.icons.length; i++) {
432        var icon = opts.icons[i];
433        m += '<i class= "fa ' + icon + '" style = "margin-right:20px;"></i>';
434    }
435    m += opts.message + "</p>";
436
437    $('<div class="message">' + m + "</div>").appendTo("body");
438
439    var $message = $(".message");
440
441    $message.css({width: opts.messageWidth});
442    if (opts.classes) {
443        $message.addClass(opts.classes);
444    }
445
446    var wW = $(window).width();
447    var mW = $message.width();
448
449    var wH = $(window).height();
450    var mH = $message.height();
451
452    $message.css({
453        position: "absolute",
454        "text-align": "center",
455        "background-color": opts.messageBgColor,
456        left: (wW - mW) / 2,
457        top: (wH - mH) / 2 + $(window).scrollTop(),
458        //'top'             : (wH - mH) / 2,
459        "z-index": parseInt(opts.zindex, 10) + 1,
460    });
461
462    if (opts.textColor) {
463        $message.css({
464            color: opts.textColor,
465        });
466    }
467    Utility.lockScreenPre();
468};
469
470Utility.unlockScreen = function () {
471    $(".message").remove();
472    $(".overlay").remove();
473    $("body").css({overflow: "auto"});
474    Utility.unlockScreenPost();
475};
476
477Utility.leadingZeros = function (numero) {
478    numero = parseInt(numero, 10);
479    return str_pad(numero, 2, "0", "STR_PAD_LEFT");
480};
481
482/**
483 * @param {string|string[]} url
484 * @param {function|undefined} callback
485 * @param {boolean} async
486 */
487Utility.loadScript = function (url, callback, async = false) {
488    if (Array.isArray(url)) {
489        if (url.length === 0) {
490            if (typeof callback == "function") {
491                callback();
492            }
493            return;
494        }
495        Utility.loadScript(url[0], function () {
496            Utility.loadScript(url.slice(1), callback, async);
497        }, async);
498        return;
499    }
500    var script = document.createElement("script");
501    script.type = "text/javascript";
502
503    if (async) {
504        script.async = true;
505    }
506
507    if (script.readyState) {
508        //IE
509        script.onreadystatechange = function () {
510            if (
511                script.readyState == "loaded" ||
512                script.readyState == "complete"
513            ) {
514                script.onreadystatechange = null;
515                if (typeof callback == "function") {
516                    callback();
517                }
518            }
519        };
520    } else {
521        //Others
522        script.onload = function () {
523            if (typeof callback == "function") {
524                callback();
525            }
526        };
527    }
528
529    script.src = url;
530    document.getElementsByTagName("head")[0].appendChild(script);
531};
532
533Utility.formattaValuta = function (val, options) {
534    var opts = {
535        DEC_POINT: Utility.getLang("base", "DEC_POINT"),
536        THOUSANDS_SEP: Utility.getLang("base", "THOUSANDS_SEP"),
537        showThousands: false,
538        decimals: 2,
539    };
540
541    opts = $.extend({}, opts, options);
542
543    return number_format(
544        val,
545        opts.decimals,
546        opts.DEC_POINT,
547        opts.showThousands ? opts.THOUSANDS_SEP : ""
548    );
549};
550
551Utility.confirm = function (options) {
552    var opts = {
553        title: Utility.getLang("base", "WARNING"),
554        message: "Messaggio vuoto",
555        okLbl: Utility.getLang("base", "OK"),
556        cancelLbl: Utility.getLang("base", "CANCEL"),
557        size: "", // modal-lg
558        type: "danger",
559        onOk: false,
560        onCancel: false,
561    };
562
563    opts = $.extend({}, opts, options);
564
565    opts.message = html_entity_decode(opts.message, "ENT_QUOTES", "UTF-8");
566
567    var opzioniTemplateCallback = function (markup) {
568        var $modal = $(markup);
569        $modal.appendTo("body");
570        $modal.modal({
571            backdrop: "static",
572            keyboard: false,
573        });
574        $modal.modal("show");
575        $modal.on("hidden.bs.modal", function (e) {
576            $(this).data("bs.modal", null);
577            $(this).remove();
578        });
579
580        $modal.find(".btn-confirm").on("click", function (e) {
581            $modal.modal("hide");
582            $(this).data("bs.modal", null);
583            if (typeof opts.onOk === "function") {
584                opts.onOk($modal);
585            }
586        });
587
588        $modal.fi
588nd(".btn-cancel").on("click", function (e) {
589            if (typeof opts.onCancel === "function") {
590                opts.onCancel($modal);
591            }
592        });
593    };
594
595    if (opts.size) {
596        opts.size = " " + opts.size;
597    }
598
599    var data = {
600        title: opts.title,
601        message: opts.message,
602        CANCEL: opts.cancelLbl,
603        OK: opts.okLbl,
604        size: opts.size,
605        type: opts.type,
606    };
607
608    var opzioniTemplate = {
609        name: "confirm",
610        path: main_host + "/public/common/",
611        callback: opzioniTemplateCallback,
612        data: data,
613    };
614
615    Utility.template(opzioniTemplate);
616};
617
618Utility.modalForm = function (options) {
619    var opts = {
620        TITLE: "[NON SETTATO]",
621        SAVE: Utility.getLang("base", "SAVE"),
622        CANCEL: Utility.getLang("base", "CANCEL"),
623        ICON: "floppy-o",
624        content: "",
625        size: "", // modal-lg modal-sm
626        onSave: false,
627        onCancel: false,
628        callback: false,
629    };
630
631    opts = $.extend({}, opts, options);
632
633    if (opts.size) {
634        opts.size = " " + opts.size;
635    }
636
637    var opzioniTemplateCallback = function (markup) {
638        var $modal = $(markup);
639        if (typeof opts.callback === "function") {
640            $modal.on("shown.bs.modal", function (e) {
641                opts.callback($modal);
642            });
643        }
644
645        $modal.appendTo("body");
646        $modal.modal("show");
647        $modal.on("hidden.bs.modal", function (e) {
648            $modal.data("bs.modal", null);
649            $modal.remove();
650        });
651
652        $modal.find(".btn-confirm").on("click", function (e) {
653            if (typeof opts.onSave === "function") {
654                opts.onSave($modal);
655            } else {
656                $(this).modal("hide");
657            }
658        });
659
660        $modal.find(".btn-cancel").on("click", function (e) {
661            if (typeof opts.onCancel === "function") {
662                opts.onCancel($modal);
663            } else {
664                $(this).modal("hide");
665            }
666        });
667    };
668
669    var data = {
670        TITLE: opts.TITLE,
671        SAVE: opts.SAVE,
672        CANCEL: opts.CANCEL,
673        ICON: opts.ICON,
674        size: opts.size,
675        content: opts.content,
676    };
677
678    var opzioniTemplate = {
679        name: "modalForm",
680        path: main_host + "/admin/generic/snippets/",
681        callback: opzioniTemplateCallback,
682        data: data,
683    };
684
685    Utility.template(opzioniTemplate);
686};
687
688Utility.postData = function (options) {
689    var opts = {
690        action: "",
691        method: "post",
692        data: {},
693    };
694
695    opts = $.extend({}, opts, options);
696
697    var html =
698        '<form id="postDataForm" method="' +
699        opts.method +
700        '" action="' +
701        opts.action +
702        '">';
703
704    for (var i in opts.data) {
705        html +=
706            '<input type="hidden" name="' +
707            i +
708            '" value="' +
709            opts.data[i] +
710            '" />';
711    }
712    html += "</form>";
713
714    $(html).appendTo("body").submit();
715};
716
717Utility.tabIndexInit = function () {
718    $elementi = $(":input");
719    var i = 0;
720    $elementi.each(function () {
721        $(this).attr({tabindex: i});
722        i = i + 1;
723    });
724    i = $elementi.size();
725    $elementi = $("a");
726    $elementi.each(function () {
727        $(this).attr({tabindex: i});
728        i++;
729    });
730};
731
732/**
733 * Passato l'evento del keyup la funzione verifica se il valore fornito è tra quelli
734 * accettati
735 *
736 * @param event e
737 * @param string allowed_chars contiene una regex sulla quale viene confrontato il carattere
738 */
739Utility.restricted = function (e, allowed_chars) {
740    Utility.log("restricted(e, allowed_chars)");
741    Utility.log("e:" + e);
742    key = e.charCode ? e.charCode : e.which;
743
744    Utility.log("key_code:" + key);
745
746    if (
747        key == null ||
748        key == 0 ||
749        key == 8 ||
750        key == 9 ||
751        key == 13 ||
752        key == 27
753    )
754        return true;
755
756    keychar = String.fromCharCode(key);
757    Utility.log("keychar:" + keychar);
758
759    Utility.log(allowed_chars + "{1}");
760
761    re = new RegExp(allowed_chars + "{1}");
762
763    if (re.test(keychar)) {
764        if (debug) Utility.log("OK");
765        return true;
766    }
767
768    if (debug) Utility.log("KO");
769    return false;
770};
771
772Utility.isNumeric = function (n) {
773    return !isNaN(parseFloat(n)) && isFinite(n);
774};
775
776Utility.registerEvent = function (options) {
777    var event = {
778        categoria: "",
779        azione: "",
780        etichetta: "",
781        valore: null,
782    };
783
784    if (typeof options !== "undefined") {
785        event = $.extend({}, event, options);
786    }
787
788    Utility.log(event);
789
790    if (typeof ga != "undefined") {
791        ga(
792            "send",
793            "event",
794            event.categoria,
795            event.azione,
796            event.etichetta,
797            event.valore
798        );
799    } else {
800        Utility.log("Non è stato incluso analytics");
801    }
802};
803
804/**
805 * @param {string|string[]} fn
806 * @param {function|undefined} callback
807 * @param {object} windowContainer
808 */
809Utility.waitForFncInWindow = function (fn, callback, windowContainer = window) {
810    if (Array.isArray(fn)) {
811        if (fn.length === 0) {
812            if (typeof callback == "function") {
813                callback();
814            }
815            return;
816        }
817        Utility.waitForFncInWindow(fn[0], function () {
818            Utility.waitForFncInWindow(fn.slice(1), callback, windowContainer);
819        }, windowContainer);
820        return;
821    }
822
823
824    if (!Utility.elementContainsRecursiveWithDot(windowContainer, fn)) {
825        windowContainer.setTimeout(
826            Utility.waitForFncInWindow.bind(
827                null,
828                fn,
829                callback,
830                windowContainer
831            ),
832            50
833        );
834    } else {
835        if (typeof callback === "function") {
836            callback();
837        }
838    }
839};
840
841Utility.elementContainsRecursiveWithDot = function (container, tokens) {
842    if (!Array.isArray(tokens)) {
843        tokens = tokens.split(".");
844    }
845
846    if (tokens.length === 0) {
847        return true;
848    }
849
850    return (
851        typeof container[tokens[0]] !== "undefined" &&
852        Utility.elementContainsRecursiveWithDot(
853            container[tokens[0]],
854            tokens.slice(1)
855        )
856    );
857};
858
859Utility.initialize = function (
860    selector,
861    callback,
862    documentContainer = document,
863    windowContainer = window
864) {
865    documentContainer.arrive(selector, {existing: true}, callback);
866};
867
868Utility.debounce = function (func, wait = 100, immediate = false) {
869    var timeout;
870    return function () {
871        var context = this,
872            args = arguments;
873        var later = function () {
874            timeout = null;
875            if (!immediate) func.apply(context, args);
876        };
877        var callNow = immediate && !timeout;
878        clearTimeout(timeout);
879        timeout = setTimeout(later, wait);
880        if (callNow) func.apply(context, args);
881    };
882};
883
884/**
885 * @param {HTMLFormElement} form
886 * @param {Object} additionalData
887 * @param {"" | "arraybuffer" | "blob" | "document" | "json" | "text"} responseType
888 * @param {function(XMLHttpRequest) : boolean} errorChecker
889 * @return {Promise}
890 */
891Utility.promiseSubmit = function (
892    form,
893    additionalData = {},
894    responseType = "json",
895    errorChecker = function (XHR /** @type {XMLHttpRequest} */) {
896        return XHR.status >= 200 && XHR.status < 300;
897    }
898) {
899    return new Promise(function (resolve, reject) {
900        var XHR = new XMLHttpRequest();
901
902        var FD = new FormData(form);
903
904        XHR.responseType = responseType;
905
906        if (
907            form.method.toLowerCase() === "get" &&
908            Array.from(FD.keys()).length > 0
909        ) {
910            console.error(
911                "cannot submit with get because XHR doesnt send data"
912            );
913            return;
914        }
915
916        XHR.open(form.method, form.action);
917
918        XHR.onload = function () {
919            if (errorChecker(XHR)) {
920                resolve(XHR.response, XHR.status);
921            } else {
922                reject(XHR.response, XHR.status);
923            }
924        };
925        XHR.onerror = function () {
926            reject(XHR.response, XHR.status);
927        };
928        for (var prop in additionalData) {
929            if (additionalData.hasOwnProperty(prop)) {
930                FD.set(prop, additionalData[prop]);
931            }
932        }
933        XHR.send(FD);
934    });
935};
936
937/**
938 * @param {HTMLFormElement} form
939 * @param {Object} data
940 */
941Utility.submit = function (
942    form,
943    data = {}
944) {
945    var newForm = document.createElement('form');
946    newForm.method = form.method;
947    newForm.action = form.action;
948    newForm.encoding = form.encoding;
949
950    for (var prop in data) {
951        if (data.hasOwnProperty(prop)) {
952            var input = document.createElement('input');
953            input.type = 'hidden';
954            input.name = prop;
955            input.value = data[prop];
956            newForm.append(input);
957        }
958    }
959    document.body.append(newForm);
960    newForm.submit();
961};
962
963/**
964 *
965 * @param {string} appId
966 * @param {HTMLFormElement} userIdForm
967 */
968Utility.initOneSignal = function (appId, userIdForm) {
969    if (appId) {
970        Utility.loadScript('https://cdn.onesignal.com/sdks/OneSignalSDK.js', undefined, true);
971        window.OneSignal = window.OneSignal || [];
972        OneSignal.push(function () {
973            OneSignal.init({
974                appId: appId,
975            });
976        });
977        if (userIdForm instanceof HTMLFormElement) {
978            OneSignal.push(function () {
979                OneSignal.getUserId(function (userId) {
980                    Utility.promiseSubmit(userIdForm, {'onesignal[userId]': userId})
981                });
982            });
983        }
984    }
985}
986
987/**
988 * @param {string} html
989 * @return {NodeList}
990 */
991Utility.htmlToElements = function(html) {
992    if (html && html != '') {
993        var template = document.createElement('template');
994        template.innerHTML = html;
995        return template.content.childNodes;
996    }
997    return new NodeList();
998}
999
1000Utility.getInput = function (el, callback) {
1001    if ('getInputElement' in el) {
1002        el.getInputElement().then(function(input) {
1003            callback.bind(input)();
1004        });
1005    } else {
1006        callback(el);
1007    }
1008};
1009
1010/**
1011 * @param {Array} arr
1012 * @param {int} old_index
1013 * @param {int} new_index
1014 * @return {Array}
1015 */
1016Utility.move = function (arr, old_index, new_index) {
1017    while (old_index < 0) {
1018        old_index += arr.length;
1019    }
1020    while (new_index < 0) {
1021        new_index += arr.length;
1022    }
1023    if (new_index >= arr.length) {
1024        var k = new_index - arr.length + 1;
1025        while (k--) {
1026            arr.push(undefined);
1027        }
1028    }
1029    arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
1030    return arr;
1031};

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