PageSourceSearch

https://thecodingcolosseum.com/Scripts/Common.js?v=2.8.0.4

js thecodingcolosseum.com collected 2026-10-03 21:19:26 UTC 18,859 bytes, 588 lines download raw bytes

1/*eslint eqeqeq: ["error", "smart"], no-extra-parens: off */
2
3function parseDate(data) {    
4    if (data instanceof Date) { return data; }
5    if (data == "") { return new Date(); }
6
7    const d = new Date(0);
8    if (data === null || data === undefined) { return d; }
9
10    let milliseconds = 0;
11
12    //if data is formatted as "/Date(1234567890)/" then parse it
13    if (data.startsWith("/Date(")) {
14        milliseconds = data.substring(6, data.length - 2);
15    }
16    else {
17        milliseconds = Date.parse(data);
18    }
19
20    milliseconds = Math.max(0, milliseconds);
21    d.setUTCMilliseconds(Number.parseInt(milliseconds));
22   
23    return (d);
24}
25
26function parseBool(data) {
27    if (data === undefined) { return false; }
28    switch (data.toString().toLowerCase()) {
29        case "1":
30        case "on":
31        case "yes":
32        case "y":
33        case "true":
34            return true;
35        case "0":
36        case "off":
37        case "no":
38        case "n":
39        case "false":
40            return false;
41        default:
42            return !!data;
43    }
44}
45
46async function sleepAsync(ms) {
47    return new Promise(resolve => setTimeout(resolve, ms));
48}
49
50function insertAtCaret(text = '') {
51    if (this.selectionStart || this.selectionStart === 0) {
52        const startPos = this.selectionStart;
53        const endPos = this.selectionEnd;
54        this.value = this.value.substring(0, startPos) +
55            text +
56            this.value.substring(endPos, this.value.length);
57        this.selectionStart = startPos + text.length;
58        this.selectionEnd = startPos + text.length;
59    } else {
60        this.value += text;
61    }
62    $(this).trigger('change');
63    return this;
64}
65
66HTMLInputElement.prototype.insertAtCaret = insertAtCaret;
67HTMLTextAreaElement.prototype.insertAtCaret = insertAtCaret;
68
69String.prototype.pad = function (size) {
70    let s = String(this);
71    if (typeof (size) !== "number") { size = 2; }
72
73    while (s.length < size) { s = "0" + s; }
74    return s;
75};
76
77Number.prototype.pad = String.prototype.pad;
78
79String.prototype.deCamelCase = function () {
80    return this.replaceAll(/([a-z])([A-Z]+$)|([A-Z]+)([A-Z])|([a-z])([A-Z])/g, '$1$3$5 $2$4$6');
81};
82
83String.prototype.escapeRegExp = function () {
84    const s = String(this);
85    return s.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
86};
87
88Date.prototype.getTimestamp = function () {
89    const lang = window.navigator.userLanguage || window.navigator.language;
90    const options = {
91        year: "numeric",
92        month: "2-digit",
93        day: "2-digit",
94        timeZone: 'UTC'
95    };
96
97    return (this.toLocaleDateString(lang, options) + " " + this.toLocaleTimeString(lang));
98};
99
100Date.prototype.getDate = function () {
101    const lang = window.navigator.userLanguage || window.navigator.language;
102    const options = {
103        year: "numeric",
104        month: "2-digit",
105        day: "2-digit"
106    };
107
108    return (this.toLocaleDateString(lang, options));
109};
110
111Date.prototype.get24hTime = function () {
112    const lang = window.navigator.userLanguage || window.navigator.language;
113    const options = {
114        hour12: false
115    };
116
117    return (this.toLocaleTimeString(lang, options));
118};
119
120let getParamValue = (function () {
121    let params;
122    const resetParams = function () {
123        const query = window.location.search;
124        const regex = /[?&;](.+?)=([^&;]+)/g;
125        let match;
126
127        params = {};
128
129        if (query) {
130            while ((match = regex.exec(query)) != null) {
131                params[match[1]] = decodeURIComponent(match[2]);
132            }
133        }
134    };
135
136    window.addEventListener && window.addEventListener('popstate', resetParams);
137
138    resetParams();
139
140    return function (param) {
141        return Object.hasOwn(params, param) ? params[param] : null;
142    };
143})();
144
145if (!Array.prototype.last) { Array.prototype.last = function () { return this.length < 1 ? null : this.at(-1); }; }
146if (!Array.prototype.first) { Array.prototype.first = function () { return this.length < 1 ? null : this[0]; }; }
147
148String.prototype.contains = function (contains) { return this.includes(contains); };
149Array.prototype.contains = function (contains) { return this.includes(contains); };
150String.prototype.isEmptyOrWhitespace = function () { return this.match(/^\s*$/); };
151
152String.prototype.format = function (args) {
153    return this.replaceAll(/\{(\w+)\}/g, function (match, key) {
154        return args[key] !== undefined ? args[key] : match;
155    });
156};
157
158Array.prototype.groupBy = function (keySelector) {
159    return this.reduce((result, currentValue) => {
160        const key = keySelector(currentValue);
161        if (!result[key]) {
162            result[key] = [];
163        }
164        result[key].push(currentValue);
165        return result;
166    }, {});
167};
168
169Array.prototype.distinct = function (keySelector) {
170    const seen = new Set();
171    return this.filter(item => {
172        const key = keySelector(item);
173        if (seen.has(key)) {
174            return false;
175        }
176        seen.add(key);
177        return true;
178    });
179};
180
181ko.bindingHandlers.enterPressed = {
182    init: function (element, valueAccessor, _allBindings, viewModel) {
183        const callback = valueAccessor();
184        $(element).keypress(function (event) {
185            const keyCode = (event.which ? event.which : event.keyCode);
186            if (keyCode === 13) {
187                callback.call(viewModel);
188                return false;
189            }
190            return true;
191        });
192    }
193};
194
195ko.bindingHandlers.fadeVisible = {
196    init: function (element, valueAccessor) {
197        // Initially set the element to be instantly visible/hidden depending on the value
198        const value = valueAccessor();
199        $(element).toggle(ko.unwrap(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
200    },
201    update: function (element, valueAccessor) {
202        // Whenever the value subsequently changes, slowly fade the element in or out
203        const value = valueAccessor();
204        ko.unwrap(value) ? $(element).fadeIn() : $(element).fadeOut();
205    }
206};
207
208ko.bindingHandlers.forcePush = {
209    init: function (element, valueAccessor, _allBindings, viewModel) {
210        const callback = valueAccessor();
211        Pressure.set(element, {
212            startDeepPress: function (event) {
213                callback.call(viewModel, element, event);
214            },
215        });
216    },
217};
218
219ko.bindingHandlers.element = {
220    init: function (element, valueAccessor) {
221        const target = valueAccessor();
222        target(element);
223    }
224};
225
226ko.bindingHandlers.scrollLoadMore = {
227    init: function (element, valueAccessor) {
228        const options = valueAccessor();
229        const callback = options.callback;
230        const threshold = options.threshold || 100;
231
232        function onScroll() {
233            const scrollTop = element.scrollTop;
234            const scrollHeight = element.scrollHeight;
235            const offsetHeight = element.offsetHeight;
236            const distanceFromBottom = scrollHeight - (scrollTop + offsetHeight);
237
238            if (distanceFromBottom <= threshold) {
239                callback();
240            }
241        }
242
243        element.addEventListener('scroll', onScroll);
244    }
245};
246
247function getForm(selector) {
248    const form = {};
249
250    $(selector).find('[data-formfield]').each(function () {
251        const self = $(this);
252        const name = self.data("formfield");
253        if (self.text() != null)
254        {
255            form[name] = self.text();
256        }
257    });
258
259    $(selector).find(':input[name]:enabled, :input[data-formfield]:enabled').each(function () {
260        const self = $(this);
261        const name = self.attr('name') || self.data("formfield");
262
263        if (self.is(":checkbox") || self.is(":radio")) {
264            form[name] = self.is(":checked");
265            return; //Logic: Behaves as continue since we're in a callback
266        }
267
268        if (form[name] !== "" && form[name] != null) {
269            form[name] = form[name] + ',' + self.val();
270        } else {
271            form[name] = self.val();
272        }
273    });
274
275    return form;
276}
277
278function setForm(selector, data) {
279    $(selector).find('[data-formfield]').each(function () {
280        const self = $(this);
281        const name = self.data("formfield");
282
283        if (data[name] != null) {
284            const fieldType = self.data("formfieldtype");
285            if (fieldType != null) {
286                let displayValue = data[name];
287                switch (fieldType) {
288                    case "DateTime":
289                        displayValue = parseDate(displayValue).getTimestamp();
290                        break;
291                }
292                self.text(displayValue);
293            }
294            else {
295                self.text(data[name]);
296            }
297        }
298        else {
299            self.text("");
300        }
301    });
302
303    $(selector).find(':input[name]:enabled').each(function () {
304        const self = $(this);
305        const name = self.attr('name');
306
307        if (data[name] != null) {
308            if (self.is(":checkbox") || self.is(":radio")) {
309                self.prop("checked", data[name]);
310                return; //Logic: Behaves as continue since we're in a callback
311            }
312
313            self.val(data[name]);
314        }
315        else {
316            self.val("");
317        }
318    });
319}
320
321function WildcardToRegex(pattern)
322{
323    if (pattern == null) { return null; }
324
325    let escapeRegex = function (string) {
326        return string.replaceAll(/([.*+?^${}()|[\]/\\])/g, "\\$1");
327    };
328
329    let escapeReplace = function (data, original, replacement) {
330        const searchRegex = new RegExp("\\\\+\\" + original, "g");
331        const newRegex = data.replaceAll(searchRegex, function (match) {
332            const count = match.length - 1;
333            const halfCount = Math.floor(count / 2);
334            const newSlashes = new Array(halfCount).join("\\");
335            const result = newSlashes + ((halfCount % 2 === 0) ? replacement : original);
336            return result;
337        });
338        return newRegex;
339    };
340
341    let toRegex = function (pattern, starMatchesEmpty, flags) {
342        let reg = "^" + escapeRegex(pattern) + "$";
343        reg = escapeReplace(reg, "?", "(.)");
344        reg = escapeReplace(reg, "*", starMatchesEmpty === true ? "(.*?)" : "(.+?)");
345        return new RegExp(reg, flags);
346    };
347
348    return toRegex(pattern, false);
349}
350
351function CalcLevenshteinDistance(a, b) {
352    if (a == null || b == null) { return 0; }
353
354    const lengthA = a.length;
355    const lengthB = b.length;
356    let distances = [];
357    for (let x = 0; x <= lengthA; x++) {
358        distances[x] = [];
359    }
360    for (let i = 0; i <= lengthA; distances[i][0] = i++);
361    for (let j = 0; j <= lengthB; distances[0][j] = j++);
362
363    for (let i = 1; i <= lengthA; i++) {
364        for (let j = 1; j <= lengthB; j++) {
365            const cost = b[j - 1] === a[i - 1] ? 0 : 1;
366            distances[i][j] = Math.min(
367                    Math.min(distances[i - 1][j] + 1, distances[i][j - 1] + 1),
368                    distances[i - 1][j - 1] + cost);
369        }
370    }
371    return distances[lengthA][lengthB];
372}
373
374function uuid4() {
375    function hex(s, b) {
376        return s +
377            (b >>> 4).toString(16) +  // high nibble
378            (b & 0b1111).toString(16);   // low nibble
379    }
380
381    let r = crypto.getRandomValues(new Uint8Array(16));
382
383    r[6] = r[6] >>> 4 | 0b01000000; // Set type 4: 0100
384    r[8] = r[8] >>> 3 | 0b10000000; // Set variant: 100
385
386    return r.slice(0, 4).reduce(hex, '') +
387        r.slice(4, 6).reduce(hex, '-') +
388        r.slice(6, 8).reduce(hex, '-') +
389        r.slice(8, 10).reduce(hex, '-') +
390        r.slice(10, 16).reduce(hex, '-');
391}
392
393function generateSecurePassword(length) {
394    const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^*()_+';
395    let password = '';
396    const buffer = new Uint8Array(length);
397
398    crypto.getRandomValues(buffer);
399    for (const element of buffer) {
400        password += charset[element % charset.length];
401    }
402
403    return password;
404}
405
406class Version {
407    constructor(major, minor, revision, build) {
408        this.Major = major || 0;
409        this.Minor = minor || 0;
410        this.Revision = revision || 0;
411        this.Build = build || 0;
412    }
413
414    static parse(versionString = "0.0.0.0") {
415        const [major, minor, revision, build] = versionString.split(".").map(Number);
416        return new Version(major, minor, revision, build);
417    }
418
419    static fromObject(obj) {
420        return new Version(obj?.Major || 0, obj?.Minor || 0, obj?.Revision || 0, obj?.Build || 0);
421    }
422
423    newerThan = otherVersion => this.compare(otherVersion) > 0;
424    olderThan = otherVersion => this.compare(otherVersion) < 0;
425    equalTo = otherVersion => this.compare(otherVersion) === 0;
426    olderThanOrEqualTo = otherVersion => this.compare(otherVersion) <= 0;
427    newerThanOrEqualTo = otherVersion => this.compare(otherVersion) >= 0;
428    toString = (parts) => [this.Major, this.Minor, this.Revision, this.Build].splice(0, parts || 4).join(".");
429
430    getParts(parts) {
431        return parse(toString(parts));
432    }
433
434    compare(otherVersion) {
435        if (typeof (otherVersion) === "string") {
436            return this.compare(Version.parse(otherVersion));
437        }
438
439        if (!(otherVersion instanceof Version)) {
440            throw new TypeError("Invalid argument: 'otherVersion' must be an instance of Version.");
441        }
442
443        if (this.Major !== otherVersion.Major) {
444            return this.Major - otherVersion.Major;
445        }
446
447        if (this.Minor !== otherVersion.Minor) {
448            return this.Minor - otherVersion.Minor;
449        }
450
451        if (this.Revision !== otherVersion.Revision) {
452            return this.Revision - otherVersion.Revision;
453        }
454
455        return this.Build - otherVersion.Build;
456    }
457}
458
459class TokenStream {
460    constructor(input) {
461        this.input = input;
462        this.index = 0;
463        this.regex = /"[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*'|==|!=|>=|<=|&&|\|\||<|>|\(|\)|\b[A-Za-z0-9_.]+\b|\btrue\b|\bfalse\b|\b\d+\b/g;
464        this.tokens = this.input.match(this.regex);
465    }
466
467    next() { return this.tokens[this.index++]; }
468    peek() { return this.tokens[this.index]; }
469    eof() { return this.peek() === undefined; }
470}
471
472class Parser {
473    constructor(input, callback) {
474        this.tokens = new TokenStream(input);
475        this.callback = callback;
476    }
477
478    parse() {
479        let expr = this.boolean();
480        if (!this.tokens.eof()) throw new SyntaxError("Unexpected '" + this.tokens.peek() + "'");
481        return expr;
482    }
483
484    boolean() {
485        let expr = this.comparison();
486        while (!this.tokens.eof() && /^&&|\|\|$/.test(this.tokens.peek())) {
487            let op = this.tokens.next() === '&&' ? (a, b) => a && b : (a, b) => a || b;
488            expr = op(expr, this.comparison());
489        }
490        return expr;
491    }
492
493    comparison() {
494        let expr = this.expression();
495        let operators = {
496            '==': (a, b) => a == b,
497            '!=': (a, b) => a != b,
498            '>=': (a, b) => a >= b,
499            '<=': (a, b) => a <= b,
500            '>': (a, b) => a > b,
501            '<': (a, b) => a < b
502        };
503
504        while (!this.tokens.eof() && operators[this.tokens.peek()]) {
505            let op = operators[this.tokens.next()];
506            expr = op(expr, this.expression());
507        }
508
509        return expr;
510    }
511
512    expression() {
513        let expr;
514        if (this.tokens.peek() === "(") {
515            this.tokens.next();
516            expr = this.boolean();
517            if (this.tokens.next() !== ")") throw new SyntaxError("Expected ')'");
518        } else {
519            expr = this.value();
520        }
521        return expr;
522    }
523
524    value() {
525        if (/^\d+$/.test(this.tokens.peek())) return Number(this.tokens.next());
526        if (/^true|false$/.test(this.tokens.peek())) return this.tokens.next() === 'true';
527        if (/^"[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*'$/.test(this.tokens.peek())) {
528            let str = this.tokens.next();
529            return str.substring(1, str.length - 1).replaceAll(/\\(.)/g, "$1");
530        }
531        return this.callback(this.tokens.next());
532    }
533}
534
535function evaluateExpression(expression, callback) {
536    return new Parser(expression, callback).parse();
537}
538
539function createTable(obj) {
540    const keys = Object.keys(obj);
541    const values = Object.values(obj);
542
543    // Calculate the width of the widest key and value
544    let maxWidthKey = Math.max(...keys.map(key => key.length));
545    let maxWidthValue = Math.max(...values.map(value => String(value).length));
546
547    let table = "";
548
549    // Create the table header
550    table += "┏" + "━".repeat(maxWidthKey) + "━━┳━" + "━".repeat(maxWidthValue) + "━┓\n";
551    table += "┃ " + "Key".padEnd(maxWidthKey) + " ┃ " + "Value".padEnd(maxWidthValue) + " ┃\n";
552    table += "┣" + "━".repeat(maxWidthKey) + "━━╋━" + "━".repeat(maxWidthValue) + "━┫\n";
553
554    // Iterate over keys and values to create table rows
555    for (let i = 0; i < keys.length; i++) {
556        table += "┃ " + keys[i].padEnd(maxWidthKey) + " ┃ " + String(values[i]).padEnd(maxWidthValue) + " ┃\n";
557    }
558
559    // Create the table footer
560    table += "┗" + "━".repeat(maxWidthKey) + "━━┻━" + "━".repeat(maxWidthValue) + "━┛\n";
561
562    return table;
563}
564
565function setupClickPulse() {
566    const selector = getComputedStyle(document.body).getPropertyValue("--pulse-on-click");
567    for (const item of document.querySelectorAll(selector)) {
568        item.classList.add("pulse-container")
569        item.addEventListener('click', function (e) {
570            // Create the pulse element
571            const pulse = document.createElement('div');
572            pulse.classList.add('pulse');
573            this.appendChild(pulse);
574
575            // Position the pulse element
576            const rect = this.getBoundingClientRect();
577            const x = e.clientX - rect.left;
578            const y = e.clientY - rect.top;
579            pulse.style.left = `${x}px`;
580            pulse.style.top = `${y}px`;
581
582            // Clean up pulse element after animation
583            pulse.addEventListener('animationend', () => {
584                pulse.remove();
585            });
586        });
587    }
588}

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.