PageSourceSearch

https://www.destination-mayenne.com/app/dist/tourisme-mayenne/addo…/code/es-modules/Core/Templating.js

js destination-mayenne.com collected 2026-10-09 05:00:43 UTC 14,506 bytes, 401 lines download raw bytes

1/* *
2 *
3 *  (c) 2010-2024 Torstein Honsi
4 *
5 *  License: www.highcharts.com/license
6 *
7 *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
8 *
9 * */
10'use strict';
11import D from './Defaults.js';
12const { defaultOptions, defaultTime } = D;
13import G from './Globals.js';
14const { pageLang } = G;
15import U from './Utilities.js';
16const { extend, getNestedProperty, isArray, isNumber, isObject, isString, pick, ucfirst } = U;
17const helpers = {
18    // Built-in helpers
19    add: (a, b) => a + b,
20    divide: (a, b) => (b !== 0 ? a / b : ''),
21    // eslint-disable-next-line eqeqeq
22    eq: (a, b) => a == b,
23    each: function (arr) {
24        const match = arguments[arguments.length - 1];
25        return isArray(arr) ?
26            arr.map((item, i) => format(match.body, extend(isObject(item) ? item : { '@this': item }, {
27                '@index': i,
28                '@first': i === 0,
29                '@last': i === arr.length - 1
30            }))).join('') :
31            false;
32    },
33    ge: (a, b) => a >= b,
34    gt: (a, b) => a > b,
35    'if': (condition) => !!condition,
36    le: (a, b) => a <= b,
37    lt: (a, b) => a < b,
38    multiply: (a, b) => a * b,
39    // eslint-disable-next-line eqeqeq
40    ne: (a, b) => a != b,
41    subtract: (a, b) => a - b,
42    ucfirst,
43    unless: (condition) => !condition
44};
45const numberFormatCache = {};
46/* *
47 *
48 *  Functions
49 *
50 * */
51// Internal convenience function
52const isQuotedString = (str) => /^["'].+["']$/.test(str);
53/**
54 * Formats a JavaScript date timestamp (milliseconds since Jan 1st 1970) into a
55 * human readable date string. The format is a subset of the formats for PHP's
56 * [strftime](https://www.php.net/manual/en/function.strftime.php) function.
57 * Additional formats can be given in the {@link Highcharts.dateFormats} hook.
58 *
59 * Since v6.0.5, all internal dates are formatted through the
60 * {@link Highcharts.Chart#time} instance to respect chart-level time settings.
61 * The `Highcharts.dateFormat` function only reflects global time settings set
62 * with `setOptions`.
63 *
64 * Supported format keys:
65 * - `%a`: Short weekday, like 'Mon'
66 * - `%A`: Long weekday, like 'Monday'
67 * - `%d`: Two digit day of the month, 01 to 31
68 * - `%e`: Day of the month, 1 through 31
69 * - `%w`: Day of the week, 0 through 6
70 * - `%b`: Short month, like 'Jan'
71 * - `%B`: Long month, like 'January'
72 * - `%m`: Two digit month number, 01 through 12
73 * - `%y`: Two digits year, like 09 for 2009
74 * - `%Y`: Four digits year, like 2009
75 * - `%H`: Two digits hours in 24h format, 00 through 23
76 * - `%k`: Hours in 24h format, 0 through 23
77 * - `%I`: Two digits hours in 12h format, 00 through 11
78 * - `%l`: Hours in 12h format, 1 through 12
79 * - `%M`: Two digits minutes, 00 through 59
80 * - `%p`: Upper case AM or PM
81 * - `%P`: Lower case AM or PM
82 * - `%S`: Two digits seconds, 00 through 59
83 * - `%L`: Milliseconds (naming from Ruby)
84 *
85 * @function Highcharts.dateFormat
86 *
87 * @param {string} format
88 *        The desired format where various time representations are prefixed
89 *        with `%`.
90 *
91 * @param {number} timestamp
92 *        The JavaScript timestamp.
93 *
94 * @param {boolean} [upperCaseFirst=false]
95 *        Upper case first letter in the return.
96 *
97 * @return {string}
98 *         The formatted date.
99 */
100function dateFormat(format, timestamp, upperCaseFirst) {
101    return defaultTime.dateFormat(format, timestamp, upperCaseFirst);
102}
103/**
104 * Format a string according to a subset of the rules of Python's String.format
105 * method.
106 *
107 * @example
108 * let s = Highcharts.format(
109 *     'The {color} fox was {len:.2f} feet long',
110 *     { color: 'red', len: Math.PI }
111 * );
112 * // => The red fox was 3.14 feet long
113 *
114 * @function Highcharts.format
115 *
116 * @param {string} str
117 *        The string to format.
118 *
119 * @param {Record<string, *>} ctx
120 *        The context, a collection of key-value pairs where each key is
121 *        replaced by its value.
122 *
123 * @param {Highcharts.Chart} [chart]
124 *        A `Chart` instance used to get numberFormatter and time.
125 *
126 * @return {string}
127 *         The formatted string.
128 */
129function format(str = '', ctx, chart) {
130    const regex = /\{([\p{L}\d:\.,;\-\/<>\[\]%_@+"'’= #\(\)]+)\}/gu, 
131    // The sub expression regex is the same as the top expression regex,
132    // but except parens and block helpers (#), and surrounded by parens
133    // instead of curly brackets.
134    subRegex = /\(([\p{L}\d:\.,;\-\/<>\[\]%_@+"'= ]+)\)/gu, matches = [], floatRegex = /f$/, decRegex = /\.(\d)/, lang = chart?.options.lang || defaultOptions.lang, time = chart && chart.time || defaultTime, numberFormatter = chart && chart.numberFormatter || numberFormat;
135    /*
136     * Get a literal or variable value inside a template expression. May be
137     * extended with other types like string or null if needed, but keep it
138     * small for now.
139     */
140    const resolveProperty = (key = '') => {
141        let n;
142        // Literals
143        if (key === 'true') {
144            return true;
145        }
146        if (key === 'false') {
147            return false;
vendor: 9,481 bytes, lines 148-401
148        }
149        if ((n = Number(key)).toString() === key) {
150            return n;
151        }
152        if (isQuotedString(key)) {
153            return key.slice(1, -1);
154        }
155        // Variables and constants
156        return getNestedProperty(key, ctx);
157    };
158    let match, currentMatch, depth = 0, hasSub;
159    // Parse and create tree
160    while ((match = regex.exec(str)) !== null) {
161        // When a sub expression is found, it is evaluated first, and the
162        // results recursively evaluated until no subexpression exists.
163        const mainMatch = match, subMatch = subRegex.exec(match[1]);
164        if (subMatch) {
165            match = subMatch;
166            hasSub = true;
167        }
168        if (!currentMatch || !currentMatch.isBlock) {
169            currentMatch = {
170                ctx,
171                expression: match[1],
172                find: match[0],
173                isBlock: match[1].charAt(0) === '#',
174                start: match.index,
175                startInner: match.index + match[0].length,
176                length: match[0].length
177            };
178        }
179        // Identify helpers
180        const fn = (currentMatch.isBlock ? mainMatch : match)[1].split(' ')[0].replace('#', '');
181        if (helpers[fn]) {
182            // Block helper, only 0 level is handled
183            if (currentMatch.isBlock && fn === currentMatch.fn) {
184                depth++;
185            }
186            if (!currentMatch.fn) {
187                currentMatch.fn = fn;
188            }
189        }
190        // Closing a block helper
191        const startingElseSection = match[1] === 'else';
192        if (currentMatch.isBlock &&
193            currentMatch.fn && (match[1] === `/${currentMatch.fn}` ||
194            startingElseSection)) {
195            if (!depth) { // === 0
196                const start = currentMatch.startInner, body = str.substr(start, match.index - start);
197                // Either closing without an else section, or when encountering
198                // an else section
199                if (currentMatch.body === void 0) {
200                    currentMatch.body = body;
201                    currentMatch.startInner = match.index + match[0].length;
202                    // The body exists already, so this is the else section
203                }
204                else {
205                    currentMatch.elseBody = body;
206                }
207                currentMatch.find += body + match[0];
208                if (!startingElseSection) {
209                    matches.push(currentMatch);
210                    currentMatch = void 0;
211                }
212            }
213            else if (!startingElseSection) {
214                depth--;
215            }
216            // Common expression
217        }
218        else if (!currentMatch.isBlock) {
219            matches.push(currentMatch);
220        }
221        // Evaluate sub-matches one by one to prevent orphaned block closers
222        if (subMatch && !currentMatch?.isBlock) {
223            break;
224        }
225    }
226    // Execute
227    matches.forEach((match) => {
228        const { body, elseBody, expression, fn } = match;
229        let replacement, i;
230        // Helper function
231        if (fn) {
232            // Pass the helpers the amount of arguments defined by the function,
233            // then the match as the last argument.
234            const args = [match], parts = [], len = expression.length;
235            let start = 0, startChar;
236            for (i = 0; i <= len; i++) {
237                const char = expression.charAt(i);
238                // Start of string
239                if (!startChar && (char === '"' || char === '\'')) {
240                    startChar = char;
241                    // End of string
242                }
243                else if (startChar === char) {
244                    startChar = '';
245                }
246                if (!startChar &&
247                    (char === ' ' || i === len)) {
248                    parts.push(expression.substr(start, i - start));
249                    start = i + 1;
250                }
251            }
252            i = helpers[fn].length;
253            while (i--) {
254                args.unshift(resolveProperty(parts[i + 1]));
255            }
256            replacement = helpers[fn].apply(ctx, args);
257            // Block helpers may return true or false. They may also return a
258            // string, like the `each` helper.
259            if (match.isBlock && typeof replacement === 'boolean') {
260                replacement = format(replacement ? body : elseBody, ctx, chart);
261            }
262            // Simple variable replacement
263        }
264        else {
265            const valueAndFormat = isQuotedString(expression) ?
266                [expression] : expression.split(':');
267            replacement = resolveProperty(valueAndFormat.shift() || '');
268            // Format the replacement
269            if (valueAndFormat.length && typeof replacement === 'number') {
270                const segment = valueAndFormat.join(':');
271                if (floatRegex.test(segment)) { // Float
272                    const decimals = parseInt((segment.match(decRegex) || ['', '-1'])[1], 10);
273                    if (replacement !== null) {
274                        replacement = numberFormatter(replacement, decimals, lang.decimalPoint, segment.indexOf(',') > -1 ? lang.thousandsSep : '');
275                    }
276                }
277                else {
278                    replacement = time.dateFormat(segment, replacement);
279                }
280            }
281            // Use string literal in order to be preserved in the outer
282            // expression
283            subRegex.lastIndex = 0;
284            if (subRegex.test(match.find) && isString(replacement)) {
285                replacement = `"${replacement}"`;
286            }
287        }
288        str = str.replace(match.find, pick(replacement, ''));
289    });
290    return hasSub ? format(str, ctx, chart) : str;
291}
292/**
293 * Format a number and return a string based on input settings.
294 *
295 * @sample highcharts/members/highcharts-numberformat/
296 *         Custom number format
297 *
298 * @function Highcharts.numberFormat
299 *
300 * @param {number} number
301 *        The input number to format.
302 *
303 * @param {number} decimals
304 *        The amount of decimals. A value of -1 preserves the amount in the
305 *        input number.
306 *
307 * @param {string} [decimalPoint]
308 *        The decimal point, defaults to the one given in the lang options, or
309 *        a dot.
310 *
311 * @param {string} [thousandsSep]
312 *        The thousands separator, defaults to the one given in the lang
313 *        options, or a space character.
314 *
315 * @return {string}
316 *         The formatted number.
317 */
318function numberFormat(number, decimals, decimalPoint, thousandsSep) {
319    number = +number || 0;
320    decimals = +decimals;
321    let ret, fractionDigits, [mantissa, exp] = number.toString().split('e').map(Number);
322    const lang = this?.options?.lang || defaultOptions.lang, origDec = (number.toString().split('.')[1] || '').split('e')[0].length, firstDecimals = decimals, options = {};
323    decimalPoint ?? (decimalPoint = lang.decimalPoint);
324    thousandsSep ?? (thousandsSep = lang.thousandsSep);
325    if (decimals === -1) {
326        // Preserve decimals. Not huge numbers (#3793).
327        decimals = Math.min(origDec, 20);
328    }
329    else if (!isNumber(decimals)) {
330        decimals = 2;
331    }
332    else if (decimals && exp < 0) {
333        // Expose decimals from exponential notation (#7042)
334        fractionDigits = decimals + exp;
335        if (fractionDigits >= 0) {
336            // Remove too small part of the number while keeping the notation
337            mantissa = +mantissa.toExponential(fractionDigits).split('e')[0];
338            decimals = fractionDigits;
339        }
340        else {
341            // `fractionDigits < 0`
342            mantissa = Math.floor(mantissa);
343            if (decimals < 20) {
344                // Use number instead of exponential notation (#7405)
345                number = +(mantissa * Math.pow(10, exp)).toFixed(decimals);
346            }
347            else {
348                // Or zero
349                number = 0;
350            }
351            exp = 0;
352        }
353    }
354    if (exp) {
355        decimals ?? (decimals = 2);
356        number = mantissa;
357    }
358    if (isNumber(decimals) && decimals >= 0) {
359        options.minimumFractionDigits = decimals;
360        options.maximumFractionDigits = decimals;
361    }
362    if (thousandsSep === '') {
363        options.useGrouping = false;
364    }
365    const hasSeparators = thousandsSep || decimalPoint, locale = hasSeparators ?
366        'en' :
367        (this?.locale || lang.locale || pageLang), cacheKey = JSON.stringify(options) + locale, nf = numberFormatCache[cacheKey] ?? (numberFormatCache[cacheKey] = new Intl.NumberFormat(locale, options));
368    ret = nf.format(number);
369    // If thousandsSep or decimalPoint are set, fall back to using English
370    // format with string replacement for the separators.
371    if (hasSeparators) {
372        ret = ret
373            // Preliminary step to avoid re-swapping (#22402)
374            .replace(/([,\.])/g, '_$1')
375            .replace(/_\,/g, thousandsSep ?? ',')
376            .replace('_.', decimalPoint ?? '.');
377    }
378    if (
379    // Remove signed zero (#20564)
380    (!decimals && +ret === 0) ||
381        // Small numbers, no decimals (#14023)
382        (exp < 0 && !firstDecimals)) {
383        ret = '0';
384    }
385    if (exp && +ret !== 0) {
386        ret += 'e' + (exp < 0 ? '' : '+') + exp;
387    }
388    return ret;
389}
390/* *
391 *
392 *  Default Export
393 *
394 * */
395const Templating = {
396    dateFormat,
397    format,
398    helpers,
399    numberFormat
400};
401export default Templating;

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.