PageSourceSearch

https://informatiktage.ch/dist/assets/autolinker-aZsZGYsK.js

js informatiktage.ch collected 2026-10-02 18:58:49 UTC 231,418 bytes, 4,883 lines download raw bytes

vendor: 4,090 bytes, lines 1-103
1/******************************************************************************
2Copyright (c) Microsoft Corporation.
3
4Permission to use, copy, modify, and/or distribute this software for any
5purpose with or without fee is hereby granted.
6
7THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13PERFORMANCE OF THIS SOFTWARE.
14***************************************************************************** */
15/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
16
17var extendStatics = function(d, b) {
18  extendStatics = Object.setPrototypeOf ||
19      ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
20      function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
21  return extendStatics(d, b);
22};
23
24function __extends(d, b) {
25  if (typeof b !== "function" && b !== null)
26      throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
27  extendStatics(d, b);
28  function __() { this.constructor = d; }
29  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
30}
31
32var __assign = function() {
33  __assign = Object.assign || function __assign(t) {
34      for (var s, i = 1, n = arguments.length; i < n; i++) {
35          s = arguments[i];
36          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
37      }
38      return t;
39  };
40  return __assign.apply(this, arguments);
41};
42
43function __decorate(decorators, target, key, desc) {
44  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
45  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
46  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
47  return c > 3 && r && Object.defineProperty(target, key, r), r;
48}
49
50function __param(paramIndex, decorator) {
51  return function (target, key) { decorator(target, key, paramIndex); }
52}
53
54function __metadata(metadataKey, metadataValue) {
55  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
56}
57
58function __read(o, n) {
59  var m = typeof Symbol === "function" && o[Symbol.iterator];
60  if (!m) return o;
61  var i = m.call(o), r, ar = [], e;
62  try {
63      while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
64  }
65  catch (error) { e = { error: error }; }
66  finally {
67      try {
68          if (r && !r.done && (m = i["return"])) m.call(i);
69      }
70      finally { if (e) throw e.error; }
71  }
72  return ar;
73}
74
75function __spreadArray(to, from, pack) {
76  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
77      if (ar || !(i in from)) {
78          if (!ar) ar = Array.prototype.slice.call(from, 0, i);
79          ar[i] = from[i];
80      }
81  }
82  return to.concat(ar || Array.prototype.slice.call(from));
83}
84
85typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
86  var e = new Error(message);
87  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
88};
89
90// Important: this file is generated from the 'build' script and should not be
91// edited directly
92var version = '4.1.5';
93
94var hasOwnProperty = Object.prototype.hasOwnProperty;
95/**
96 * Simpler helper method to check for a boolean type simply for the benefit of
97 * gaining better compression when minified by not needing to have multiple
98 * `typeof` comparisons in the codebase.
99 */
100function isBoolean(value) {
101    return typeof value === 'boolean';
102}
103/**
104 * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the
105 * end of the string (by default, two periods: '..'). If the `str` length does not exceed
106 * `len`, the string will be returned unchanged.
107 *
108 * @param {String} str The string to truncate and add an ellipsis to.
109 * @param {Number} truncateLen The length to truncate the string at.
110 * @param {String} [ellipsisChars=...] The ellipsis character(s) to add to the end of `str`
111 *   when truncated. Defaults to '...'
112 */
113function ellipsis(str, truncateLen, ellipsisChars) {
114    var ellipsisLength;
115    if (str.length > truncateLen) {
116        if (ellipsisChars == null) {
117            ellipsisChars = '&hellip;';
118            ellipsisLength = 3;
119        }
120        else {
121            ellipsisLength = ellipsisChars.length;
122        }
123        str = str.substring(0, truncateLen - ellipsisLength) + ellipsisChars;
124    }
125    return str;
126}
127/**
128 * Removes array elements based on a filtering function. Mutates the input
129 * array.
130 *
131 * Using this instead of the ES5 Array.prototype.filter() function to prevent
132 * creating many new arrays in memory for filtering.
133 *
134 * @param arr The array to remove elements from. This array is mutated.
135 * @param fn The predicate function which should return `true` to remove an
136 *   element.
137 */
138function removeWithPredicate(arr, fn) {
139    for (var i = arr.length - 1; i >= 0; i--) {
140        if (fn(arr[i]) === true) {
141            arr.splice(i, 1);
142        }
143    }
144}
145/**
146 * Function that should never be called but is used to check that every
147 * enum value is handled using TypeScript's 'never' type.
148 */
149/* istanbul ignore next */
150function assertNever(theValue) {
151    throw new Error("Unhandled case for value: '".concat(theValue, "'"));
152}
153
154// Regular expression to match whitespace
vendor: 10,889 bytes, lines 155-449
155var whitespaceRe = /\s+/;
156/**
157 * @class Autolinker.HtmlTag
158 * @extends Object
159 *
160 * Represents an HTML tag, which can be used to easily build/modify HTML tags programmatically.
161 *
162 * Autolinker uses this abstraction to create HTML tags, and then write them out as strings. You may also use
163 * this class in your code, especially within a {@link Autolinker#replaceFn replaceFn}.
164 *
165 * ## Examples
166 *
167 * Example instantiation:
168 *
169 *     var tag = new Autolinker.HtmlTag( {
170 *         tagName : 'a',
171 *         attrs   : { 'href': 'http://google.com', 'class': 'external-link' },
172 *         innerHtml : 'Google'
173 *     } );
174 *
175 *     tag.toAnchorString();  // <a href="http://google.com" class="external-link">Google</a>
176 *
177 *     // Individual accessor methods
178 *     tag.getTagName();                 // 'a'
179 *     tag.getAttr( 'href' );            // 'http://google.com'
180 *     tag.hasClass( 'external-link' );  // true
181 *
182 *
183 * Using mutator methods (which may be used in combination with instantiation config properties):
184 *
185 *     var tag = new Autolinker.HtmlTag();
186 *     tag.setTagName( 'a' );
187 *     tag.setAttr( 'href', 'http://google.com' );
188 *     tag.addClass( 'external-link' );
189 *     tag.setInnerHtml( 'Google' );
190 *
191 *     tag.getTagName();                 // 'a'
192 *     tag.getAttr( 'href' );            // 'http://google.com'
193 *     tag.hasClass( 'external-link' );  // true
194 *
195 *     tag.toAnchorString();  // <a href="http://google.com" class="external-link">Google</a>
196 *
197 *
198 * ## Example use within a {@link Autolinker#replaceFn replaceFn}
199 *
200 *     var html = Autolinker.link( "Test google.com", {
201 *         replaceFn : function( match ) {
202 *             var tag = match.buildTag();  // returns an {@link Autolinker.HtmlTag} instance, configured with the Match's href and anchor text
203 *             tag.setAttr( 'rel', 'nofollow' );
204 *
205 *             return tag;
206 *         }
207 *     } );
208 *
209 *     // generated html:
210 *     //   Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a>
211 *
212 *
213 * ## Example use with a new tag for the replacement
214 *
215 *     var html = Autolinker.link( "Test google.com", {
216 *         replaceFn : function( match ) {
217 *             var tag = new Autolinker.HtmlTag( {
218 *                 tagName : 'button',
219 *                 attrs   : { 'title': 'Load URL: ' + match.getAnchorHref() },
220 *                 innerHtml : 'Load URL: ' + match.getAnchorText()
221 *             } );
222 *
223 *             return tag;
224 *         }
225 *     } );
226 *
227 *     // generated html:
228 *     //   Test <button title="Load URL: http://google.com">Load URL: google.com</button>
229 */
230var HtmlTag = /** @class */ (function () {
231    /**
232     * @method constructor
233     * @param {Object} [cfg] The configuration properties for this class, in an Object (map)
234     */
235    function HtmlTag(cfg) {
236        if (cfg === void 0) { cfg = {}; }
237        /**
238         * @cfg {String} tagName
239         *
240         * The tag name. Ex: 'a', 'button', etc.
241         *
242         * Not required at instantiation time, but should be set using {@link #setTagName} before {@link #toAnchorString}
243         * is executed.
244         */
245        this.tagName = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
246        /**
247         * @cfg {Object.<String, String>} attrs
248         *
249         * An key/value Object (map) of attributes to create the tag with. The keys are the attribute names, and the
250         * values are the attribute values.
251         */
252        this.attrs = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
253        /**
254         * @cfg {String} innerHTML
255         *
256         * The inner HTML for the tag.
257         */
258        this.innerHTML = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
259        this.tagName = cfg.tagName || '';
260        this.attrs = cfg.attrs || {};
261        this.innerHTML = cfg.innerHtml || cfg.innerHTML || ''; // accept either the camelCased form or the fully capitalized acronym as in the DOM
262    }
263    /**
264     * Sets the tag name that will be used to generate the tag with.
265     *
266     * @param {String} tagName
267     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
268     */
269    HtmlTag.prototype.setTagName = function (tagName) {
270        this.tagName = tagName;
271        return this;
272    };
273    /**
274     * Retrieves the tag name.
275     *
276     * @return {String}
277     */
278    HtmlTag.prototype.getTagName = function () {
279        return this.tagName;
280    };
281    /**
282     * Sets an attribute on the HtmlTag.
283     *
284     * @param {String} attrName The attribute name to set.
285     * @param {String} attrValue The attribute value to set.
286     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
287     */
288    HtmlTag.prototype.setAttr = function (attrName, attrValue) {
289        var tagAttrs = this.getAttrs();
290        tagAttrs[attrName] = attrValue;
291        return this;
292    };
293    /**
294     * Retrieves an attribute from the HtmlTag. If the attribute does not exist, returns `undefined`.
295     *
296     * @param {String} attrName The attribute name to retrieve.
297     * @return {String} The attribute's value, or `undefined` if it does not exist on the HtmlTag.
298     */
299    HtmlTag.prototype.getAttr = function (attrName) {
300        return this.getAttrs()[attrName];
301    };
302    /**
303     * Sets one or more attributes on the HtmlTag.
304     *
305     * @param {Object.<String, String>} attrs A key/value Object (map) of the attributes to set.
306     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
307     */
308    HtmlTag.prototype.setAttrs = function (attrs) {
309        Object.assign(this.getAttrs(), attrs);
310        return this;
311    };
312    /**
313     * Retrieves the attributes Object (map) for the HtmlTag.
314     *
315     * @return {Object.<String, String>} A key/value object of the attributes for the HtmlTag.
316     */
317    HtmlTag.prototype.getAttrs = function () {
318        return this.attrs;
319    };
320    /**
321     * Sets the provided `cssClass`, overwriting any current CSS classes on the HtmlTag.
322     *
323     * @param {String} cssClass One or more space-separated CSS classes to set (overwrite).
324     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
325     */
326    HtmlTag.prototype.setClass = function (cssClass) {
327        return this.setAttr('class', cssClass);
328    };
329    /**
330     * Convenience method to add one or more CSS classes to the HtmlTag. Will not add duplicate CSS classes.
331     *
332     * @param {String} cssClass One or more space-separated CSS classes to add.
333     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
334     */
335    HtmlTag.prototype.addClass = function (cssClass) {
336        var classAttr = this.getClass();
337        var classes = !classAttr ? [] : classAttr.split(whitespaceRe);
338        var newClasses = cssClass.split(whitespaceRe);
339        var newClass;
340        while ((newClass = newClasses.shift())) {
341            if (classes.indexOf(newClass) === -1) {
342                classes.push(newClass);
343            }
344        }
345        this.getAttrs()['class'] = classes.join(' ');
346        return this;
347    };
348    /**
349     * Convenience method to remove one or more CSS classes from the HtmlTag.
350     *
351     * @param {String} cssClass One or more space-separated CSS classes to remove.
352     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
353     */
354    HtmlTag.prototype.removeClass = function (cssClass) {
355        var classAttr = this.getClass();
356        var classes = !classAttr ? [] : classAttr.split(whitespaceRe);
357        var removeClasses = cssClass.split(whitespaceRe);
358        var removeClass;
359        while (classes.length && (removeClass = removeClasses.shift())) {
360            var idx = classes.indexOf(removeClass);
361            if (idx !== -1) {
362                classes.splice(idx, 1);
363            }
364        }
365        this.getAttrs()['class'] = classes.join(' ');
366        return this;
367    };
368    /**
369     * Convenience method to retrieve the CSS class(es) for the HtmlTag, which will each be separated by spaces when
370     * there are multiple.
371     *
372     * @return {String}
373     */
374    HtmlTag.prototype.getClass = function () {
375        return this.getAttrs()['class'] || '';
376    };
377    /**
378     * Convenience method to check if the tag has a CSS class or not.
379     *
380     * @param {String} cssClass The CSS class to check for.
381     * @return {Boolean} `true` if the HtmlTag has the CSS class, `false` otherwise.
382     */
383    HtmlTag.prototype.hasClass = function (cssClass) {
384        return (' ' + this.getClass() + ' ').indexOf(' ' + cssClass + ' ') !== -1;
385    };
386    /**
387     * Sets the inner HTML for the tag.
388     *
389     * @param {String} html The inner HTML to set.
390     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
391     */
392    HtmlTag.prototype.setInnerHTML = function (html) {
393        this.innerHTML = html;
394        return this;
395    };
396    /**
397     * Backwards compatibility method name.
398     *
399     * @param {String} html The inner HTML to set.
400     * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.
401     */
402    HtmlTag.prototype.setInnerHtml = function (html) {
403        return this.setInnerHTML(html);
404    };
405    /**
406     * Retrieves the inner HTML for the tag.
407     *
408     * @return {String}
409     */
410    HtmlTag.prototype.getInnerHTML = function () {
411        return this.innerHTML || '';
412    };
413    /**
414     * Backward compatibility method name.
415     *
416     * @return {String}
417     */
418    HtmlTag.prototype.getInnerHtml = function () {
419        return this.getInnerHTML();
420    };
421    /**
422     * Generates the HTML string for the tag.
423     *
424     * @return {String}
425     */
426    HtmlTag.prototype.toAnchorString = function () {
427        var tagName = this.getTagName();
428        var attrsStr = this.buildAttrsStr();
429        attrsStr = attrsStr ? ' ' + attrsStr : ''; // prepend a space if there are actually attributes
430        return ['<', tagName, attrsStr, '>', this.getInnerHtml(), '</', tagName, '>'].join('');
431    };
432    /**
433     * Support method for {@link #toAnchorString}, returns the string space-separated key="value" pairs, used to populate
434     * the stringified HtmlTag.
435     *
436     * @protected
437     * @return {String} Example return: `attr1="value1" attr2="value2"`
438     */
439    HtmlTag.prototype.buildAttrsStr = function () {
440        var attrs = this.getAttrs(), attrsArr = [];
441        for (var prop in attrs) {
442            if (hasOwnProperty.call(attrs, prop)) {
443                attrsArr.push(prop + '="' + attrs[prop] + '"');
444            }
445        }
446        return attrsArr.join(' ');
447    };
448    return HtmlTag;
449}());
vendor: 10,436 bytes, lines 450-730
450
451/**
452 * Date: 2015-10-05
453 * Author: Kasper Søfren <[email protected]> (https://github.com/kafoso)
454 *
455 * A truncation feature, where the ellipsis will be placed at a section within
456 * the URL making it still somewhat human readable.
457 *
458 * @param {String} url						 A URL.
459 * @param {Number} truncateLen		 The maximum length of the truncated output URL string.
460 * @param {String} ellipsisChars	 The characters to place within the url, e.g. "...".
461 * @return {String} The truncated URL.
462 */
463function truncateSmart(url, truncateLen, ellipsisChars) {
464    var ellipsisLengthBeforeParsing;
465    var ellipsisLength;
466    if (ellipsisChars == null) {
467        ellipsisChars = '&hellip;';
468        ellipsisLength = 3;
469        ellipsisLengthBeforeParsing = 8;
470    }
471    else {
472        ellipsisLength = ellipsisChars.length;
473        ellipsisLengthBeforeParsing = ellipsisChars.length;
474    }
475    // If the URL is shorter than the truncate length, return it as is
476    if (url.length <= truncateLen) {
477        return url;
478    }
479    var availableLength = truncateLen - ellipsisLength;
480    var urlObj = parseUrl(url);
481    // Clean up the URL by removing any malformed query string
482    // (e.g. "?foo=bar?ignorethis")
483    if (urlObj.query) {
484        var matchQuery = urlObj.query.match(/^(.*?)(?=(\?|#))(.*?)$/i);
485        if (matchQuery) {
486            // Malformed URL; two or more "?". Removed any content behind the 2nd.
487            urlObj.query = urlObj.query.substr(0, matchQuery[1].length);
488            url = buildUrl(urlObj);
489        }
490    }
491    if (url.length <= truncateLen) {
492        return url; // removing a malformed query string brought the URL under the truncateLength
493    }
494    // Clean up the URL by removing 'www.' from the host if it exists
495    if (urlObj.host) {
496        urlObj.host = urlObj.host.replace(/^www\./, '');
497        url = buildUrl(urlObj);
498    }
499    if (url.length <= truncateLen) {
500        return url; // removing 'www.' brought the URL under the truncateLength
501    }
502    // Process and build the truncated URL, starting with the hostname
503    var truncatedUrl = '';
504    if (urlObj.host) {
505        truncatedUrl += urlObj.host;
506    }
507    if (truncatedUrl.length >= availableLength) {
508        if (urlObj.host.length === truncateLen) {
509            return (urlObj.host.substr(0, truncateLen - ellipsisLength) + ellipsisChars).substr(0, availableLength + ellipsisLengthBeforeParsing);
510        }
511        return buildSegment(truncatedUrl, availableLength, ellipsisChars).substr(0, availableLength + ellipsisLengthBeforeParsing);
512    }
513    // If we still have available chars left, add the path and query string
514    var pathAndQuery = '';
515    if (urlObj.path) {
516        pathAndQuery += '/' + urlObj.path;
517    }
518    if (urlObj.query) {
519        pathAndQuery += '?' + urlObj.query;
520    }
521    if (pathAndQuery) {
522        if ((truncatedUrl + pathAndQuery).length >= availableLength) {
523            if ((truncatedUrl + pathAndQuery).length == truncateLen) {
524                return (truncatedUrl + pathAndQuery).substr(0, truncateLen);
525            }
526            var remainingAvailableLength = availableLength - truncatedUrl.length;
527            return (truncatedUrl + buildSegment(pathAndQuery, remainingAvailableLength, ellipsisChars)).substr(0, availableLength + ellipsisLengthBeforeParsing);
528        }
529        else {
530            truncatedUrl += pathAndQuery;
531        }
532    }
533    // If we still have available chars left, add the fragment
534    if (urlObj.fragment) {
535        var fragment = '#' + urlObj.fragment;
536        if ((truncatedUrl + fragment).length >= availableLength) {
537            if ((truncatedUrl + fragment).length == truncateLen) {
538                return (truncatedUrl + fragment).substr(0, truncateLen);
539            }
540            var remainingAvailableLength2 = availableLength - truncatedUrl.length;
541            return (truncatedUrl + buildSegment(fragment, remainingAvailableLength2, ellipsisChars)).substr(0, availableLength + ellipsisLengthBeforeParsing);
542        }
543        else {
544            truncatedUrl += fragment;
545        }
546    }
547    // If we still have available chars left, add the scheme
548    if (urlObj.scheme && urlObj.host) {
549        var scheme = urlObj.scheme + '://';
550        if ((truncatedUrl + scheme).length < availableLength) {
551            return (scheme + truncatedUrl).substr(0, truncateLen);
552        }
553    }
554    if (truncatedUrl.length <= truncateLen) {
555        return truncatedUrl;
556    }
557    var end = '';
558    if (availableLength > 0) {
559        end = truncatedUrl.substr(-1 * Math.floor(availableLength / 2));
560    }
561    return (truncatedUrl.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);
562}
563/**
564 * Parses a URL into its components: scheme, host, path, query, and fragment.
565 */
566function parseUrl(url) {
567    // Functionality inspired by PHP function of same name
568    var urlObj = {};
569    var urlSub = url;
570    // Parse scheme
571    var match = urlSub.match(/^([a-z]+):\/\//i);
572    if (match) {
573        urlObj.scheme = match[1];
574        urlSub = urlSub.slice(match[0].length);
575    }
576    // Parse host
577    match = urlSub.match(/^(.*?)(?=(\?|#|\/|$))/i);
578    if (match) {
579        urlObj.host = match[1];
580        urlSub = urlSub.slice(match[0].length);
581    }
582    // Parse path
583    match = urlSub.match(/^\/(.*?)(?=(\?|#|$))/i);
584    if (match) {
585        urlObj.path = match[1];
586        urlSub = urlSub.slice(match[0].length);
587    }
588    // Parse query
589    match = urlSub.match(/^\?(.*?)(?=(#|$))/i);
590    if (match) {
591        urlObj.query = match[1];
592        urlSub = urlSub.slice(match[0].length);
593    }
594    // Parse fragment
595    match = urlSub.match(/^#(.*?)$/i);
596    if (match) {
597        urlObj.fragment = match[1];
598        //urlSub = urlSub.slice(match[0].length);  -- not used. Uncomment if adding another block.
599    }
600    return urlObj;
601}
602function buildUrl(urlObj) {
603    var url = '';
604    if (urlObj.scheme && urlObj.host) {
605        url += urlObj.scheme + '://';
606    }
607    if (urlObj.host) {
608        url += urlObj.host;
609    }
610    if (urlObj.path) {
611        url += '/' + urlObj.path;
612    }
613    if (urlObj.query) {
614        url += '?' + urlObj.query;
615    }
616    if (urlObj.fragment) {
617        url += '#' + urlObj.fragment;
618    }
619    return url;
620}
621function buildSegment(segment, remainingAvailableLength, ellipsisChars) {
622    var remainingAvailableLengthHalf = remainingAvailableLength / 2;
623    var startOffset = Math.ceil(remainingAvailableLengthHalf);
624    var endOffset = -1 * Math.floor(remainingAvailableLengthHalf);
625    var end = '';
626    if (endOffset < 0) {
627        end = segment.substr(endOffset);
628    }
629    return segment.substr(0, startOffset) + ellipsisChars + end;
630}
631
632/**
633 * Date: 2015-10-05
634 * Author: Kasper Søfren <[email protected]> (https://github.com/kafoso)
635 *
636 * A truncation feature, where the ellipsis will be placed in the dead-center of the URL.
637 *
638 * @param {String} url             A URL.
639 * @param {Number} truncateLen     The maximum length of the truncated output URL string.
640 * @param {String} ellipsisChars   The characters to place within the url, e.g. "..".
641 * @return {String} The truncated URL.
642 */
643function truncateMiddle(url, truncateLen, ellipsisChars) {
644    if (url.length <= truncateLen) {
645        return url;
646    }
647    var ellipsisLengthBeforeParsing;
648    var ellipsisLength;
649    if (ellipsisChars == null) {
650        ellipsisChars = '&hellip;';
651        ellipsisLengthBeforeParsing = 8;
652        ellipsisLength = 3;
653    }
654    else {
655        ellipsisLengthBeforeParsing = ellipsisChars.length;
656        ellipsisLength = ellipsisChars.length;
657    }
658    var availableLength = truncateLen - ellipsisLength;
659    var end = '';
660    if (availableLength > 0) {
661        end = url.substr(-1 * Math.floor(availableLength / 2));
662    }
663    return (url.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);
664}
665
666/**
667 * A truncation feature where the ellipsis will be placed at the end of the URL.
668 *
669 * @param {String} anchorText
670 * @param {Number} truncateLen The maximum length of the truncated output URL string.
671 * @param {String} ellipsisChars The characters to place within the url, e.g. "..".
672 * @return {String} The truncated URL.
673 */
674function truncateEnd(anchorText, truncateLen, ellipsisChars) {
675    return ellipsis(anchorText, truncateLen, ellipsisChars);
676}
677
678/**
679 * @protected
680 * @class Autolinker.AnchorTagBuilder
681 * @extends Object
682 *
683 * Builds anchor (&lt;a&gt;) tags for the Autolinker utility when a match is
684 * found.
685 *
686 * Normally this class is instantiated, configured, and used internally by an
687 * {@link Autolinker} instance, but may actually be used indirectly in a
688 * {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag}
689 * instances which may be modified before returning from the
690 * {@link Autolinker#replaceFn replaceFn}. For example:
691 *
692 *     var html = Autolinker.link("Test google.com", {
693 *         replaceFn: function(match) {
694 *             var tag = match.buildTag();  // returns an {@link Autolinker.HtmlTag} instance
695 *             tag.setAttr('rel', 'nofollow');
696 *
697 *             return tag;
698 *         }
699 *     });
700 *
701 *     // generated html:
702 *     //   Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a>
703 */
704var AnchorTagBuilder = /** @class */ (function () {
705    /**
706     * @method constructor
707     * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map).
708     */
709    function AnchorTagBuilder(cfg) {
710        if (cfg === void 0) { cfg = {}; }
711        /**
712         * @cfg {Boolean} newWindow
713         * @inheritdoc Autolinker#newWindow
714         */
715        this.newWindow = false; // default value just to get the above doc comment in the ES5 output and documentation generator
716        /**
717         * @cfg {Object} truncate
718         * @inheritdoc Autolinker#truncate
719         */
720        this.truncate = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
721        /**
722         * @cfg {String} className
723         * @inheritdoc Autolinker#className
724         */
725        this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
726        this.newWindow = cfg.newWindow || false;
727        this.truncate = cfg.truncate || {};
728        this.className = cfg.className || '';
729    }
730    /**
731     * Generates the actual anchor (&lt;a&gt;) tag to use in place of the
732     * matched text, via its `match` object.
733     *
734     * @param match The Match instance to generate an anchor tag from.
735     * @return The HtmlTag instance for the anchor tag.
736     */
737    AnchorTagBuilder.prototype.build = function (match) {
738        return new HtmlTag({
739            tagName: 'a',
740            attrs: this.createAttrs(match),
741            innerHtml: this.processAnchorText(match.getAnchorText()),
742        });
743    };
744    /**
745     * Creates the Object (map) of the HTML attributes for the anchor (&lt;a&gt;)
746     *   tag being generated.
747     *
748     * @protected
749     * @param match The Match instance to generate an anchor tag from.
750     * @return A key/value Object (map) of the anchor tag's attributes.
751     */
752    AnchorTagBuilder.prototype.createAttrs = function (match) {
753        var attrs = {
754            href: match.getAnchorHref(), // we'll always have the `href` attribute
755        };
756        var cssClass = this.createCssClass(match);
757        if (cssClass) {
758            attrs['class'] = cssClass;
759        }
760        if (this.newWindow) {
761            attrs['target'] = '_blank';
762            attrs['rel'] = 'noopener noreferrer'; // Issue #149. See https://mathiasbynens.github.io/rel-noopener/
763        }
764        if (this.truncate.length && this.truncate.length < match.getAnchorText().length) {
765            attrs['title'] = match.getAnchorHref();
766        }
767        return attrs;
768    };
769    /**
770     * Creates the CSS class that will be used for a given anchor tag, based on
771     * the `matchType` and the {@link #className} config.
772     *
773     * Example returns:
774     *
775     * - ""                                      // no {@link #className}
776     * - "myLink myLink-url"                     // url match
777     * - "myLink myLink-email"                   // email match
778     * - "myLink myLink-phone"                   // phone match
779     * - "myLink myLink-hashtag"                 // hashtag match
780     * - "myLink myLink-mention myLink-twitter"  // mention match with Twitter service
781     *
782     * @protected
783     * @param match The Match instance to generate an
784     *   anchor tag from.
785     * @return The CSS class string for the link. Example return:
786     *   "myLink myLink-url". If no {@link #className} was configured, returns
787     *   an empty string.
788     */
789    AnchorTagBuilder.prototype.createCssClass = function (match) {
790        var className = this.className;
791        if (!className) {
792            return '';
793        }
794        else {
795            var returnClasses = [className], cssClassSuffixes = match.getCssClassSuffixes();
796            for (var i = 0, len = cssClassSuffixes.length; i < len; i++) {
797                returnClasses.push(className + '-' + cssClassSuffixes[i]);
798            }
799            return returnClasses.join(' ');
800        }
801    };
802    /**
803     * Processes the `anchorText` by truncating the text according to the
804     * {@link #truncate} config.
805     *
806     * @private
807     * @param anchorText The anchor tag's text (i.e. what will be
808     *   displayed).
809     * @return The processed `anchorText`.
810     */
811    AnchorTagBuilder.prototype.processAnchorText = function (anchorText) {
812        anchorText = this.doTruncate(anchorText);
813        return anchorText;
814    };
815    /**
816     * Performs the truncation of the `anchorText` based on the {@link #truncate}
817     * option. If the `anchorText` is longer than the length specified by the
818     * {@link #truncate} option, the truncation is performed based on the
819     * `location` property. See {@link #truncate} for details.
820     *
821     * @private
822     * @param anchorText The anchor tag's text (i.e. what will be
823     *   displayed).
824     * @return The truncated anchor text.
825     */
826    AnchorTagBuilder.prototype.doTruncate = function (anchorText) {
827        var truncate = this.truncate;
828        if (!truncate.length)
829            return anchorText;
830        var truncateLength = truncate.length, truncateLocation = truncate.location;
831        if (truncateLocation === 'smart') {
832            return truncateSmart(anchorText, truncateLength);
833        }
834        else if (truncateLocation === 'middle') {
835            return truncateMiddle(anchorText, truncateLength);
836        }
837        else {
838            return truncateEnd(anchorText, truncateLength);
839        }
840    };
841    return AnchorTagBuilder;
842}());
843
844/**
845 * @abstract
846 * @class Autolinker.match.AbstractMatch
847 *
848 * Represents a match found in an input string which should be Autolinked. A Match object is what is provided in a
849 * {@link Autolinker#replaceFn replaceFn}, and may be used to query for details about the match.
850 *
851 * For example:
852 *
853 *     var input = "...";  // string with URLs, Email Addresses, and Mentions (Twitter, Instagram, Soundcloud)
854 *
855 *     var linkedText = Autolinker.link( input, {
856 *         replaceFn : function( match ) {
857 *             console.log( "href = ", match.getAnchorHref() );
858 *             console.log( "text = ", match.getAnchorText() );
859 *
860 *             switch( match.getType() ) {
861 *                 case 'url' :
862 *                     console.log( "url: ", match.getUrl() );
863 *
864 *                 case 'email' :
865 *                     console.log( "email: ", match.getEmail() );
866 *
867 *                 case 'mention' :
868 *                     console.log( "mention: ", match.getMention() );
869 *             }
870 *         }
871 *     } );
872 *
873 * See the {@link Autolinker} class for more details on using the {@link Autolinker#replaceFn replaceFn}.
874 */
875var AbstractMatch = /** @class */ (function () {
876    /**
877     * @member Autolinker.match.Match
878     * @method constructor
879     * @param {Object} cfg The configuration properties for the Match
880     *   instance, specified in an Object (map).
881     */
882    function AbstractMatch(cfg) {
883        /**
884         * @cfg {Autolinker.AnchorTagBuilder} tagBuilder (required)
885         *
886         * Reference to the AnchorTagBuilder instance to use to generate an anchor
887         * tag for the Match.
888         */
889        // @ts-expect-error Property used just to get the above doc comment into the ES5 output and documentation generator
890        this._ = null;
891        /**
892         * @cfg {String} matchedText (required)
893         *
894         * The original text that was matched by the {@link Autolinker.matcher.Matcher}.
895         */
896        this.matchedText = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
897        /**
898         * @cfg {Number} offset (required)
899         *
900         * The offset of where the match was made in the input string.
901         */
902        this.offset = 0; // default value just to get the above doc comment in the ES5 output and documentation generator
903        this.tagBuilder = cfg.tagBuilder;
904        this.matchedText = cfg.matchedText;
905        this.offset = cfg.offset;
906    }
907    /**
908     * Returns the original text that was matched.
909     *
910     * @return {String}
911     */
912    AbstractMatch.prototype.getMatchedText = function () {
913        return this.matchedText;
914    };
915    /**
916     * Sets the {@link #offset} of where the match was made in the input string.
917     *
918     * A {@link Autolinker.matcher.Matcher} will be fed only HTML text nodes,
919     * and will therefore set an original offset that is relative to the HTML
920     * text node itself. However, we want this offset to be relative to the full
921     * HTML input string, and thus if using {@link Autolinker#parse} (rather
922     * than calling a {@link Autolinker.matcher.Matcher} directly), then this
923     * offset is corrected after the Matcher itself has done its job.
924     *
925     * @private
926     * @param {Number} offset
927     */
928    AbstractMatch.prototype.setOffset = function (offset) {
929        this.offset = offset;
930    };
931    /**
932     * Returns the offset of where the match was made in the input string. This
933     * is the 0-based index of the match.
934     *
935     * @return {Number}
936     */
937    AbstractMatch.prototype.getOffset = function () {
938        return this.offset;
939    };
940    /**
941     * Returns the CSS class suffix(es) for this match.
942     *
943     * A CSS class suffix is appended to the {@link Autolinker#className} in
944     * the {@link Autolinker.AnchorTagBuilder} when a match is translated into
945     * an anchor tag.
946     *
947     * For example, if {@link Autolinker#className} was configured as 'myLink',
948     * and this method returns `[ 'url' ]`, the final class name of the element
949     * will become: 'myLink myLink-url'.
950     *
951     * The match may provide multiple CSS class suffixes to be appended to the
952     * {@link Autolinker#className} in order to facilitate better styling
953     * options for different match criteria. See {@link Autolinker.match.Mention}
954     * for an example.
955     *
956     * By default, this method returns a single array with the match's
957     * {@link #getType type} name, but may be overridden by subclasses.
958     *
959     * @return {String[]}
960     */
961    AbstractMatch.prototype.getCssClassSuffixes = function () {
962        return [this.type];
963    };
964    /**
965     * Builds and returns an {@link Autolinker.HtmlTag} instance based on the
966     * Match.
967     *
968     * This can be used to easily generate anchor tags from matches, and either
969     * return their HTML string, or modify them before doing so.
970     *
971     * Example Usage:
972     *
973     *     var tag = match.buildTag();
974     *     tag.addClass( 'cordova-link' );
975     *     tag.setAttr( 'target', '_system' );
976     *
977     *     tag.toAnchorString();  // <a href="http://google.com" class="cordova-link" target="_system">Google</a>
978     *
979     * Example Usage in {@link Autolinker#replaceFn}:
980     *
981     *     var html = Autolinker.link( "Test google.com", {
982     *         replaceFn : function( match ) {
983     *             var tag = match.buildTag();  // returns an {@link Autolinker.HtmlTag} instance
984     *             tag.setAttr( 'rel', 'nofollow' );
985     *
986     *             return tag;
987     *         }
988     *     } );
989     *
990     *     // generated html:
991     *     //   Test <a href="http://google.com" target="_blank" rel="nofollow">google.com</a>
992     */
993    AbstractMatch.prototype.buildTag = function () {
994        return this.tagBuilder.build(this);
995    };
996    return AbstractMatch;
997}());
998
999// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
1000// INSTEAD, RUN: npm run generate-char-utils
1001/**
1002 * Determines if the given character `c` matches the regular expression /[\x00-\x1F\x7F]/
1003 * by checking it via character code in a binary search fashion.
1004 *
1005 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1006 * on the character itself.
1007 *
1008 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1009 *
1010 *     npm run generate-char-utils
1011 */
1012function isControlChar(c) {
1013    return ((c >= 0 && c <= 31) || c == 127);
1014}
1015/**
1016 * Determines if the given character `c` matches the regular expression /[A-Za-z]/
1017 * by checking it via character code in a binary search fashion.
1018 *
1019 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1020 * on the character itself.
1021 *
1022 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1023 *
1024 *     npm run generate-char-utils
1025 */
1026function isAsciiLetterChar(c) {
1027    return ((c >= 65 && c <= 90) || (c >= 97 && c <= 122));
1028}
1029/**
1030 * Determines if the given character `c` matches the regular expression /\d/
1031 * by checking it via character code in a binary search fashion.
1032 *
1033 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1034 * on the character itself.
1035 *
1036 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1037 *
1038 *     npm run generate-char-utils
1039 */
1040function isDigitChar(c) {
1041    return (c >= 48 && c <= 57);
1042}
1043/**
1044 * Determines if the given character `c` matches the regular expression /['"]/
1045 * by checking it via character code in a binary search fashion.
1046 *
1047 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1048 * on the character itself.
1049 *
1050 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1051 *
1052 *     npm run generate-char-utils
1053 */
1054function isQuoteChar(c) {
1055    return (c == 34 || c == 39);
1056}
1057/**
1058 * Determines if the given character `c` matches the regular expression /\s/
1059 * by checking it via character code in a binary search fashion.
1060 *
1061 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1062 * on the character itself.
1063 *
1064 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1065 *
1066 *     npm run generate-char-utils
1067 */
1068function isWhitespaceChar(c) {
1069    return (c < 8232 ? (c < 160 ? ((c >= 9 && c <= 13) || c == 32) : (c < 5760 ? c == 160 : (c == 5760 || (c >= 8192 && c <= 8202)))) : (c < 8287 ? ((c >= 8232 && c <= 8233) || c == 8239) : (c < 12288 ? c == 8287 : (c == 12288 || c == 65279)))
1069);
1070}
1071/**
1072 * Determines if the given character `c` matches the regular expression /[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFB
1072D3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\u2700-\u27bf\udde6-\uddff\ud800-\udbff\udc00-\udfff\ufe0e\ufe0f\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0\ud83c\udffb-\udfff\u200d\u3299\u3297\u303d\u3030\u24c2\ud83c\udd70-\udd71\udd7e-\udd7f\udd8e\udd91-\udd9a\udde6-\uddff\ude01-\ude02\ude1a\ude2f\ude32-\ude3a\ude50-\ude51\u203c\u2049\u25aa-\u25ab\u25b6\u25c0\u25fb-\u25fe\u00a9\u00ae\u2122\u2139\udc04\u2600-\u26FF\u2b05\u2b06\u2b07\u2b1b\u2b1c\u2b50\u2b55\u231a\u231b\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa\udccf\u2935\u2934\u2190-\u21ff\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D4-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]/
1073 * by checking it via character code in a binary search fashion.
1074 *
1075 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1076 * on the character itself.
1077 *
1078 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1079 *
1080 *     npm run generate-char-utils
1081 */
vendor: 15,635 bytes, lines 1082-1095
1082function isAlphaNumericOrMarkChar(c) {
1083    return (c < 4800 ? (c < 2949 ? (c < 2451 ? (c < 1425 ? (c < 768 ? (c < 192 ? (c < 169 ? (c < 65 ? (c >= 48 && c <= 57) : ((c >= 65 && c <= 90) || (c >= 97 && c <= 122))) : (c < 181 ? ((c >= 169 && c <= 170) || c == 174) : (c == 181 || c == 186))) : (c < 710 ? (c < 216 ? (c >= 192 && c <= 214) : ((c >= 216 && c <= 246) || (c >= 248 && c <= 705))) : (c < 748 ? ((c >= 710 && c <= 721) || (c >= 736 && c <= 740)) : (c == 748 || c == 750)))) : (c < 910 ? (c < 895 ? (c < 886 ? (c >= 768 && c <= 884) : ((c >= 886 && c <= 887) || (c >= 890 && c <= 893))) : (c < 904 ? (c == 895 || c == 902) : ((c >= 904 && c <= 906) || c == 908))) : (c < 1155 ? (c < 931 ? (c >= 910 && c <= 929) : ((c >= 931 && c <= 1013) || (c >= 1015 && c <= 1153))) : (c < 1369 ? ((c >= 1155 && c <= 1327) || (c >= 1329 && c <= 1366)) : (c == 1369 || (c >= 1377 && c <= 1415)))))) : (c < 1808 ? (c < 1552 ? (c < 1476 ? (c < 1471 ? (c >= 1425 && c <= 1469) : (c == 1471 || (c >= 1473 && c <= 1474))) : (c < 1488 ? ((c >= 1476 && c <= 1477) || c == 1479) : ((c >= 1488 && c <= 1514) || (c >= 1520 && c <= 1522)))) : (c < 1749 ? (c < 1568 ? (c >= 1552 && c <= 1562) : ((c >= 1568 && c <= 1641) || (c >= 1646 && c <= 1747))) : (c < 1770 ? ((c >= 1749 && c <= 1756) || (c >= 1759 && c <= 1768)) : ((c >= 1770 && c <= 1788) || c == 1791)))) : (c < 2230 ? (c < 2042 ? (c < 1869 ? (c >= 1808 && c <= 1866) : ((c >= 1869 && c <= 1969) || (c >= 1984 && c <= 2037))) : (c < 2112 ? (c == 2042 || (c >= 2048 && c <= 2093)) : ((c >= 2112 && c <= 2139) || (c >= 2208 && c <= 2228)))) : (c < 2406 ? (c < 2260 ? (c >= 2230 && c <= 2237) : ((c >= 2260 && c <= 2273) || (c >= 2275 && c <= 2403))) : (c < 2437 ? ((c >= 2406 && c <= 2415) || (c >= 2417 && c <= 2435)) : ((c >= 2437 && c <= 2444) || (c >= 2447 && c <= 2448))))))) : (c < 2693 ? (c < 2579 ? (c < 2519 ? (c < 2486 ? (c < 2474 ? (c >= 2451 && c <= 2472) : ((c >= 2474 && c <= 2480) || c == 2482)) : (c < 2503 ? ((c >= 2486 && c <= 2489) || (c >= 2492 && c <= 2500)) : ((c >= 2503 && c <= 2504) || (c >= 2507 && c <= 2510)))) : (c < 2534 ? (c < 2524 ? c == 2519 : ((c >= 2524 && c <= 2525) || (c >= 2527 && c <= 2531))) : (c < 2565 ? ((c >= 2534 && c <= 2545) || (c >= 2561 && c <= 2563)) : ((c >= 2565 && c <= 2570) || (c >= 2575 && c <= 2576))))) : (c < 2631 ? (c < 2613 ? (c < 2602 ? (c >= 2579 && c <= 2600) : ((c >= 2602 && c <= 2608) || (c >= 2610 && c <= 2611))) : (c < 2620 ? ((c >= 2613 && c <= 2614) || (c >= 2616 && c <= 2617)) : (c == 2620 || (c >= 2622 && c <= 2626)))) : (c < 2649 ? (c < 2635 ? (c >= 2631 && c <= 2632) : ((c >= 2635 && c <= 2637) || c == 2641)) : (c < 2662 ? ((c >= 2649 && c <= 2652) || c == 2654) : ((c >= 2662 && c <= 2677) || (c >= 2689 && c <= 2691)))))) : (c < 2821 ? (c < 2759 ? (c < 2730 ? (c < 2703 ? (c >= 2693 && c <= 2701) : ((c >= 2703 && c <= 2705) || (c >= 2707 && c <= 2728))) : (c < 2741 ? ((c >= 2730 && c <= 2736) || (c >= 2738 && c <= 2739)) : ((c >= 2741 && c <= 2745) || (c >= 2748 && c <= 2757)))) : (c < 2784 ? (c < 2763 ? (c >= 2759 && c <= 2761) : ((c >= 2763 && c <= 2765) || c == 2768)) : (c < 2809 ? ((c >= 2784 && c <= 2787) || (c >= 2790 && c <= 2799)) : (c == 2809 || (c >= 2817 && c <= 2819))))) : (c < 2887 ? (c < 2858 ? (c < 2831 ? (c >= 2821 && c <= 2828) : ((c >= 2831 && c <= 2832) || (c >= 2835 && c <= 2856))) : (c < 2869 ? ((c >= 2858 && c <= 2864) || (c >= 2866 && c <= 2867)) : ((c >= 2869 && c <= 2873) || (c >= 2876 && c <= 2884)))) : (c < 2911 ? (c < 2902 ? ((c >= 2887 && c <= 2888) || (c >= 2891 && c <= 2893)) : ((c >= 2902 && c <= 2903) || (c >= 2908 && c <= 2909))) : (c < 2929 ? ((c >= 2911 && c <= 2915) || (c >= 2918 && c <= 2927)) : (c == 2929 || (c >= 2946 && c <= 2947)))))))) : (c < 3517 ? (c < 3205 ? (c < 3046 ? (c < 2984 ? (c < 2969 ? (c < 2958 ? (c >= 2949 && c <= 2954) : ((c >= 2958 && c <= 2960) || (c >= 2962 && c <= 2965))) : (c < 2974 ? ((c >= 2969 && c <= 2970) || c == 2972) : ((c >= 2974 && c <= 2975) || (c >= 2979 && c <= 2980)))) : (c < 3014 ? (c < 2990 ? (c >= 2984 && c <= 2986) : ((c >= 2990 && c <= 3001) || (c >= 3006 && c <= 3010))) : (c < 3024 ? ((c >= 3014 && c <= 3016) || (c >= 3018 && c <= 3021)) : (c == 3024 || c == 3031)))) : (c < 3142 ? (c < 3086 ? (c < 3072 ? (c >= 3046 && c <= 3055) : ((c >= 3072 && c <= 3075) || (c >= 3077 && c <= 3084))) : (c < 3114 ? ((c >= 3086 && c <= 3088) || (c >= 3090 && c <= 3112)) : ((c >= 3114 && c <= 3129) || (c >= 3133 && c <= 3140)))) : (c < 3160 ? (c < 3146 ? (c >= 3142 && c <= 3144) : ((c >= 3146 && c <= 3149) || (c >= 3157 && c <= 3158))) : (c < 3174 ? ((c >= 3160 && c <= 3162) || (c >= 3168 && c <= 3171)) : ((c >= 3174 && c <= 3183) || (c >= 3200 && c <= 3203)))))) : (c < 3333 ? (c < 3274 ? (c < 3242 ? (c < 3214 ? (c >= 3205 && c <= 3212) : ((c >= 3214 && c <= 3216) || (c >= 3218 && c <= 3240))) : (c < 3260 ? ((c >= 3242 && c <= 3251) || (c >= 3253 && c <= 3257)) : ((c >= 3260 && c <= 3268) || (c >= 3270 && c <= 3272)))) : (c < 3296 ? (c < 3285 ? (c >= 3274 && c <= 3277) : ((c >= 3285 && c <= 3286) || c == 3294)) : (c < 3313 ? ((c >= 3296 && c <= 3299) || (c >= 3302 && c <= 3311)) : ((c >= 3313 && c <= 3314) || (c >= 3329 && c <= 3331))))) : (c < 3423 ? (c < 3389 ? (c < 3342 ? (c >= 3333 && c <= 3340) : ((c >= 3342 && c <= 3344) || (c >= 3346 && c <= 3386))) : (c < 3402 ? ((c >= 3389 && c <= 3396) || (c >= 3398 && c <= 3400)) : ((c >= 3402 && c <= 3406) || (c >= 3412 && c <= 3415)))) : (c < 3458 ? (c < 3430 ? (c >= 3423 && c <= 3427) : ((c >= 3430 && c <= 3439) || (c >= 3450 && c <= 3455))) : (c < 3482 ? ((c >= 3458 && c <= 3459) || (c >= 3461 && c <= 3478)) : ((c >= 3482 && c <= 3505) || (c >= 3507 && c <= 3515))))))) : (c < 3804 ? (c < 3722 ? (c < 3570 ? (c < 3535 ? (c < 3520 ? c == 3517 : ((c >= 3520 && c <= 3526) || c == 3530)) : (c < 3544 ? ((c >= 3535 && c <= 3540) || c == 3542) : ((c >= 3544 && c <= 3551) || (c >= 3558 && c <= 3567)))) : (c < 3664 ? (c < 3585 ? (c >= 3570 && c <= 3571) : ((c >= 3585 && c <= 3642) || (c >= 3648 && c <= 3662))) : (c < 3716 ? ((c >= 3664 && c <= 3673) || (c >= 3713 && c <= 3714)) : (c == 3716 || (c >= 3719 && c <= 3720))))) : (c < 3754 ? (c < 3737 ? (c < 3725 ? c == 3722 : (c == 3725 || (c >= 3732 && c <= 3735))) : (c < 3749 ? ((c >= 3737 && c <= 3743) || (c >= 3745 && c <= 3747)) : (c == 3749 || c == 3751))) : (c < 3776 ? (c < 3757 ? (c >= 3754 && c <= 3755) : ((c >= 3757 && c <= 3769) || (c >= 3771 && c <= 3773))) : (c < 3784 ? ((c >= 3776 && c <= 3780) || c == 3782) : ((c >= 3784 && c <= 3789) || (c >= 3792 && c <= 3801)))))) : (c < 4176 ? (c < 3902 ? (c < 3872 ? (c < 3840 ? (c >= 3804 && c <= 3807) : (c == 3840 || (c >= 3864 && c <= 3865))) : (c < 3895 ? ((c >= 3872 && c <= 3881) || c == 3893) : (c == 3895 || c == 3897))) : (c < 3974 ? (c < 3913 ? (c >= 3902 && c <= 3911) : ((c >= 3913 && c <= 3948) || (c >= 3953 && c <= 3972))) : (c < 4038 ? ((c >= 3974 && c <= 3991) || (c >= 3993 && c <= 4028)) : (c == 4038 || (c >= 4096 && c <= 4169))))) : (c < 4688 ? (c < 4301 ? (c < 4256 ? (c >= 4176 && c <= 4253) : ((c >= 4256 && c <= 4293) || c == 4295)) : (c < 4348 ? (c == 4301 || (c >= 4304 && c <= 4346)) : ((c >= 4348 && c <= 4680) || (c >= 4682 && c <= 4685)))) : (c < 4746 ? (c < 4698 ? ((c >= 4688 && c <= 4694) || c == 4696) : ((c >= 4698 && c <= 4701) || (c >= 4704 && c <= 4744))) : (c < 4786 ? ((c >= 4746 && c <= 4749) || (c >= 4752 && c <= 4784)) : ((c >= 4786 && c <= 4789) || (c >= 4792 && c <= 4798))))))))) : (c < 11035 ? (c < 7416 ? (c < 6176 ? (c < 5873 ? (c < 4992 ? (c < 4824 ? (c < 4802 ? c == 4800 : ((c >= 4802 && c <= 4805) || (c >= 4808 && c <= 4822))) : (c < 4888 ? ((c >= 4824 && c <= 4880) || (c >= 4882 && c <= 4885)) : ((c >= 4888 && c <= 4954) || (c >= 4957 && c <= 4959)))) : (c < 5121 ? (c < 5024 ? (c >= 4992 && c <= 5007) : ((c >= 5024 && c <= 5109) || (c >= 5112 && c <= 5117))) : (c < 5761 ? ((c >= 5121 && c <= 5740) || (c >= 5743 && c <= 5759)) : ((c >= 5761 && c <= 5786) || (c >= 5792 && c <= 5866))))) : (c < 6002 ? (c < 5920 ? (c < 5888 ? (c >= 5873 && c <= 5880) : ((c >= 5888 && c <= 5900) || (c >= 5902 && c <= 5908))) : (c < 5984 ? ((c >= 5920 && c <= 5940) || (c >= 5952 && c <= 5971)) : ((c >= 5984 && c <= 5996) || (c >= 5998 && c <= 6000)))) : (c < 6108 ? (c < 6016 ? (c >= 6002 && c <= 6003) : ((c >= 6016 && c <= 6099) || c == 6103)) : (c < 6155 ? ((c >= 6108 && c <= 6109) || (c >= 6112 && c <= 6121)) : ((c >= 6155 && c <= 6157) || (c >= 6160 && c <= 6169)))))) : (c < 6783 ? (c < 6512 ? (c < 6400 ? (c < 6272 ? (c >= 6176 && c <= 6263) : ((c >= 6272 && c <= 6314) || (c >= 6320 && c <= 6389))) : (c < 6448 ? ((c >= 6400 && c <= 6430) || (c >= 6432 && c <= 6443)) : ((c >= 6448 && c <= 6459) || (c >= 6470 && c <= 6509)))) : (c < 6608 ? (c < 6528 ? (c >= 6512 && c <= 6516) : ((c >= 6528 && c <= 6571) || (c >= 6576 && c <= 6601))) : (c < 6688 ? ((c >= 6608 && c <= 6617) || (c >= 6656 && c <= 6683)) : ((c >= 6688 && c <= 6750) || (c >= 6752 && c <= 6780))))) : (c < 7040 ? (c < 6832 ? (c < 6800 ? (c >= 6783 && c <= 6793) : ((c >= 6800 && c <= 6809) || c == 6823)) : (c < 6992 ? ((c >= 6832 && c <= 6846) || (c >= 6912 && c <= 6987)) : ((c >= 6992 && c <= 7001) || (c >= 7019 && c <= 7027)))) : (c < 7245 ? (c < 7168 ? (c >= 7040 && c <= 7155) : ((c >= 7168 && c <= 7223) || (c >= 7232 && c <= 7241))) : (c < 7376 ? ((c >= 7245 && c <= 7293) || (c >= 7296 && c <= 7304)) : ((c >= 7376 && c <= 7378) || (c >= 7380 && c <= 7414))))))) : (c < 8450 ? (c < 8130 ? (c < 8025 ? (c < 7960 ? (c < 7424 ? (c >= 7416 && c <= 7417) : ((c >= 7424 && c <= 7669) || (c >= 7675 && c <= 7957))) : (c < 8008 ? ((c >= 7960 && c <= 7965) || (c >= 7968 && c <= 8005)) : ((c >= 8008 && c <= 8013) || (c >= 8016 && c <= 8023)))) : (c < 8031 ? (c < 8027 ? c == 8025 : (c == 8027 || c == 8029)) : (c < 8118 ? ((c >= 8031 && c <= 8061) || (c >= 8064 && c <= 8116)) : ((c >= 8118 && c <= 8124) || c == 8126)))) : (c < 8205 ? (c < 8150 ? (c < 8134 ? (c >= 8130 && c <= 8132) : ((c >= 8134 && c <= 8140) || (c >= 8144 && c <= 8147))) : (c < 8178 ? ((c >= 8150 && c <= 8155) || (c >= 8160 && c <= 8172)) : ((c >= 8178 && c <= 8180) || (c >= 8182 && c <= 8188)))) : (c < 8305 ? (c < 8252 ? c == 8205 : (c == 8252 || c == 8265)) : (c < 8336 ? (c == 8305 || c == 8319) : ((c >= 8336 && c <= 8348) || (c >= 8400 && c <= 8432)))))) : (c < 8579 ? (c < 8486 ? (c < 8469 ? (c < 8455 ? c == 8450 : (c == 8455 || (c >= 8458 && c <= 8467))) : (c < 8482 ? (c == 8469 || (c >= 8473 && c <= 8477)) : (c == 8482 || c == 8484))) : (c < 8495 ? (c < 8488 ? c == 8486 : (c == 8488 || (c >= 8490 && c <= 8493))) : (c < 8517 ? ((c >= 8495 && c <= 8505) || (c >= 8508 && c <= 8511)) : ((c >= 8517 && c <= 8521) || c == 8526)))) : (c < 9410 ? (c < 9000 ? (c < 8592 ? (c >= 8579 && c <= 8580) : ((c >= 8592 && c <= 8703) || (c >= 8986 && c <= 8987))) : (c < 9193 ? (c == 9000 || c == 9167) : ((c >= 9193 && c <= 9203) || (c >= 9208 && c <= 9210)))) : (c < 9723 ? (c < 9654 ? (c == 9410 || (c >= 9642 && c <= 9643)) : (c == 9654 || c == 9664)) : (c < 10548 ? ((c >= 9723 && c <= 9726) || (c >= 9728 && c <= 10175)) : ((c >= 10548 && c <= 10549) || (c >= 11013 && c <= 11015)))))))) : (c < 43259 ? (c < 12445 ? (c < 11688 ? (c < 11520 ? (c < 11264 ? (c < 11088 ? (c >= 11035 && c <= 11036) : (c == 11088 || c == 11093)) : (c < 11360 ? ((c >= 11264 && c <= 11310) || (c >= 11312 && c <= 11358)) : ((c >= 11360 && c <= 11492) || (c >= 11499 && c <= 11507)))) : (c < 11568 ? (c < 11559 ? (c >= 11520 && c <= 11557) : (c == 11559 || c == 11565)) : (c < 11647 ? ((c >= 11568 && c <= 11623) || c == 11631) : ((c >= 11647 && c <= 11670) || (c >= 11680 && c <= 11686))))) : (c < 11744 ? (c < 11712 ? (c < 11696 ? (c >= 11688 && c <= 11694) : ((c >= 11696 && c <= 11702) || (c >= 11704 && c <= 11710))) : (c < 11728 ? ((c >= 11712 && c <= 11718) || (c >= 11720 && c <= 11726)) : ((c >= 11728 && c <= 11734) || (c >= 11736 && c <= 11742)))) : (c < 12330 ? (c < 11823 ? (c >= 11744 && c <= 11775) : (c == 11823 || (c >= 12293 && c <= 12294))) : (c < 12353 ? ((c >= 12330 && c <= 12341) || (c >= 12347 && c <= 12349)) : ((c >= 12353 && c <= 12438) || (c >= 12441 && c <= 12442)))))) : (c < 42512 ? (c < 12951 ? (c < 12549 ? (c < 12449 ? (c >= 12445 && c <= 12447) : ((c >= 12449 && c <= 12538) || (c >= 12540 && c <= 12543))) : (c < 12704 ? ((c >= 12549 && c <= 12589) || (c >= 12593 && c <= 12686)) : ((c >= 12704 && c <= 12730) || (c >= 12784 && c <= 12799)))) : (c < 19968 ? (c < 12953 ? c == 12951 : (c == 12953 || (c >= 13312 && c <= 19893))) : (c < 42192 ? ((c >= 19968 && c <= 40917) || (c >= 40960 && c <= 42124)) : ((c >= 42192 && c <= 42237) || (c >= 42240 && c <= 42508))))) : (c < 42891 ? (c < 42623 ? (c < 42560 ? (c >= 42512 && c <= 42539) : ((c >= 42560 && c <= 42610) || (c >= 42612 && c <= 42621))) : (c < 42775 ? ((c >= 42623 && c <= 42725) || (c >= 42736 && c <= 42737)) : ((c >= 42775 && c <= 42783) || (c >= 42786 && c <= 42888)))) : (c < 43072 ? (c < 42928 ? (c >= 42891 && c <= 42926) : ((c >= 42928 && c <= 42935) || (c >= 42999 && c <= 43047))) : (c < 43216 ? ((c >= 43072 && c <= 43123) || (c >= 43136 && c <= 43205)) : ((c >= 43216 && c <= 43225) || (c >= 43232 && c <= 43255))))))) : (c < 55243 ? (c < 43744 ? (c < 43488 ? (c < 43312 ? (c < 43261 ? c == 43259 : (c == 43261 || (c >= 43264 && c <= 43309))) : (c < 43392 ? ((c >= 43312 && c <= 43347) || (c >= 43360 && c <= 43388)) : ((c >= 43392 && c <= 43456) || (c >= 43471 && c <= 43481)))) : (c < 43600 ? (c < 43520 ? (c >= 43488 && c <= 43518) : ((c >= 43520 && c <= 43574) || (c >= 43584 && c <= 43597))) : (c < 43642 ? ((c >= 43600 && c <= 43609) || (c >= 43616 && c <= 43638)) : ((c >= 43642 && c <= 43714) || (c >= 43739 && c <= 43741))))) : (c < 43824 ? (c < 43785 ? (c < 43762 ? (c >= 43744 && c <= 43759) : ((c >= 43762 && c <= 43766) || (c >= 43777 && c <= 43782))) : (c < 43808 ? ((c >= 43785 && c <= 43790) || (c >= 43793 && c <= 43798)) : ((c >= 43808 && c <= 43814) || (c >= 43816 && c <= 43822)))) : (c < 44012 ? (c < 43868 ? (c >= 43824 && c <= 43866) : ((c >= 43868 && c <= 43877) || (c >= 43888 && c <= 44010))) : (c < 44032 ? ((c >= 44012 && c <= 44013) || (c >= 44016 && c <= 44025)) : ((c >= 44032 && c <= 55203) || (c >= 55216 && c <= 55238)))))) : (c < 64848 ? (c < 64298 ? (c < 64112 ? (c < 55296 ? (c >= 55243 && c <= 55291) : ((c >= 55296 && c <= 57343) || (c >= 63744 && c <= 64109))) : (c < 64275 ? ((c >= 64112 && c <= 64217) || (c >= 64256 && c <= 64262)) : ((c >= 64275 && c <= 64279) || (c >= 64285 && c <= 64296)))) : (c < 64320 ? (c < 64312 ? (c >= 64298 && c <= 64310) : ((c >= 64312 && c <= 64316) || c == 64318)) : (c < 64326 ? ((c >= 64320 && c <= 64321) || (c >= 64323 && c <= 64324)) : ((c >= 64326 && c <= 64433) || (c >= 64467 && c <= 64829))))) : (c < 65296 ? (c < 65024 ? (c < 64914 ? (c >= 64848 && c <= 64911) : ((c >= 64914 && c <= 64967) || (c >= 65008 && c <= 65019))) : (c < 65136 ? ((c >= 65024 && c <= 65039) || (c >= 65056 && c <= 65071)) : ((c >= 65136 && c <= 65140) || (c >= 65142 && c <= 65276)))) : (c < 65474 ? (c < 65345 ? ((c >= 65296 && c <= 65305) || (c >= 65313 && c <= 65338)) : ((c >= 65345 && c <= 65370) || (c >= 65382 && c <= 65470))) : (c < 65490 ? ((c >= 65474 && c <= 65479) || (c >= 65482 && c <= 65487)) : ((c >= 65490 && c <= 65495) || (c >= 65498 && c <= 65500))))))))));
1084}
1085/**
1086 * Determines if the given character `c` matches the regular expression /[!#$%&'*+/=?^_`{|}~-]/
1087 * by checking it via character code in a binary search fashion.
1088 *
1089 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1090 * on the character itself.
1091 *
1092 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1093 *
1094 *     npm run generate-char-utils
1095 */
vendor: 2,618 bytes, lines 1096-1158
1096function isValidEmailLocalPartSpecialChar(c) {
1097    return (c < 47 ? (c < 42 ? (c == 33 || (c >= 35 && c <= 39)) : ((c >= 42 && c <= 43) || c == 45)) : (c < 63 ? (c == 47 || c == 61) : (c < 94 ? c == 63 : ((c >= 94 && c <= 96) || (c >= 123 && c <= 126)))));
1098}
1099/**
1100 * Determines if the given character `c` matches the regular expression /[-+&@#/%=~_()|'$*[\]{}\u2713]/
1101 * by checking it via character code in a binary search fashion.
1102 *
1103 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1104 * on the character itself.
1105 *
1106 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1107 *
1108 *     npm run generate-char-utils
1109 */
1110function isUrlSuffixAllowedSpecialChar(c) {
1111    return (c < 91 ? (c < 47 ? ((c >= 35 && c <= 43) || c == 45) : (c < 61 ? c == 47 : (c == 61 || c == 64))) : (c < 95 ? (c == 91 || c == 93) : (c < 123 ? c == 95 : ((c >= 123 && c <= 126) || c == 10003))));
1112}
1113/**
1114 * Determines if the given character `c` matches the regular expression /[?!:,.;^]/
1115 * by checking it via character code in a binary search fashion.
1116 *
1117 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1118 * on the character itself.
1119 *
1120 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1121 *
1122 *     npm run generate-char-utils
1123 */
1124function isUrlSuffixNotAllowedAsFinalChar(c) {
1125    return (c < 58 ? (c < 44 ? c == 33 : (c == 44 || c == 46)) : (c < 63 ? (c >= 58 && c <= 59) : (c == 63 || c == 94)));
1126}
1127/**
1128 * Determines if the given character `c` matches the regular expression /[({[]/
1129 * by checking it via character code in a binary search fashion.
1130 *
1131 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1132 * on the character itself.
1133 *
1134 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1135 *
1136 *     npm run generate-char-utils
1137 */
1138function isOpenBraceChar(c) {
1139    return (c < 91 ? c == 40 : (c == 91 || c == 123));
1140}
1141/**
1142 * Determines if the given character `c` matches the regular expression /[)}\]]/
1143 * by checking it via character code in a binary search fashion.
1144 *
1145 * This technique speeds this function up by a factor of ~10x vs. running RegExp.prototype.test()
1146 * on the character itself.
1147 *
1148 * NOTE: This function is generated. Do not edit manually. To regenerate, run:
1149 *
1150 *     npm run generate-char-utils
1151 */
1152function isCloseBraceChar(c) {
1153    return (c < 93 ? c == 41 : (c == 93 || c == 125));
1154}
1155
1156// NOTE: THIS IS A GENERATED FILE
1157// To update with the latest TLD list, run `npm run update-known-tlds`
1158var tldRegex = 
vendor: 1,969 bytes, line 1158
1158/^(?:xn--vermgensberatung-pwb|xn--vermgensberater-ctb|xn--clchc0ea0b2g2a9gcd|xn--w4r85el8fhu5dnra|travelersinsurance|vermögensberatung|xn--5su34j936bgsg|xn--bck1b9a5dre4c|xn--mgbah1a3hjkrd|xn--mgbai9azgqp6j|xn--mgberp4a5d4ar|xn--xkc2dl3a5ee0h|vermögensberater|xn--fzys8d69uvgm|xn--mgba7c0bbn0a|xn--mgbcpq6gpa1a|xn--xkc2al3hye2a|americanexpress|kerryproperties|sandvikcoromant|xn--i1b6b1a6a2e|xn--kcrx77d1x4a|xn--lgbbat1ad8j|xn--mgba3a4f16a|xn--mgbc0a9azcg|xn--nqv7fs00ema|americanfamily|weatherchannel|xn--54b7fta0cc|xn--6qq986b3xl|xn--80aqecdr1a|xn--b4w605ferd|xn--fiq228c5hs|xn--h2breg3eve|xn--jlq480n2rg|xn--mgba3a3ejt|xn--mgbaam7a8h|xn--mgbayh7gpa|xn--mgbbh1a71e|xn--mgbca7dzdo|xn--mgbi4ecexp|xn--mgbx4cd0ab|xn--rvc1e0am3e|international|lifeinsurance|wolterskluwer|xn--cckwcxetd|xn--eckvdtc9d|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--h2brj9c8c|xn--tiq49xqyj|xn--yfro4i67o|xn--ygbi2ammx|construction|lplfinancial|scholarships|versicherung|xn--3e0b707e|xn--45br5cyl|xn--4dbrk0ce|xn--80adxhks|xn--80asehdb|xn--8y0a063a|xn--gckr3f0f|xn--mgb9awbf|xn--mgbab2bd|xn--mgbgu82a|xn--mgbpl2fh|xn--mgbt3dhd|xn--mk1bu44c|xn--ngbc5azd|xn--ngbe9e0a|xn--ogbpf8fl|xn--qcka1pmc|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|williamhill|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--3bst00m|xn--3ds443g|xn--3hcrj9c|xn--42c2d9a|xn--45brj9c|xn--55qw42g|xn--6frz82g|xn--80ao21a|xn--9krt00a|xn--cck2b3b|xn--czr694b|xn--d1acj3b|xn--efvy88h|xn--fct429k|xn--fjq720a|xn--flw351e|xn--g2xx48c|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|xn--imr513n|xn--j6w193g|xn--jvr189m|xn--kprw13d|xn--kpry57d|xn--mgbbh1a|xn--mgbtx2b|xn--mix891f|xn--nyqy26a|xn--otu796d|xn--pgbs0dh|xn--q9jyb4c|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--vuq861b|xn--w4rs40l|xn--xhq521b|xn--zfr164b|சிங
vendor: 9,053 bytes, line 1158
1158்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nextdirect|properties|protection|prudential|realestate|republican|restaurant|schaeffler|tatamotors|technology|university|vlaanderen|xn--30rr7y|xn--3pxu8k|xn--45q11c|xn--4gbrim|xn--55qx5d|xn--5tzm5g|xn--80aswg|xn--90a3ac|xn--9dbq2a|xn--9et52u|xn--c2br7g|xn--cg4bki|xn--czrs0t|xn--czru2d|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--io0a7i|xn--kput3i|xn--mxtq1m|xn--o3cw4h|xn--pssy2u|xn--q7ce6a|xn--unup4y|xn--wgbh1c|xn--wgbl6a|xn--y9a3aq|accenture|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|institute|insurance|kuokgroup|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|pramerica|richardli|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|xn--90ais|xn--c1avg|xn--d1alf|xn--e1a4c|xn--fhbei|xn--j1aef|xn--j1amh|xn--l1acc|xn--ngbrx|xn--nqv7f|xn--p1acf|xn--qxa6a|xn--tckwe|xn--vhquv|yodobashi|موريتانيا|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|builders|business|capetown|catering|catholic|cipriani|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|mckinsey|memorial|merckmsd|mortgage|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|softbank|software|stcgroup|supplies|training|vanguard|ventures|verisign|woodside|xn--90ae|xn--node|xn--p1ai|xn--qxam|yokohama|السعودية|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|banamex|bauhaus|bestbuy|booking|brother|capital|caravan|careers|channel|charity|chintai|citadel|clubmed|college|cologne|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hotmail|hyundai|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lanxess|lasalle|latrobe|leclerc|limited|lincoln|markets|monster|netbank|netflix|network|neustar|okinawa|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|singles|staples|storage|support|surgery|systems|temasek|theater|theatre|tickets|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|yamaxun|youtube|zuerich|католик|البحرين|الجزائر|العليان|پاکستان|كاثوليك|இந்தியா|abbott|abbvie|africa|agency|airbus|airtel|alipay|alsace|alstom|amazon|anquan|aramco|author|bayern|beauty|berlin|bharti|bostik|boston|broker|camera|career|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kindle|kosher|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|monash|mormon|moscow|museum|nagoya|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|pictet|quebec|racing|realty|reisen|repair|report|review|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|walter|webcam|xihuan|yachts|yandex|zappos|москва|онлайн|ابوظبي|ارامكو|الاردن|المغرب|امارات|فلسطين|مليسيا|भारतम्|இலங்கை|ファッション|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dance|deals|delta|drive|dubai|earth|edeka|email|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|irish|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|loans|locus|lotte|lotto|mango|media|miami|money|movie|music|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|yahoo|ישראל|ایران|بازار|بھارت|سودان|سورية|همراه|भारोत|संगठन|বাংলা|భారత్|ഭാരതം|嘉里大酒店|aarp|able|aero|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|dvag|erni|fage|fail|fans|farm|fast|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kids|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|read|reit|rent|rest|rich|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scot|seat|seek|sexy|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|yoga|zara|zero|zone|дети|сайт|بارت|بيتك|ڀارت|تونس|شبكة|عراق|عمان|موقع|भारत|ভারত|ভাৰত|ਭਾਰਤ|ભારત|ଭାରତ|ಭಾರತ|ලංකා|アマゾン|グーグル|クラウド|ポイント|组织机构|電訊盈科|香格里拉|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|ceo|cfa|cfd|com|cpa|crs|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gay|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|llp|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|scb|sew|sex|sfr|ski|sky|soy|spa|srl|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|xxx|xyz|you|yun|zip|бел|ком|қаз|мкд|мон|орг|рус|срб|укр|հայ|קום|عرب|قطر|كوم|مصر|कॉम|नेट|คอม|ไทย|ລາວ|ストア|セール|みんな|中文网|亚马逊|天主教|我爱你|新加坡|淡马锡|飞利浦|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|ευ|бг|ею|рф|გე|닷넷|닷컴|삼성|한국|コム|世界|中信|中国|中國|企业|佛山|信息|健康|八卦|公司|公益|台湾|台灣|商城|商店|商标|嘉里|在线|大拿|娱乐|家電|广东|微博|慈善|手机|招聘|政务|政府|新闻|时尚|書籍|机构|游戏|澳門|点看|移动|网址|网店|网站|网络|联通|谷歌|购物|通販|集团|食品|餐厅|香港)$/
vendor: 8,947 bytes, lines 1158-1393
1158;
1159
1160/**
1161 * Regular expression to match an http:// or https:// scheme.
1162 */
1163var httpSchemeRe = /https?:\/\//i;
1164/**
1165 * Regular expression to match an http:// or https:// scheme as the prefix of
1166 * a string.
1167 */
1168var httpSchemePrefixRe = new RegExp('^' + httpSchemeRe.source, 'i');
1169/**
1170 * A regular expression used to determine the schemes we should not autolink
1171 */
1172var invalidSchemeRe = /^(javascript|vbscript):/i;
1173// A regular expression used to determine if the URL is a scheme match (such as
1174// 'http://google.com', and as opposed to a "TLD match"). This regular
1175// expression is used to parse out the host along with if the URL has an
1176// authority component (i.e. '//')
1177//
1178// Capturing groups:
1179//    1. '//' if the URL has an authority component, empty string otherwise
1180//    2. The host (if one exists). Ex: 'google.com'
1181//
1182// See https://www.rfc-editor.org/rfc/rfc3986#appendix-A for terminology
1183var schemeUrlRe = /^[A-Za-z][-.+A-Za-z0-9]*:(\/\/)?([^:/]*)/;
1184// A regular expression used to determine if the URL is a TLD match (such as
1185// 'google.com', and as opposed to a "scheme match"). This regular
1186// expression is used to help parse out the TLD (top-level domain) of the host.
1187//
1188// See https://www.rfc-editor.org/rfc/rfc3986#appendix-A for terminology
1189var tldUrlHostRe = /^(?:\/\/)?([^/#?:]+)/; // optionally prefixed with protocol-relative '//' chars
1190/**
1191 * Determines if the given character code represents a character that may start
1192 * a scheme (ex: the 'h' in 'http')
1193 */
1194var isSchemeStartChar = isAsciiLetterChar; // Equivalent to checking the RegExp `/[A-Za-z]/`, but aliased for clarity and maintainability
1195/**
1196 * Determines if the given character is a valid character in a scheme (such as
1197 * 'http' or 'ssh+git'), but only after the start char (which is handled by
1198 * {@link isSchemeStartChar}.
1199 */
1200function isSchemeChar(charCode) {
1201    return (isAsciiLetterChar(charCode) ||
1202        isDigitChar(charCode) ||
1203        charCode === 43 /* Char.Plus */ || // '+'
1204        charCode === 45 /* Char.Dash */ || // '-'
1205        charCode === 46 /* Char.Dot */ // '.'
1206    );
1207}
1208/**
1209 * Determines if the character can begin a domain label, which must be an
1210 * alphanumeric character and not an underscore or dash.
1211 *
1212 * A domain label is a segment of a hostname such as subdomain.google.com.
1213 */
1214var isDomainLabelStartChar = isAlphaNumericOrMarkChar; // alias function for clarity
1215/**
1216 * Determines if the character is part of a domain label (but not a domain label
1217 * start character).
1218 *
1219 * A domain label is a segment of a hostname such as subdomain.google.com.
1220 */
1221function isDomainLabelChar(charCode) {
1222    return charCode === 95 /* Char.Underscore */ || isDomainLabelStartChar(charCode);
1223}
1224/**
1225 * Determines if the character is a path character ("pchar") as defined by
1226 * https://tools.ietf.org/html/rfc3986#appendix-A
1227 *
1228 *     pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
1229 *
1230 *     unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
1231 *     pct-encoded   = "%" HEXDIG HEXDIG
1232 *     sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
1233 *                   / "*" / "+" / "," / ";" / "="
1234 *
1235 * Note that this implementation doesn't follow the spec exactly, but rather
1236 * follows URL path characters found out in the wild (spec might be out of date?)
1237 */
1238function isPathChar(charCode) {
1239    return (isAlphaNumericOrMarkChar(charCode) ||
1240        isUrlSuffixAllowedSpecialChar(charCode) ||
1241        isUrlSuffixNotAllowedAsFinalChar(charCode) // characters in addition to those allowed by isUrlSuffixAllowedSpecialChar()
1242    );
1243}
1244/**
1245 * Determines if the character given may begin the "URL Suffix" section of a
1246 * URI (i.e. the path, query, or hash section). These are the '/', '?' and '#'
1247 * characters.
1248 *
1249 * See https://tools.ietf.org/html/rfc3986#appendix-A
1250 */
1251function isUrlSuffixStartChar(charCode) {
1252    return (charCode === 47 /* Char.Slash */ || // '/'
1253        charCode === 63 /* Char.Question */ || // '?'
1254        charCode === 35 /* Char.NumberSign */ // '#'
1255    );
1256}
1257/**
1258 * Determines if the top-level domain (TLD) read in the host is a known TLD.
1259 *
1260 * Example: 'com' would be a known TLD (for a host of 'google.com'), but
1261 * 'local' would not (for a domain name of 'my-computer.local').
1262 */
1263function isKnownTld(tld) {
1264    return tldRegex.test(tld.toLowerCase()); // make sure the tld is lowercase for the regex
1265}
1266/**
1267 * Determines if the given `url` is a valid scheme-prefixed URL.
1268 */
1269function isValidSchemeUrl(url) {
1270    // If the scheme is 'javascript:' or 'vbscript:', these link
1271    // types can be dangerous. Don't link them.
1272    if (invalidSchemeRe.test(url)) {
1273        return false;
1274    }
1275    var schemeMatch = url.match(schemeUrlRe);
1276    if (!schemeMatch) {
1277        return false;
1278    }
1279    var isAuthorityMatch = !!schemeMatch[1];
1280    var host = schemeMatch[2];
1281    if (isAuthorityMatch) {
1282        // Any match that has an authority ('//' chars) after the scheme is
1283        // valid, such as 'http://anything'
1284        return true;
1285    }
1286    // If there's no authority ('//' chars), check that we have a hostname
1287    // that looks valid.
1288    //
1289    // The host must contain at least one '.' char and have a domain label
1290    // with at least one letter to be considered valid.
1291    //
1292    // Accept:
1293    //   - git:domain.com (scheme followed by a host
1294    // Do not accept:
1295    //   - git:something ('something' doesn't look like a host)
1296    //   - version:1.0   ('1.0' doesn't look like a host)
1297    if (host.indexOf('.') === -1 || !/[A-Za-z]/.test(host)) {
1298        // `letterRe` RegExp checks for a letter anywhere in the host string
1299        return false;
1300    }
1301    return true;
1302}
1303/**
1304 * Determines if the given `url` is a match with a valid TLD.
1305 */
1306function isValidTldMatch(url) {
1307    // TLD URL such as 'google.com', we need to confirm that we have a valid
1308    // top-level domain
1309    var tldUrlHostMatch = url.match(tldUrlHostRe);
1310    if (!tldUrlHostMatch) {
1311        // At this point, if the URL didn't match our TLD re, it must be invalid
1312        // (highly unlikely to happen, but just in case)
1313        return false;
1314    }
1315    var host = tldUrlHostMatch[0];
1316    var hostLabels = host.split('.');
1317    if (hostLabels.length < 2) {
1318        // 0 or 1 host label, there's no TLD. Ex: 'localhost'
1319        return false;
1320    }
1321    var tld = hostLabels[hostLabels.length - 1];
1322    if (!isKnownTld(tld)) {
1323        return false;
1324    }
1325    // TODO: Implement these conditions for TLD matcher:
1326    // (
1327    //     this.longestDomainLabelLength <= 63 &&
1328    //     this.domainNameLength <= 255
1329    // );
1330    return true;
1331}
1332// Regular expression to confirm a valid IPv4 address (ex: '192.168.0.1')
1333// TODO: encode this into the state machine so that we don't need to run this
1334//       regexp separately to confirm the match
1335var ipV4Re = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
1336// Regular expression used to split the IPv4 address itself from any port/path/query/hash
1337var ipV4PartRe = /[:/?#]/;
1338/**
1339 * Determines if the given URL is a valid IPv4-prefixed URL.
1340 */
1341function isValidIpV4Address(url) {
1342    // Grab just the IP address
1343    var ipV4Part = url.split(ipV4PartRe, 1)[0]; // only 1 result needed
1344    return ipV4Re.test(ipV4Part);
1345}
1346
1347/**
1348 * A regular expression used to remove the 'www.' from URLs.
1349 */
1350var wwwPrefixRegex = /^(https?:\/\/)?(?:www\.)?/i;
1351/**
1352 * The regular expression used to remove the protocol-relative '//' from a URL
1353 * string, for purposes of formatting the anchor text. A protocol-relative URL
1354 * is, for example, "//yahoo.com"
1355 */
1356var protocolRelativeRegex = /^\/\//;
1357/**
1358 * @class Autolinker.match.Url
1359 * @extends Autolinker.match.AbstractMatch
1360 *
1361 * Represents a Url match found in an input string which should be Autolinked.
1362 *
1363 * See this class's superclass ({@link Autolinker.match.Match}) for more details.
1364 */
1365var UrlMatch = /** @class */ (function (_super) {
1366    __extends(UrlMatch, _super);
1367    /**
1368     * @method constructor
1369     * @param {Object} cfg The configuration properties for the Match
1370     *   instance, specified in an Object (map).
1371     */
1372    function UrlMatch(cfg) {
1373        var _this = _super.call(this, cfg) || this;
1374        /**
1375         * @public
1376         * @property {'url'} type
1377         *
1378         * A string name for the type of match that this class represents. Can be
1379         * used in a TypeScript discriminating union to type-narrow from the
1380         * `Match` type.
1381         */
1382        _this.type = 'url';
1383        /**
1384         * @cfg {String} url (required)
1385         *
1386         * The url that was matched.
1387         */
1388        _this.url = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1389        /**
1390         * @cfg {"scheme"/"www"/"tld"} urlMatchType (required)
1391         *
1392         * The type of URL match that this class represents. This helps to determine
1393         * if the match was made in the original text with a prefixed scheme (ex:
1394         * 'http://www.google.com'), a prefixed 'www' (ex: 'www.google.com'), or
1395         * was matched by a known top-level domain (ex: 'google.com').
1396         */
1397        _this.urlMatchType = 'scheme'; // default value just to get the above doc comment in the ES5 output and documentation generator
1398        /**
1399         * @cfg {Boolean} protocolRelativeMatch (required)
1400         *
1401         * `true` if the URL is a protocol-relative match. A protocol-relative match
1402         * is a URL that starts with '//', and will be either http:// or https://
1403         * based on the protocol that the site is loaded under.
1404         */
1405        _this.protocolRelativeMatch = false; // default value just to get the above doc comment in the ES5 output and documentation generator
1406        /**
1407         * @cfg {Object} stripPrefix (required)
1408         *
1409         * The Object form of {@link Autolinker#cfg-stripPrefix}.
1410         */
1411        _this.stripPrefix = {
1412            scheme: true,
1413            www: true,
1414        }; // default value just to get the above doc comment in the ES5 output and documentation generator
1415        /**
1416         * @cfg {Boolean} stripTrailingSlash (required)
1417         * @inheritdoc Autolinker#cfg-stripTrailingSlash
1418         */
1419        _this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator
1420        /**
1421         * @cfg {Boolean} decodePercentEncoding (required)
1422         * @inheritdoc Autolinker#cfg-decodePercentEncoding
1423         */
1424        _this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator
1425        /**
1426         * @private
1427         * @property {Boolean} protocolPrepended
1428         *
1429         * Will be set to `true` if the 'http://' protocol has been prepended to the {@link #url} (because the
1430         * {@link #url} did not have a protocol)
1431         */
1432        _this.protocolPrepended = false;
1433        _this.urlMatchType = cfg.urlMatchType;
1434        _this.url = cfg.url;
1435        _this.protocolRelativeMatch = cfg.protocolRelativeMatch;
1436        _this.stripPrefix = cfg.stripPrefix;
1437        _this.stripTrailingSlash = cfg.stripTrailingSlash;
1438        _this.decodePercentEncoding = cfg.decodePercentEncoding;
1439        return _this;
1440    }
1441    /**
1442     * Returns a string name for the type of match that this class represents.
1443     * For the case of UrlMatch, returns 'url'.
1444     *
1445     * @return {String}
1446     */
1447    UrlMatch.prototype.getType = function () {
1448        return 'url';
1449    };
1450    /**
1451     * Returns a string name for the type of URL match that this class
1452     * represents.
1453     *
1454     * This helps to determine if the match was made in the original text with a
1455     * prefixed scheme (ex: 'http://www.google.com'), a prefixed 'www' (ex:
1456     * 'www.google.com'), or was matched by a known top-level domain (ex:
1457     * 'google.com').
1458     *
1459     * @return {"scheme"/"www"/"tld"}
1460     */
1461    UrlMatch.prototype.getUrlMatchType = function () {
1462        return this.urlMatchType;
1463    };
1464    /**
1465     * Returns the url that was matched, assuming the protocol to be 'http://' if the original
1466     * match was missing a protocol.
1467     *
1468     * @return {String}
1469     */
1470    UrlMatch.prototype.getUrl = function () {
1471        var url = this.url;
1472        // if the url string doesn't begin with a scheme, assume 'http://'
1473        if (!this.protocolRelativeMatch &&
1474            this.urlMatchType !== 'scheme' &&
1475            !this.protocolPrepended) {
1476            url = this.url = 'http://' + url;
1477            this.protocolPrepended = true;
1478        }
1479        return url;
1480    };
1481    /**
1482     * Returns the anchor href that should be generated for the match.
1483     *
1484     * @return {String}
1485     */
1486    UrlMatch.prototype.getAnchorHref = function () {
1487        var url = this.getUrl();
1488        return url.replace(/&amp;/g, '&'); // any &amp;'s in the URL should be converted back to '&' if they were displayed as &amp; in the source html
1489    };
1490    /**
1491     * Returns the anchor text that should be generated for the match.
1492     *
1493     * @return {String}
1494     */
1495    UrlMatch.prototype.getAnchorText = function () {
1496        var anchorText = this.getMatchedText();
1497        if (this.protocolRelativeMatch) {
1498            // Strip off any protocol-relative '//' from the anch
1498or text
1499            anchorText = stripProtocolRelativePrefix(anchorText);
1500        }
1501        if (this.stripPrefix.scheme) {
1502            anchorText = stripSchemePrefix(anchorText);
1503        }
1504        if (this.stripPrefix.www) {
1505            anchorText = stripWwwPrefix(anchorText);
1506        }
1507        if (this.stripTrailingSlash) {
1508            anchorText = removeTrailingSlash(anchorText); // remove trailing slash, if there is one
1509        }
1510        if (this.decodePercentEncoding) {
1511            anchorText = removePercentEncoding(anchorText);
1512        }
1513        return anchorText;
1514    };
1515    return UrlMatch;
1516}(AbstractMatch));
1517// Utility Functionality
1518/**
1519 * Strips the scheme prefix (such as "http://" or "https://") from the given
1520 * `url`.
1521 *
1522 * @private
1523 * @param {String} url The text of the anchor that is being generated, for
1524 *   which to strip off the url scheme.
1525 * @return {String} The `url`, with the scheme stripped.
1526 */
1527function stripSchemePrefix(url) {
1528    return url.replace(httpSchemePrefixRe, '');
1529}
1530/**
1531 * Strips the 'www' prefix from the given `url`.
1532 *
1533 * @private
1534 * @param {String} url The text of the anchor that is being generated, for
1535 *   which to strip off the 'www' if it exists.
1536 * @return {String} The `url`, with the 'www' stripped.
1537 */
1538function stripWwwPrefix(url) {
1539    // If the URL doesn't actually include 'www.' in it, skip running the
1540    // .replace() regexp on it, which is fairly slow even just to check the
1541    // string for the 'www.'s existence. Most URLs these days do not have 'www.'
1542    // in it, so most of the time we skip running the .replace(). One other
1543    // option in the future is to run a state machine on the `url` string
1544    if (!url.includes('www.')) {
1545        return url;
1546    }
1547    else {
1548        return url.replace(wwwPrefixRegex, '$1'); // leave any scheme ($1), it one exists
1549    }
1550}
1551/**
1552 * Strips any protocol-relative '//' from the anchor text.
1553 *
1554 * @private
1555 * @param {String} text The text of the anchor that is being generated, for which to strip off the
1556 *   protocol-relative prefix (such as stripping off "//")
1557 * @return {String} The `anchorText`, with the protocol-relative prefix stripped.
1558 */
1559function stripProtocolRelativePrefix(text) {
1560    return text.replace(protocolRelativeRegex, '');
1561}
1562/**
1563 * Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed.
1564 *
1565 * @private
1566 * @param {String} anchorText The text of the anchor that is being generated, for which to remove any trailing
1567 *   slash ('/') that may exist.
1568 * @return {String} The `anchorText`, with the trailing slash removed.
1569 */
1570function removeTrailingSlash(anchorText) {
1571    if (anchorText.charAt(anchorText.length - 1) === '/') {
1572        anchorText = anchorText.slice(0, -1);
1573    }
1574    return anchorText;
1575}
1576/**
1577 * Decodes percent-encoded characters from the given `anchorText`, in
1578 * preparation for the text to be displayed.
1579 *
1580 * @private
1581 * @param {String} anchorText The text of the anchor that is being
1582 *   generated, for which to decode any percent-encoded characters.
1583 * @return {String} The `anchorText`, with the percent-encoded characters
1584 *   decoded.
1585 */
1586function removePercentEncoding(anchorText) {
1587    // First, convert a few of the known % encodings to the corresponding
1588    // HTML entities that could accidentally be interpretted as special
1589    // HTML characters
1590    // NOTE: This used to be written as 5 separate .replace() calls, but that
1591    //       was 25% slower than the current form below according to jsperf
1592    var preProcessedEntityAnchorText = anchorText.replace(/%(?:22|26|27|3C|3E)/gi, function (match) {
1593        if (match === '%22')
1594            return '&quot;'; // %22: '"' char
1595        if (match === '%26')
1596            return '&amp;'; // %26: '&' char
1597        if (match === '%27')
1598            return '&#39;'; // %27: "'" char
1599        if (match === '%3C' || match === '%3c')
1600            return '&lt;'; // %3C: '<' char
1601        /*if (match === '%3E' || match === '%3e')*/ return '&gt;'; // %3E: '>' char
1602    });
1603    // Now attempt to URL-decode the rest of the anchor text. However,
1604    // decodeURIComponent() is a slow function. Only call it if we have
1605    // remaining %-encoded entities. Adding this check added ~300 ops/sec to
1606    // benchmark
1607    if (preProcessedEntityAnchorText.includes('%')) {
1608        try {
1609            return decodeURIComponent(preProcessedEntityAnchorText);
1610            // eslint-disable-next-line @typescript-eslint/no-unused-vars
1611        }
1612        catch (error) {
1613            // Invalid % escape sequence in the anchor text, we'll simply return
1614            // the preProcessedEntityAnchorText below
1615        }
1616    }
1617    return preProcessedEntityAnchorText;
1618}
1619
1620/**
1621 * A regular expression to match a 'mailto:' prefix on an email address.
1622 */
1623var mailtoSchemePrefixRe = /^mailto:/i;
1624/**
1625 * Determines if the given character may start the "local part" of an email
1626 * address. The local part is the part to the left of the '@' sign.
1627 *
1628 * Technically according to the email spec, any of the characters in the
1629 * {@link emailLocalPartCharRegex} can start an email address (including any of
1630 * the special characters), but this is so rare in the wild and the
1631 * implementation is much simpler by only starting an email address with a word
1632 * character. This is especially important when matching the '{' character which
1633 * generally starts a brace that isn't part of the email address.
1634 */
1635var isEmailLocalPartStartChar = isAlphaNumericOrMarkChar; // alias for clarity
1636/**
1637 * Determines if the given character can be part of the "local part" of an email
1638 * address. The local part is the part to the left of the '@' sign.
1639 *
1640 * Checking for an email address's start char is handled with {@link #isEmailLocalPartStartChar}
1641 */
1642function isEmailLocalPartChar(charCode) {
1643    return isEmailLocalPartStartChar(charCode) || isValidEmailLocalPartSpecialChar(charCode);
1644}
1645/**
1646 * Determines if the given email address is valid. We consider it valid if it
1647 * has a valid TLD in its host.
1648 *
1649 * @param emailAddress email address
1650 * @return true is email have valid TLD, false otherwise
1651 */
1652function isValidEmail(emailAddress) {
1653    var emailAddressTld = emailAddress.split('.').pop(); // as long as we have a valid string (as opposed to null or undefined), we will always get at least one element in the .split('.') array
1654    return isKnownTld(emailAddressTld);
1655}
1656
1657/**
1658 * @class Autolinker.match.Email
1659 * @extends Autolinker.match.AbstractMatch
1660 *
1661 * Represents a Email match found in an input string which should be Autolinked.
1662 *
1663 * See this class's superclass ({@link Autolinker.match.Match}) for more details.
1664 */
1665var EmailMatch = /** @class */ (function (_super) {
1666    __extends(EmailMatch, _super);
1667    /**
1668     * @method constructor
1669     * @param {Object} cfg The configuration properties for the Match
1670     *   instance, specified in an Object (map).
1671     */
1672    function EmailMatch(cfg) {
1673        var _this = _super.call(this, cfg) || this;
1674        /**
1675         * @public
1676         * @property {'email'} type
1677         *
1678         * A string name for the type of match that this class represents. Can be
1679         * used in a TypeScript discriminating union to type-narrow from the
1680         * `Match` type.
1681         */
1682        _this.type = 'email';
1683        /**
1684         * @cfg {String} email (required)
1685         *
1686         * The email address that was matched.
1687         */
1688        _this.email = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1689        _this.email = cfg.email;
1690        return _this;
1691    }
1692    /**
1693     * Returns a string name for the type of match that this class represents.
1694     * For the case of EmailMatch, returns 'email'.
1695     *
1696     * @return {String}
1697     */
1698    EmailMatch.prototype.getType = function () {
1699        return 'email';
1700    };
1701    /**
1702     * Returns the email address that was matched.
1703     *
1704     * @return {String}
1705     */
1706    EmailMatch.prototype.getEmail = function () {
1707        return this.email;
1708    };
1709    /**
1710     * Returns the anchor href that should be generated for the match.
1711     *
1712     * @return {String}
1713     */
1714    EmailMatch.prototype.getAnchorHref = function () {
1715        return 'mailto:' + this.email;
1716    };
1717    /**
1718     * Returns the anchor text that should be generated for the match.
1719     *
1720     * @return {String}
1721     */
1722    EmailMatch.prototype.getAnchorText = function () {
1723        return this.email;
1724    };
1725    return EmailMatch;
1726}(AbstractMatch));
1727
1728/**
1729 * Determines if the given `char` is a an allowed character in a hashtag. These
1730 * are underscores or any alphanumeric char.
1731 */
1732function isHashtagTextChar(charCode) {
1733    return charCode === 95 /* Char.Underscore */ || isAlphaNumericOrMarkChar(charCode);
1734}
1735/**
1736 * Determines if a hashtag match is valid.
1737 */
1738function isValidHashtag(hashtag) {
1739    // Max length of 140 for a hashtag ('#' char + 139 word chars)
1740    return hashtag.length <= 140;
1741}
1742var hashtagServices = [
1743    'twitter',
1744    'facebook',
1745    'instagram',
1746    'tiktok',
1747    'youtube',
1748];
1749
1750/**
1751 * @class Autolinker.match.Hashtag
1752 * @extends Autolinker.match.AbstractMatch
1753 *
1754 * Represents a Hashtag match found in an input string which should be
1755 * Autolinked.
1756 *
1757 * See this class's superclass ({@link Autolinker.match.Match}) for more
1758 * details.
1759 */
1760var HashtagMatch = /** @class */ (function (_super) {
1761    __extends(HashtagMatch, _super);
1762    /**
1763     * @method constructor
1764     * @param {Object} cfg The configuration properties for the Match
1765     *   instance, specified in an Object (map).
1766     */
1767    function HashtagMatch(cfg) {
1768        var _this = _super.call(this, cfg) || this;
1769        /**
1770         * @public
1771         * @property {'hashtag'} type
1772         *
1773         * A string name for the type of match that this class represents. Can be
1774         * used in a TypeScript discriminating union to type-narrow from the
1775         * `Match` type.
1776         */
1777        _this.type = 'hashtag';
1778        /**
1779         * @cfg {String} serviceName
1780         *
1781         * The service to point hashtag matches to. See {@link Autolinker#hashtag}
1782         * for available values.
1783         */
1784        _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator
1785        /**
1786         * @cfg {String} hashtag (required)
1787         *
1788         * The HashtagMatch that was matched, without the '#'.
1789         */
1790        _this.hashtag = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1791        _this.serviceName = cfg.serviceName;
1792        _this.hashtag = cfg.hashtag;
1793        return _this;
1794    }
1795    /**
1796     * Returns a string name for the type of match that this class represents.
1797     * For the case of HashtagMatch, returns 'hashtag'.
1798     *
1799     * @return {String}
1800     */
1801    HashtagMatch.prototype.getType = function () {
1802        return 'hashtag';
1803    };
1804    /**
1805     * Returns the configured {@link #serviceName} to point the HashtagMatch to.
1806     * Ex: 'facebook', 'twitter'.
1807     *
1808     * @return {String}
1809     */
1810    HashtagMatch.prototype.getServiceName = function () {
1811        return this.serviceName;
1812    };
1813    /**
1814     * Returns the matched hashtag, without the '#' character.
1815     *
1816     * @return {String}
1817     */
1818    HashtagMatch.prototype.getHashtag = function () {
1819        return this.hashtag;
1820    };
1821    /**
1822     * Returns the anchor href that should be generated for the match.
1823     *
1824     * @return {String}
1825     */
1826    HashtagMatch.prototype.getAnchorHref = function () {
1827        var serviceName = this.serviceName, hashtag = this.hashtag;
1828        switch (serviceName) {
1829            case 'twitter':
1830                return 'https://twitter.com/hashtag/' + hashtag;
1831            case 'facebook':
1832                return 'https://www.facebook.com/hashtag/' + hashtag;
1833            case 'instagram':
1834                return 'https://instagram.com/explore/tags/' + hashtag;
1835            case 'tiktok':
1836                return 'https://www.tiktok.com/tag/' + hashtag;
1837            case 'youtube':
1838                return 'https://youtube.com/hashtag/' + hashtag;
1839            /* istanbul ignore next */
1840            default:
1841                // Should never happen because Autolinker's constructor should block any invali
vendor: 11,747 bytes, lines 1841-2164
1841d values, but just in case
1842                assertNever(serviceName);
1843        }
1844    };
1845    /**
1846     * Returns the anchor text that should be generated for the match.
1847     *
1848     * @return {String}
1849     */
1850    HashtagMatch.prototype.getAnchorText = function () {
1851        return '#' + this.hashtag;
1852    };
1853    /**
1854     * Returns the CSS class suffixes that should be used on a tag built with
1855     * the match. See {@link Autolinker.match.Match#getCssClassSuffixes} for
1856     * details.
1857     *
1858     * @return {String[]}
1859     */
1860    HashtagMatch.prototype.getCssClassSuffixes = function () {
1861        var cssClassSuffixes = _super.prototype.getCssClassSuffixes.call(this), serviceName = this.getServiceName();
1862        if (serviceName) {
1863            cssClassSuffixes.push(serviceName);
1864        }
1865        return cssClassSuffixes;
1866    };
1867    return HashtagMatch;
1868}(AbstractMatch));
1869
1870var mentionRegexes = {
1871    twitter: /^@\w{1,15}$/,
1872    instagram: /^@[_\w]{1,30}$/,
1873    soundcloud: /^@[-a-z0-9_]{3,25}$/,
1874    // TikTok usernames are 1-24 characters containing letters, numbers, underscores
1875    // and periods, but cannot end in a period: https://support.tiktok.com/en/getting-started/setting-up-your-profile/changing-your-username
1876    tiktok: /^@[.\w]{1,23}[\w]$/,
1877    // Youtube usernames are 3-30 characters containing letters, numbers, underscores,
1878    // dashes, or latin middle dots ('·').
1879    // https://support.google.com/youtube/answer/11585688?hl=en&co=GENIE.Platform%3DAndroid#tns
1880    youtube: /^@[-.·\w]{3,30}$/,
1881};
1882/**
1883 * Determines if the given character can be part of a mention's text characters.
1884 *
1885 * Accepts characters that match the RegExp `/[-\w.]/`, which are the possible
1886 * mention characters for any service.
1887 *
1888 * We'll confirm the match based on the user-configured service name after the
1889 * match is found.
1890 */
1891function isMentionTextChar(charCode) {
1892    return (charCode === 45 /* Char.Dash */ || // '-'
1893        charCode === 46 /* Char.Dot */ || // '.'
1894        charCode === 95 /* Char.Underscore */ || // '_'
1895        isAsciiLetterChar(charCode) ||
1896        isDigitChar(charCode));
1897}
1898/**
1899 * Determines if the given `mention` text is valid.
1900 */
1901function isValidMention(mention, serviceName) {
1902    var re = mentionRegexes[serviceName];
1903    return re.test(mention);
1904}
1905var mentionServices = [
1906    'twitter',
1907    'instagram',
1908    'soundcloud',
1909    'tiktok',
1910    'youtube',
1911];
1912
1913/**
1914 * @class Autolinker.match.Mention
1915 * @extends Autolinker.match.AbstractMatch
1916 *
1917 * Represents a Mention match found in an input string which should be Autolinked.
1918 *
1919 * See this class's superclass ({@link Autolinker.match.Match}) for more details.
1920 */
1921var MentionMatch = /** @class */ (function (_super) {
1922    __extends(MentionMatch, _super);
1923    /**
1924     * @method constructor
1925     * @param {Object} cfg The configuration properties for the Match
1926     *   instance, specified in an Object (map).
1927     */
1928    function MentionMatch(cfg) {
1929        var _this = _super.call(this, cfg) || this;
1930        /**
1931         * @public
1932         * @property {'mention'} type
1933         *
1934         * A string name for the type of match that this class represents. Can be
1935         * used in a TypeScript discriminating union to type-narrow from the
1936         * `Match` type.
1937         */
1938        _this.type = 'mention';
1939        /**
1940         * @cfg {String} serviceName
1941         *
1942         * The service to point mention matches to. See {@link Autolinker#mention}
1943         * for available values.
1944         */
1945        _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator
1946        /**
1947         * @cfg {String} mention (required)
1948         *
1949         * The Mention that was matched, without the '@' character.
1950         */
1951        _this.mention = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
1952        _this.mention = cfg.mention;
1953        _this.serviceName = cfg.serviceName;
1954        return _this;
1955    }
1956    /**
1957     * Returns a string name for the type of match that this class represents.
1958     * For the case of MentionMatch, returns 'mention'.
1959     *
1960     * @return {String}
1961     */
1962    MentionMatch.prototype.getType = function () {
1963        return 'mention';
1964    };
1965    /**
1966     * Returns the mention, without the '@' character.
1967     *
1968     * @return {String}
1969     */
1970    MentionMatch.prototype.getMention = function () {
1971        return this.mention;
1972    };
1973    /**
1974     * Returns the configured {@link #serviceName} to point the mention to.
1975     * Ex: 'instagram', 'twitter', 'soundcloud'.
1976     *
1977     * @return {String}
1978     */
1979    MentionMatch.prototype.getServiceName = function () {
1980        return this.serviceName;
1981    };
1982    /**
1983     * Returns the anchor href that should be generated for the match.
1984     *
1985     * @return {String}
1986     */
1987    MentionMatch.prototype.getAnchorHref = function () {
1988        switch (this.serviceName) {
1989            case 'twitter':
1990                return 'https://twitter.com/' + this.mention;
1991            case 'instagram':
1992                return 'https://instagram.com/' + this.mention;
1993            case 'soundcloud':
1994                return 'https://soundcloud.com/' + this.mention;
1995            case 'tiktok':
1996                return 'https://www.tiktok.com/@' + this.mention;
1997            case 'youtube':
1998                return 'https://youtube.com/@' + this.mention;
1999            /* istanbul ignore next */
2000            default:
2001                // Should never happen because Autolinker's constructor should block any invalid values, but just in case.
2002                assertNever(this.serviceName);
2003        }
2004    };
2005    /**
2006     * Returns the anchor text that should be generated for the match.
2007     *
2008     * @return {String}
2009     */
2010    MentionMatch.prototype.getAnchorText = function () {
2011        return '@' + this.mention;
2012    };
2013    /**
2014     * Returns the CSS class suffixes that should be used on a tag built with
2015     * the match. See {@link Autolinker.match.Match#getCssClassSuffixes} for
2016     * details.
2017     *
2018     * @return {String[]}
2019     */
2020    MentionMatch.prototype.getCssClassSuffixes = function () {
2021        var cssClassSuffixes = _super.prototype.getCssClassSuffixes.call(this), serviceName = this.getServiceName();
2022        if (serviceName) {
2023            cssClassSuffixes.push(serviceName);
2024        }
2025        return cssClassSuffixes;
2026    };
2027    return MentionMatch;
2028}(AbstractMatch));
2029
2030// Regex that specifies any delimiter char that allows us to treat the number as
2031// a phone number rather than just any other number that could appear in text.
2032var hasDelimCharsRe = /[-. ()]/;
2033// Over the years, many people have added to this regex, but it should have been
2034// split up by country. Maybe one day we can break this down.
2035var mostPhoneNumbers = /(?:(?:(?:(\+)?\d{1,3}[-. ]?)?\(?\d{3}\)?[-. ]?\d{3}[-. ]?\d{4})|(?:(\+)(?:9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-. ]?(?:\d[-. ]?){6,12}\d+))([,;]+[0-9]+#?)*/;
2036// Regex for Japanese phone numbers
2037var japanesePhoneRe = /(0([1-9]-?[1-9]\d{3}|[1-9]{2}-?\d{3}|[1-9]{2}\d{1}-?\d{2}|[1-9]{2}\d{2}-?\d{1})-?\d{4}|0[789]0-?\d{4}-?\d{4}|050-?\d{4}-?\d{4})/;
2038// Combined regex
2039var validPhoneNumberRe = new RegExp("^".concat(mostPhoneNumbers.source, "|").concat(japanesePhoneRe.source, "$"));
2040/**
2041 * Determines if the character is a phone number separator character (i.e.
2042 * '-', '.', or ' ' (space))
2043 */
2044function isPhoneNumberSeparatorChar(charCode) {
2045    return (charCode === 45 /* Char.Dash */ || // '-'
2046        charCode === 46 /* Char.Dot */ || // '.'
2047        charCode === 32 /* Char.Space */ // ' '
2048    );
2049}
2050/**
2051 * Determines if the character is a control character in a phone number. Control
2052 * characters are as follows:
2053 *
2054 * - ',': A 1 second pause. Useful for dialing extensions once the main phone number has been reached
2055 * - ';': A "wait" that waits for the user to take action (tap something, for instance on a smart phone)
2056 */
2057function isPhoneNumberControlChar(charCode) {
2058    return (charCode === 44 /* Char.Comma */ || // ','
2059        charCode === 59 /* Char.SemiColon */ // ';'
2060    );
2061}
2062/**
2063 * Determines if the given phone number text found in a string is a valid phone
2064 * number.
2065 *
2066 * Our state machine parser is simplified to grab anything that looks like a
2067 * phone number, and this function confirms the match.
2068 */
2069function isValidPhoneNumber(phoneNumberText) {
2070    // We'll only consider the match as a phone number if there is some kind of
2071    // delimiter character (a prefixed '+' sign, or separator chars).
2072    //
2073    // Accepts:
2074    //     (123) 456-7890
2075    //     +38755233976
2076    // Does not accept:
2077    //     1234567890  (no delimiter chars - may just be a random number that's not a phone number)
2078    var hasDelimiters = phoneNumberText.charAt(0) === '+' || hasDelimCharsRe.test(phoneNumberText);
2079    return hasDelimiters && validPhoneNumberRe.test(phoneNumberText);
2080}
2081
2082/**
2083 * @class Autolinker.match.Phone
2084 * @extends Autolinker.match.AbstractMatch
2085 *
2086 * Represents a Phone number match found in an input string which should be
2087 * Autolinked.
2088 *
2089 * See this class's superclass ({@link Autolinker.match.Match}) for more
2090 * details.
2091 */
2092var PhoneMatch = /** @class */ (function (_super) {
2093    __extends(PhoneMatch, _super);
2094    /**
2095     * @method constructor
2096     * @param {Object} cfg The configuration properties for the Match
2097     *   instance, specified in an Object (map).
2098     */
2099    function PhoneMatch(cfg) {
2100        var _this = _super.call(this, cfg) || this;
2101        /**
2102         * @public
2103         * @property {'phone'} type
2104         *
2105         * A string name for the type of match that this class represents. Can be
2106         * used in a TypeScript discriminating union to type-narrow from the
2107         * `Match` type.
2108         */
2109        _this.type = 'phone';
2110        /**
2111         * @protected
2112         * @property {String} number (required)
2113         *
2114         * The phone number that was matched, without any delimiter characters.
2115         *
2116         * Note: This is a string to allow for prefixed 0's.
2117         */
2118        _this.number = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
2119        /**
2120         * @protected
2121         * @property  {Boolean} plusSign (required)
2122         *
2123         * `true` if the matched phone number started with a '+' sign. We'll include
2124         * it in the `tel:` URL if so, as this is needed for international numbers.
2125         *
2126         * Ex: '+1 (123) 456 7879'
2127         */
2128        _this.plusSign = false; // default value just to get the above doc comment in the ES5 output and documentation generator
2129        _this.number = cfg.number;
2130        _this.plusSign = cfg.plusSign;
2131        return _this;
2132    }
2133    /**
2134     * Returns a string name for the type of match that this class represents.
2135     * For the case of PhoneMatch, returns 'phone'.
2136     *
2137     * @return {String}
2138     */
2139    PhoneMatch.prototype.getType = function () {
2140        return 'phone';
2141    };
2142    /**
2143     * Returns the phone number that was matched as a string, without any
2144     * delimiter characters.
2145     *
2146     * Note: This is a string to allow for prefixed 0's.
2147     *
2148     * @return {String}
2149     */
2150    PhoneMatch.prototype.getPhoneNumber = function () {
2151        return this.number;
2152    };
2153    /**
2154     * Alias of {@link #getPhoneNumber}, returns the phone number that was
2155     * matched as a string, without any delimiter characters.
2156     *
2157     * Note: This is a string to allow for prefixed 0's.
2158     *
2159     * @return {String}
2160     */
2161    PhoneMatch.prototype.getNumber = function () {
2162        return this.getPhoneNumber();
2163    };
2164    /**
2165     * Returns the anchor href that should be generated for the match.
2166     *
2167     * @return {String}
2168     */
2169    PhoneMatch.prototype.getAnchorHref = function () {
2170        return 'tel:' + (this.plusSign ? '+' : '') + this.number;
2171    };
2172    /**
2173     * Returns the anchor text that should be generated for the match.
2174     *
2175     * @return {String}
2176     */
2177    PhoneMatch.prototype.getAnchorText = function () {
2178        return this.matchedText;
2179    };
2180    return PhoneMatch;
2181}(AbstractMatch));
vendor: 7,811 bytes, lines 2182-2332
2182
2183// For debugging: search for and uncomment other "For debugging" lines
2184// import CliTable from 'cli-table';
2185/**
2186 * Context object containing all the state needed by the state machine functions.
2187 *
2188 * ## Historical note
2189 *
2190 * In v4.1.1, we used nested functions to handle the context via closures, but
2191 * this necessitated re-creating the functions for each call to `parseMatches()`,
2192 * which made them difficult for v8 to JIT optimize. In v4.1.2, we lifted all of
2193 * the functions to the top-level scope and passed the context object between
2194 * them, which allows the functions to be JIT compiled once and reused.
2195 */
2196var ParseMatchesContext = /** @class */ (function () {
2197    function ParseMatchesContext(text, args) {
2198        this.charIdx = 0; // Current character index being processed
2199        this.matches = []; // Collection of matches found
2200        this._stateMachines = []; // Array of active state machines
2201        this.schemeUrlMachinesCount = 0; // part of an optimization to remove the need to go into a slow code block when unnecessary. Since it's been so long since the initial implementation, not sure that this can ever go above 1, but keeping it as a counter to be safe
2202        this.text = text;
2203        this.tagBuilder = args.tagBuilder;
2204        this.stripPrefix = args.stripPrefix;
2205        this.stripTrailingSlash = args.stripTrailingSlash;
2206        this.decodePercentEncoding = args.decodePercentEncoding;
2207        this.hashtagServiceName = args.hashtagServiceName;
2208        this.mentionServiceName = args.mentionServiceName;
2209    }
2210    Object.defineProperty(ParseMatchesContext.prototype, "stateMachines", {
2211        get: function () {
2212            return this._stateMachines;
2213        },
2214        enumerable: false,
2215        configurable: true
2216    });
2217    ParseMatchesContext.prototype.addMachine = function (stateMachine) {
2218        this._stateMachines.push(stateMachine);
2219        if (isSchemeUrlStateMachine(stateMachine)) {
2220            this.schemeUrlMachinesCount++;
2221        }
2222    };
2223    ParseMatchesContext.prototype.removeMachine = function (stateMachine) {
2224        // Performance note: this was originally implemented with Array.prototype.splice()
2225        // and mutated the array in place. Switching to filter added ~280ops/sec
2226        // on the benchmark, although likely at the expense of GC time. Perhaps
2227        // in the future, we implement a rotating array so we never need to move
2228        // or clean anything up
2229        this._stateMachines = this._stateMachines.filter(function (m) { return m !== stateMachine; });
2230        // If we've removed the URL state machine, set the flag to false.
2231        // This flag is a quick test that helps us skip a slow section of
2232        // code when there is already a URL state machine present.
2233        if (isSchemeUrlStateMachine(stateMachine)) {
2234            this.schemeUrlMachinesCount--;
2235        }
2236    };
2237    ParseMatchesContext.prototype.hasSchemeUrlMachine = function () {
2238        return this.schemeUrlMachinesCount > 0;
2239    };
2240    return ParseMatchesContext;
2241}());
2242/**
2243 * Parses URL, email, twitter, mention, and hashtag matches from the given
2244 * `text`.
2245 */
2246function parseMatches(text, args) {
2247    // Create the context object that will be passed to all state functions
2248    var context = new ParseMatchesContext(text, args);
2249    // For debugging: search for and uncomment other "For debugging" lines
2250    // const table = new CliTable({
2251    //     head: ['charIdx', 'char', 'code', 'type', 'states', 'startIdx', 'reached accept state'],
2252    // });
2253    for (; context.charIdx < context.text.length; context.charIdx++) {
2254        var char = text.charAt(context.charIdx);
2255        var charCode = text.charCodeAt(context.charIdx);
2256        if (context.stateMachines.length === 0) {
2257            stateNoMatch(context, char, charCode);
2258        }
2259        else {
2260            // Must loop through the state machines backwards for when one
2261            // is removed
2262            for (var stateIdx = context.stateMachines.length - 1; stateIdx >= 0; stateIdx--) {
2263                var stateMachine = context.stateMachines[stateIdx];
2264                switch (stateMachine.state) {
2265                    // Protocol-relative URL states
2266                    case 11 /* State.ProtocolRelativeSlash1 */:
2267                        stateProtocolRelativeSlash1(context, stateMachine, charCode);
2268                        break;
2269                    case 12 /* State.ProtocolRelativeSlash2 */:
2270                        stateProtocolRelativeSlash2(context, stateMachine, charCode);
2271                        break;
2272                    case 0 /* State.SchemeChar */:
2273                        stateSchemeChar(context, stateMachine, charCode);
2274                        break;
2275                    case 1 /* State.SchemeHyphen */:
2276                        stateSchemeHyphen(context, stateMachine, charCode);
2277                        break;
2278                    case 2 /* State.SchemeColon */:
2279                        stateSchemeColon(context, stateMachine, charCode);
2280                        break;
2281                    case 3 /* State.SchemeSlash1 */:
2282                        stateSchemeSlash1(context, stateMachine, charCode);
2283                        break;
2284                    case 4 /* State.SchemeSlash2 */:
2285                        stateSchemeSlash2(context, stateMachine, char, charCode);
2286                        break;
2287                    case 5 /* State.DomainLabelChar */:
2288                        stateDomainLabelChar(context, stateMachine, charCode);
2289                        break;
2290                    case 6 /* State.DomainHyphen */:
2291                        stateDomainHyphen(context, stateMachine, char, charCode);
2292                        break;
2293                    case 7 /* State.DomainDot */:
2294                        stateDomainDot(context, stateMachine, char, charCode);
2295                        break;
2296                    case 13 /* State.IpV4Digit */:
2297                        stateIpV4Digit(context, stateMachine, charCode);
2298                        break;
2299                    case 14 /* State.IpV4Dot */:
2300                        stateIpV4Dot(context, stateMachine, charCode);
2301                        break;
2302                    case 8 /* State.PortColon */:
2303                        statePortColon(context, stateMachine, charCode);
2304                        break;
2305                    case 9 /* State.PortNumber */:
2306                        statePortNumber(context, stateMachine, charCode);
2307                        break;
2308                    case 10 /* State.Path */:
2309                        statePath(context, stateMachine, charCode);
2310                        break;
2311                    // Email States
2312                    case 15 /* State.EmailMailto_M */:
2313                        stateEmailMailto_M(context, stateMachine, char, charCode);
2314                        break;
2315                    case 16 /* State.EmailMailto_A */:
2316                        stateEmailMailto_A(context, stateMachine, char, charCode);
2317                        break;
2318                    case 17 /* State.EmailMailto_I */:
2319                        stateEmailMailto_I(context, stateMachine, char, charCode);
2320                        break;
2321                    case 18 /* State.EmailMailto_L */:
2322                        stateEmailMailto_L(context, stateMachine, char, charCode);
2323                        break;
2324                    case 19 /* State.EmailMailto_T */:
2325                        stateEmailMailto_T(context, stateMachine, char, charCode);
2326                        break;
2327                    case 20 /* State.EmailMailto_O */:
2328                        stateEmailMailto_O(context, stateMachine, charCode);
2329                        break;
2330                    case 21 /* State.EmailMailto_Colon */:
2331                        stateEmailMailtoColon(context, stateMachine, charCode);
2332                        break;
vendor: 9,630 bytes, lines 2333-2510
2333                    case 22 /* State.EmailLocalPart */:
2334                        stateEmailLocalPart(context, stateMachine, charCode);
2335                        break;
2336                    case 23 /* State.EmailLocalPartDot */:
2337                        stateEmailLocalPartDot(context, stateMachine, charCode);
2338                        break;
2339                    case 24 /* State.EmailAtSign */:
2340                        stateEmailAtSign(context, stateMachine, charCode);
2341                        break;
2342                    case 25 /* State.EmailDomainChar */:
2343                        stateEmailDomainChar(context, stateMachine, charCode);
2344                        break;
2345                    case 26 /* State.EmailDomainHyphen */:
2346                        stateEmailDomainHyphen(context, stateMachine, charCode);
2347                        break;
2348                    case 27 /* State.EmailDomainDot */:
2349                        stateEmailDomainDot(context, stateMachine, charCode);
2350                        break;
2351                    // Hashtag states
2352                    case 28 /* State.HashtagHashChar */:
2353                        stateHashtagHashChar(context, stateMachine, charCode);
2354                        break;
2355                    case 29 /* State.HashtagTextChar */:
2356                        stateHashtagTextChar(context, stateMachine, charCode);
2357                        break;
2358                    // Mention states
2359                    case 30 /* State.MentionAtChar */:
2360                        stateMentionAtChar(context, stateMachine, charCode);
2361                        break;
2362                    case 31 /* State.MentionTextChar */:
2363                        stateMentionTextChar(context, stateMachine, charCode);
2364                        break;
2365                    // Phone number states
2366                    case 32 /* State.PhoneNumberOpenParen */:
2367                        statePhoneNumberOpenParen(context, stateMachine, char, charCode);
2368                        break;
2369                    case 33 /* State.PhoneNumberAreaCodeDigit1 */:
2370                        statePhoneNumberAreaCodeDigit1(context, stateMachine, charCode);
2371                        break;
2372                    case 34 /* State.PhoneNumberAreaCodeDigit2 */:
2373                        statePhoneNumberAreaCodeDigit2(context, stateMachine, charCode);
2374                        break;
2375                    case 35 /* State.PhoneNumberAreaCodeDigit3 */:
2376                        statePhoneNumberAreaCodeDigit3(context, stateMachine, charCode);
2377                        break;
2378                    case 36 /* State.PhoneNumberCloseParen */:
2379                        statePhoneNumberCloseParen(context, stateMachine, char, charCode);
2380                        break;
2381                    case 37 /* State.PhoneNumberPlus */:
2382                        statePhoneNumberPlus(context, stateMachine, char, charCode);
2383                        break;
2384                    case 38 /* State.PhoneNumberDigit */:
2385                        statePhoneNumberDigit(context, stateMachine, char, charCode);
2386                        break;
2387                    case 39 /* State.PhoneNumberSeparator */:
2388                        statePhoneNumberSeparator(context, stateMachine, char, charCode);
2389                        break;
2390                    case 40 /* State.PhoneNumberControlChar */:
2391                        statePhoneNumberControlChar(context, stateMachine, charCode);
2392                        break;
2393                    case 41 /* State.PhoneNumberPoundChar */:
2394                        statePhoneNumberPoundChar(context, stateMachine, charCode);
2395                        break;
2396                    /* istanbul ignore next */
2397                    default:
2398                        assertNever(stateMachine.state);
2399                }
2400            }
2401            // Special case for handling a colon (or other non-alphanumeric)
2402            // when preceded by another character, such as in the text:
2403            //     Link 1:http://google.com
2404            // In this case, the 'h' character after the colon wouldn't start a
2405            // new scheme url because we'd be in a ipv4 or tld url and the colon
2406            // would be interpreted as a port ':' char. Also, only start a new
2407            // scheme url machine if there isn't currently one so we don't start
2408            // new ones for colons inside a url
2409            //
2410            // TODO: The addition of this snippet (to fix the bug) in 4.0.1 lost
2411            // us ~500 ops/sec on the benchmarks. Optimizing it with the
2412            // hasSchemeUrlMachine() flag and optimizing the isSchemeStartChar()
2413            // method for 4.1.3 got us back about ~400ops/sec. One potential way
2414            // to improve this even ore is to add this snippet to individual
2415            // state handler functions where it can occur to prevent running it
2416            // on every loop interation.
2417            if (!context.hasSchemeUrlMachine() &&
2418                context.charIdx > 0 &&
2419                isSchemeStartChar(charCode)) {
2420                var prevCharCode = context.text.charCodeAt(context.charIdx - 1);
2421                if (!isSchemeStartChar(prevCharCode)) {
2422                    context.addMachine(createSchemeUrlStateMachine(context.charIdx, 0 /* State.SchemeChar */));
2423                }
2424            }
2425        }
2426        // For debugging: search for and uncomment other "For debugging" lines
2427        // table.push([
2428        //     String(context.charIdx),
2429        //     char,
2430        //     `10: ${char.charCodeAt(0)}\n0x: ${char.charCodeAt(0).toString(16)}\nU+${char.codePointAt(0)}`,
2431        //     context.stateMachines.map(machine => `${StateMachineType[machine.type]}${'matchType' in machine ? ` (${UrlStateMachineMatchType[machine.matchType]})` : ''}`).join('\n') || '(none)',
2432        //     context.stateMachines.map(machine => State[machine.state]).join('\n') || '(none)',
2433        //     context.stateMachines.map(m => m.startIdx).join('\n'),
2434        //     context.stateMachines.map(m => m.acceptStateReached).join('\n'),
2435        // ]);
2436    }
2437    // Capture any valid match at the end of the string
2438    // Note: this loop must happen in reverse because
2439    // captureMatchIfValidAndRemove() removes state machines from the array
2440    // and we'll end up skipping every other one if we remove while looping
2441    // forward
2442    for (var i = context.stateMachines.length - 1; i >= 0; i--) {
2443        context.stateMachines.forEach(function (stateMachine) {
2444            return captureMatchIfValidAndRemove(context, stateMachine);
2445        });
2446    }
2447    // For debugging: search for and uncomment other "For debugging" lines
2448    // console.log(`\nRead string:\n  ${text}`);
2449    // console.log(table.toString());
2450    return context.matches;
2451}
2452/**
2453 * Handles the state when we're not in a URL/email/etc. (i.e. when no state machines exist)
2454 */
2455function stateNoMatch(context, char, charCode) {
2456    var charIdx = context.charIdx;
2457    if (charCode === 35 /* Char.NumberSign */ /* '#' */) {
2458        // Hash char, start a Hashtag match
2459        context.addMachine(createHashtagStateMachine(charIdx, 28 /* State.HashtagHashChar */));
2460    }
2461    else if (charCode === 64 /* Char.AtSign */ /* '@' */) {
2462        // '@' char, start a Mention match
2463        context.addMachine(createMentionStateMachine(charIdx, 30 /* State.MentionAtChar */));
2464    }
2465    else if (charCode === 47 /* Char.Slash */ /* '/' */) {
2466        // A slash could begin a protocol-relative URL
2467        context.addMachine(createTldUrlStateMachine(charIdx, 11 /* State.ProtocolRelativeSlash1 */));
2468    }
2469    else if (charCode === 43 /* Char.Plus */ /* '+' */) {
2470        // A '+' char can start a Phone number
2471        context.addMachine(createPhoneNumberStateMachine(charIdx, 37 /* State.PhoneNumberPlus */));
2472    }
2473    else if (charCode === 40 /* Char.OpenParen */ /* '(' */) {
2474        context.addMachine(createPhoneNumberStateMachine(charIdx, 32 /* State.PhoneNumberOpenParen */));
2475    }
2476    else {
2477        if (isDigitChar(charCode)) {
2478            // A digit could start a phone number
2479            context.addMachine(createPhoneNumberStateMachine(charIdx, 38 /* State.PhoneNumberDigit */));
2480            // A digit could start an IP address
2481            context.addMachine(createIpV4UrlStateMachine(charIdx, 13 /* State.IpV4Digit */));
2482        }
2483        if (isEmailLocalPartStartChar(charCode)) {
2484            // Any email local part. An 'm' character in particular could
2485            // start a 'mailto:' match
2486            var startState = char.toLowerCase() === 'm' ? 15 /* State.EmailMailto_M */ : 22 /* State.EmailLocalPart */;
2487            context.addMachine(createEmailStateMachine(charIdx, startState));
2488        }
2489        if (isSchemeStartChar(charCode)) {
2490            // An uppercase or lowercase letter may start a scheme match
2491            context.addMachine(createSchemeUrlStateMachine(charIdx, 0 /* State.SchemeChar */));
2492        }
2493        if (isAlphaNumericOrMarkChar(charCode)) {
2494            // A unicode alpha character or digit could start a domain name
2495            // label for a TLD match
2496            context.addMachine(createTldUrlStateMachine(charIdx, 5 /* State.DomainLabelChar */));
2497        }
2498    }
2499    // Anything else, remain in the "non-url" state by not creating any
2500    // state machines
2501}
2502// Implements ABNF: ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
2503function stateSchemeChar(context, stateMachine, charCode) {
2504    if (charCode === 58 /* Char.Colon */ /* ':' */) {
2505        stateMachine.state = 2 /* State.SchemeColon */;
2506    }
2507    else if (charCode === 45 /* Char.Dash */ /* '-' */) {
2508        stateMachine.state = 1 /* State.SchemeHyphen */;
2509    }
2510    else if (isSchemeChar(charCode)) 
vendor: 8,995 bytes, lines 2510-2749
2510;
2511    else {
2512        // Any other character, not a scheme
2513        context.removeMachine(stateMachine);
2514    }
2515}
2516function stateSchemeHyphen(context, stateMachine, charCode) {
2517    var charIdx = context.charIdx;
2518    if (charCode === 45 /* Char.Dash */ /* '-' */) ;
2519    else if (charCode === 47 /* Char.Slash */ /* '/' */) {
2520        // Not a valid scheme match, but may be the start of a
2521        // protocol-relative match (such as //google.com)
2522        context.removeMachine(stateMachine);
2523        context.addMachine(createTldUrlStateMachine(charIdx, 11 /* State.ProtocolRelativeSlash1 */));
2524    }
2525    else if (isSchemeChar(charCode)) {
2526        stateMachine.state = 0 /* State.SchemeChar */;
2527    }
2528    else {
2529        // Any other character, not a scheme
2530        context.removeMachine(stateMachine);
2531    }
2532}
2533// https://tools.ietf.org/html/rfc3986#appendix-A
2534function stateSchemeColon(context, stateMachine, charCode) {
2535    var charIdx = context.charIdx;
2536    if (charCode === 47 /* Char.Slash */ /* '/' */) {
2537        stateMachine.state = 3 /* State.SchemeSlash1 */;
2538    }
2539    else if (charCode === 46 /* Char.Dot */ /* '.' */) {
2540        // We've read something like 'hello:.' - don't capture
2541        context.removeMachine(stateMachine);
2542    }
2543    else if (isDomainLabelStartChar(charCode)) {
2544        stateMachine.state = 5 /* State.DomainLabelChar */;
2545        // It's possible that we read an "introduction" piece of text,
2546        // and the character after the current colon actually starts an
2547        // actual scheme. An example of this is:
2548        //     "The link:http://google.com"
2549        // Hence, start a new machine to capture this match if so
2550        if (isSchemeStartChar(charCode)) {
2551            context.addMachine(createSchemeUrlStateMachine(charIdx, 0 /* State.SchemeChar */));
2552        }
2553    }
2554    else {
2555        context.removeMachine(stateMachine);
2556    }
2557}
2558// https://tools.ietf.org/html/rfc3986#appendix-A
2559function stateSchemeSlash1(context, stateMachine, charCode) {
2560    if (charCode === 47 /* Char.Slash */ /* '/' */) {
2561        stateMachine.state = 4 /* State.SchemeSlash2 */;
2562    }
2563    else if (isPathChar(charCode)) {
2564        stateMachine.state = 10 /* State.Path */;
2565        stateMachine.acceptStateReached = true;
2566    }
2567    else {
2568        captureMatchIfValidAndRemove(context, stateMachine);
2569    }
2570}
2571function stateSchemeSlash2(context, stateMachine, char, charCode) {
2572    if (charCode === 47 /* Char.Slash */ /* '/' */) {
2573        // 3rd slash, must be an absolute path (`path-absolute` in the
2574        // ABNF), such as in "file:///c:/windows/etc". See
2575        // https://tools.ietf.org/html/rfc3986#appendix-A
2576        stateMachine.state = 10 /* State.Path */;
2577        stateMachine.acceptStateReached = true;
2578    }
2579    else if (isDomainLabelStartChar(charCode)) {
2580        // start of "authority" section - see https://tools.ietf.org/html/rfc3986#appendix-A
2581        stateMachine.state = 5 /* State.DomainLabelChar */;
2582        stateMachine.acceptStateReached = true;
2583    }
2584    else {
2585        // not valid
2586        context.removeMachine(stateMachine);
2587    }
2588}
2589// Handles after we've read a '/' from the NonUrl state
2590function stateProtocolRelativeSlash1(context, stateMachine, charCode) {
2591    if (charCode === 47 /* Char.Slash */ /* '/' */) {
2592        stateMachine.state = 12 /* State.ProtocolRelativeSlash2 */;
2593    }
2594    else {
2595        // Anything else, cannot be the start of a protocol-relative
2596        // URL.
2597        context.removeMachine(stateMachine);
2598    }
2599}
2600// Handles after we've read a second '/', which could start a protocol-relative URL
2601function stateProtocolRelativeSlash2(context, stateMachine, charCode) {
2602    if (isDomainLabelStartChar(charCode)) {
2603        stateMachine.state = 5 /* State.DomainLabelChar */;
2604    }
2605    else {
2606        // Anything else, not a URL
2607        context.removeMachine(stateMachine);
2608    }
2609}
2610// Handles when we have read a domain label character
2611function stateDomainLabelChar(context, stateMachine, charCode) {
2612    if (charCode === 46 /* Char.Dot */ /* '.' */) {
2613        stateMachine.state = 7 /* State.DomainDot */;
2614    }
2615    else if (charCode === 45 /* Char.Dash */ /* '-' */) {
2616        stateMachine.state = 6 /* State.DomainHyphen */;
2617    }
2618    else if (charCode === 58 /* Char.Colon */ /* ':' */) {
2619        // Beginning of a port number, end the domain name
2620        stateMachine.state = 8 /* State.PortColon */;
2621    }
2622    else if (isUrlSuffixStartChar(charCode)) {
2623        // '/', '?', or '#'
2624        stateMachine.state = 10 /* State.Path */;
2625    }
2626    else if (isDomainLabelChar(charCode)) ;
2627    else {
2628        // Anything else, end the domain name
2629        captureMatchIfValidAndRemove(context, stateMachine);
2630    }
2631}
2632function stateDomainHyphen(context, stateMachine, char, charCode) {
2633    if (charCode === 45 /* Char.Dash */ /* '-' */) ;
2634    else if (charCode === 46 /* Char.Dot */ /* '.' */) {
2635        // Not valid to have a '-.' in a domain label
2636        captureMatchIfValidAndRemove(context, stateMachine);
2637    }
2638    else if (isDomainLabelStartChar(charCode)) {
2639        stateMachine.state = 5 /* State.DomainLabelChar */;
2640    }
2641    else {
2642        captureMatchIfValidAndRemove(context, stateMachine);
2643    }
2644}
2645function stateDomainDot(context, stateMachine, char, charCode) {
2646    if (charCode === 46 /* Char.Dot */ /* '.' */) {
2647        // domain names cannot have multiple '.'s next to each other.
2648        // It's possible we've already read a valid domain name though,
2649        // and that the '..' sequence just forms an ellipsis at the end
2650        // of a sentence
2651        captureMatchIfValidAndRemove(context, stateMachine);
2652    }
2653    else if (isDomainLabelStartChar(charCode)) {
2654        stateMachine.state = 5 /* State.DomainLabelChar */;
2655        stateMachine.acceptStateReached = true; // after hitting a dot, and then another domain label, we've reached an accept state
2656    }
2657    else {
2658        // Anything else, end the domain name
2659        captureMatchIfValidAndRemove(context, stateMachine);
2660    }
2661}
2662function stateIpV4Digit(context, stateMachine, charCode) {
2663    if (charCode === 46 /* Char.Dot */ /* '.' */) {
2664        stateMachine.state = 14 /* State.IpV4Dot */;
2665    }
2666    else if (charCode === 58 /* Char.Colon */ /* ':' */) {
2667        // Beginning of a port number
2668        stateMachine.state = 8 /* State.PortColon */;
2669    }
2670    else if (isDigitChar(charCode)) ;
2671    else if (isUrlSuffixStartChar(charCode)) {
2672        stateMachine.state = 10 /* State.Path */;
2673    }
2674    else if (isAlphaNumericOrMarkChar(charCode)) {
2675        // If we hit an alpha character, must not be an IPv4
2676        // Example of this: 1.2.3.4abc
2677        context.removeMachine(stateMachine);
2678    }
2679    else {
2680        captureMatchIfValidAndRemove(context, stateMachine);
2681    }
2682}
2683function stateIpV4Dot(context, stateMachine, charCode) {
2684    if (isDigitChar(charCode)) {
2685        stateMachine.octetsEncountered++;
2686        // Once we have encountered 4 octets, it's *potentially* a valid
2687        // IPv4 address. Our IPv4 regex will confirm the match later
2688        // though to make sure each octet is in the 0-255 range, and
2689        // there's exactly 4 octets (not 5 or more)
2690        if (stateMachine.octetsEncountered === 4) {
2691            stateMachine.acceptStateReached = true;
2692        }
2693        stateMachine.state = 13 /* State.IpV4Digit */;
2694    }
2695    else {
2696        captureMatchIfValidAndRemove(context, stateMachine);
2697    }
2698}
2699function statePortColon(context, stateMachine, charCode) {
2700    if (isDigitChar(charCode)) {
2701        stateMachine.state = 9 /* State.PortNumber */;
2702    }
2703    else {
2704        captureMatchIfValidAndRemove(context, stateMachine);
2705    }
2706}
2707function statePortNumber(context, stateMachine, charCode) {
2708    if (isDigitChar(charCode)) ;
2709    else if (isUrlSuffixStartChar(charCode)) {
2710        // '/', '?', or '#'
2711        stateMachine.state = 10 /* State.Path */;
2712    }
2713    else {
2714        captureMatchIfValidAndRemove(context, stateMachine);
2715    }
2716}
2717function statePath(context, stateMachine, charCode) {
2718    if (isPathChar(charCode)) ;
2719    else {
2720        captureMatchIfValidAndRemove(context, stateMachine);
2721    }
2722}
2723// Handles if we're reading a 'mailto:' prefix on the string
2724function stateEmailMailto_M(context, stateMachine, char, charCode) {
2725    if (char.toLowerCase() === 'a') {
2726        stateMachine.state = 16 /* State.EmailMailto_A */;
2727    }
2728    else {
2729        stateEmailLocalPart(context, stateMachine, charCode);
2730    }
2731}
2732function stateEmailMailto_A(context, stateMachine, char, charCode) {
2733    if (char.toLowerCase() === 'i') {
2734        stateMachine.state = 17 /* State.EmailMailto_I */;
2735    }
2736    else {
2737        stateEmailLocalPart(context, stateMachine, charCode);
2738    }
2739}
2740function stateEmailMailto_I(context, stateMachine, char, charCode) {
2741    if (char.toLowerCase() === 'l') {
2742        stateMachine.state = 18 /* State.EmailMailto_L */;
2743    }
2744    else {
2745        stateEmailLocalPart(context, stateMachine, charCode);
2746    }
2747}
2748function stateEmailMailto_L(context, stateMachine, char, charCode) {
2749    if (char.toLowerCase() === 't') {
2750        stateMachine.state = 19 /* State.EmailMailto_T */;
2751    }
2752    else {
2753        stateEmailLocalPart(context, stateMachine, charCode);
2754    }
2755}
2756function stateEmailMailto_T(context, stateMachine, char, charCode) {
2757    if (char.toLowerCase() === 'o') {
2758        stateMachine.state = 20 /* State.EmailMailto_O */;
2759    }
2760    else {
2761        stateEmailLocalPart(context, stateMachine, charCode);
2762    }
2763}
2764function stateEmailMailto_O(context, stateMachine, charCode) {
2765    if (charCode === 58 /* Char.Colon */ /* ':' */) {
2766        stateMachine.state = 21 /* State.EmailMailto_Colon */;
2767    }
2768    else {
2769        stateEmailLocalPart(context, stateMachine, charCode);
2770    }
2771}
2772function stateEmailMailtoColon(context, stateMachine, charCode) {
2773    if (isEmailLocalPartChar(charCode)) {
2774        stateMachine.state = 22 /* State.EmailLocalPart */;
2775    }
2776    else {
2777        context.removeMachine(stateMachine);
2778    }
2779}
2780// Handles the state when we're currently in the "local part" of an
2781// email address (as opposed to the "domain part")
2782function stateEmailLocalPart(context, stateMachine, charCode) {
2783    if (charCode === 46 /* Char.Dot */ /* '.' */) {
2784        stateMachine.state = 23 /* State.EmailLocalPartDot */;
2785    }
2786    else if (charCode === 64 /* Char.AtSign */ /* '@' */) {
2787        stateMachine.state = 24 /* State.EmailAtSign */;
2788    }
2789    else if (isEmailLocalPartChar(charCode)) {
2790        // stay in the "local part" of the email address
2791        // Note: because stateEmailLocalPart() is called from the
2792        // 'mailto' states (when the 'mailto' prefix itself has been
2793        // broken), make sure to set the state to EmailLocalPart
2794        stateMachine.state = 22 /* State.EmailLocalPart */;
2795    }
2796    else {
2797        // not an email address character
2798        context.removeMachine(stateMachine);
2799    }
2800}
2801// Handles the state where we've read a '.' character in the local part of
2802// the email address (i.e. the part before the '@' character)
2803function stateEmailLocalPartDot(context, stateMachine, charCode) {
2804    if (charCode === 46 /* Char.Dot */ /* '.' */) {
2805        // We read a second '.' in a row, not a valid email address
2806        // local part
2807        context.removeMachine(stateMachine);
2808    }
2809    else if (charCode === 64 /* Char.AtSign */ /* '@' */) {
2810        // We read the '@' character immediately after a dot ('.'), not
2811        // an email address
2812        context.removeMachine(stateMachine);
2813    }
2814    else if (isEmailLocalPartChar(charCode)) {
2815        stateMachine.state = 22 /* State.EmailLocalPart */;
2816    }
2817    else {
2818        // Anything else, not an email address
2819        context.removeMachine(stateMachine);
2820    }
2821}
2822function stateEmailAtSign(context, stateMachine, charCode) {
2823    if (isDomainLabelStartChar(charCode)) {
2824        stateMachine.state = 25 /* State.EmailDomainChar */;
2825    }
2826    else {
2827        // Anything else, not an email address
2828        context.removeMachine(stateMachine);
2829    }
2830}
2831function stateEmailDomainChar(context, stateMachine, charCode) {
2832    if (charCode === 46 /* Char.Dot */ /* '.' */) {
2833        stateMachine.state = 27 /* State.EmailDomainDot */;
2834    }
2835    else if (charCode === 45 /* Char.Dash */ /* '-' */) {
2836        stateMachine.state = 26 /* State.EmailDomainHyphen */;
2837    }
2838    else if (isDomainLabelChar(charCode)) ;
2839    else {
2840        // Anything else, we potentially matched if the criteria has
2841        // been met
2842        captureMatchIfValidAndRemove(context, stateMachine);
2843    }
2844}
2845function stateEmailDomainHyphen(context, stateMachine, charCode) {
vendor: 6,853 bytes, lines 2846-3020
2846    if (charCode === 45 /* Char.Dash */ /* '-' */ || charCode === 46 /* Char.Dot */ /* '.' */) {
2847        // Not valid to have two hyphens ("--") or hypen+dot ("-.")
2848        captureMatchIfValidAndRemove(context, stateMachine);
2849    }
2850    else if (isDomainLabelChar(charCode)) {
2851        stateMachine.state = 25 /* State.EmailDomainChar */;
2852    }
2853    else {
2854        // Anything else
2855        captureMatchIfValidAndRemove(context, stateMachine);
2856    }
2857}
2858function stateEmailDomainDot(context, stateMachine, charCode) {
2859    if (charCode === 46 /* Char.Dot */ /* '.' */ || charCode === 45 /* Char.Dash */ /* '-' */) {
2860        // not valid to have two dots ("..") or dot+hypen (".-")
2861        captureMatchIfValidAndRemove(context, stateMachine);
2862    }
2863    else if (isDomainLabelStartChar(charCode)) {
2864        stateMachine.state = 25 /* State.EmailDomainChar */;
2865        // After having read a '.' and then a valid domain character,
2866        // we now know that the domain part of the email is valid, and
2867        // we have found at least a partial EmailMatch (however, the
2868        // email address may have additional characters from this point)
2869        stateMachine.acceptStateReached = true;
2870    }
2871    else {
2872        // Anything else
2873        captureMatchIfValidAndRemove(context, stateMachine);
2874    }
2875}
2876// Handles the state when we've just encountered a '#' character
2877function stateHashtagHashChar(context, stateMachine, charCode) {
2878    if (isHashtagTextChar(charCode)) {
2879        // '#' char with valid hash text char following
2880        stateMachine.state = 29 /* State.HashtagTextChar */;
2881        stateMachine.acceptStateReached = true;
2882    }
2883    else {
2884        context.removeMachine(stateMachine);
2885    }
2886}
2887// Handles the state when we're currently in the hash tag's text chars
2888function stateHashtagTextChar(context, stateMachine, charCode) {
2889    if (isHashtagTextChar(charCode)) ;
2890    else {
2891        captureMatchIfValidAndRemove(context, stateMachine);
2892    }
2893}
2894// Handles the state when we've just encountered a '@' character
2895function stateMentionAtChar(context, stateMachine, charCode) {
2896    if (isMentionTextChar(charCode)) {
2897        // '@' char with valid mention text char following
2898        stateMachine.state = 31 /* State.MentionTextChar */;
2899        stateMachine.acceptStateReached = true;
2900    }
2901    else {
2902        context.removeMachine(stateMachine);
2903    }
2904}
2905// Handles the state when we're currently in the mention's text chars
2906function stateMentionTextChar(context, stateMachine, charCode) {
2907    if (isMentionTextChar(charCode)) ;
2908    else if (isAlphaNumericOrMarkChar(charCode)) {
2909        // Char is invalid for a mention text char, not a valid match.
2910        // Note that ascii alphanumeric chars are okay (which are tested
2911        // in the previous 'if' statement, but others are not)
2912        context.removeMachine(stateMachine);
2913    }
2914    else {
2915        captureMatchIfValidAndRemove(context, stateMachine);
2916    }
2917}
2918function statePhoneNumberPlus(context, stateMachine, char, charCode) {
2919    if (isDigitChar(charCode)) {
2920        stateMachine.state = 38 /* State.PhoneNumberDigit */;
2921    }
2922    else {
2923        context.removeMachine(stateMachine);
2924        // This character may start a new match. Add states for it
2925        stateNoMatch(context, char, charCode);
2926    }
2927}
2928function statePhoneNumberOpenParen(context, stateMachine, char, charCode) {
2929    if (isDigitChar(charCode)) {
2930        stateMachine.state = 33 /* State.PhoneNumberAreaCodeDigit1 */;
2931    }
2932    else {
2933        context.removeMachine(stateMachine);
2934    }
2935    // It's also possible that the paren was just an open brace for
2936    // a piece of text. Start other machines
2937    stateNoMatch(context, char, charCode);
2938}
2939function statePhoneNumberAreaCodeDigit1(context, stateMachine, charCode) {
2940    if (isDigitChar(charCode)) {
2941        stateMachine.state = 34 /* State.PhoneNumberAreaCodeDigit2 */;
2942    }
2943    else {
2944        context.removeMachine(stateMachine);
2945    }
2946}
2947function statePhoneNumberAreaCodeDigit2(context, stateMachine, charCode) {
2948    if (isDigitChar(charCode)) {
2949        stateMachine.state = 35 /* State.PhoneNumberAreaCodeDigit3 */;
2950    }
2951    else {
2952        context.removeMachine(stateMachine);
2953    }
2954}
2955function statePhoneNumberAreaCodeDigit3(context, stateMachine, charCode) {
2956    if (charCode === 41 /* Char.CloseParen */ /* ')' */) {
2957        stateMachine.state = 36 /* State.PhoneNumberCloseParen */;
2958    }
2959    else {
2960        context.removeMachine(stateMachine);
2961    }
2962}
2963function statePhoneNumberCloseParen(context, stateMachine, char, charCode) {
2964    if (isDigitChar(charCode)) {
2965        stateMachine.state = 38 /* State.PhoneNumberDigit */;
2966    }
2967    else if (isPhoneNumberSeparatorChar(charCode)) {
2968        stateMachine.state = 39 /* State.PhoneNumberSeparator */;
2969    }
2970    else {
2971        context.removeMachine(stateMachine);
2972    }
2973}
2974function statePhoneNumberDigit(context, stateMachine, char, charCode) {
2975    var charIdx = context.charIdx;
2976    // For now, if we've reached any digits, we'll say that the machine
2977    // has reached its accept state. The phone regex will confirm the
2978    // match later.
2979    // Alternatively, we could count the number of digits to avoid
2980    // invoking the phone number regex
2981    stateMachine.acceptStateReached = true;
2982    if (isPhoneNumberControlChar(charCode)) {
2983        stateMachine.state = 40 /* State.PhoneNumberControlChar */;
2984    }
2985    else if (charCode === 35 /* Char.NumberSign */ /* '#' */) {
2986        stateMachine.state = 41 /* State.PhoneNumberPoundChar */;
2987    }
2988    else if (isDigitChar(charCode)) ;
2989    else if (charCode === 40 /* Char.OpenParen */ /* '(' */) {
2990        stateMachine.state = 32 /* State.PhoneNumberOpenParen */;
2991    }
2992    else if (isPhoneNumberSeparatorChar(charCode)) {
2993        stateMachine.state = 39 /* State.PhoneNumberSeparator */;
2994    }
2995    else {
2996        captureMatchIfValidAndRemove(context, stateMachine);
2997        // The transition from a digit character to a letter can be the
2998        // start of a new scheme URL match
2999        if (isSchemeStartChar(charCode)) {
3000            context.addMachine(createSchemeUrlStateMachine(charIdx, 0 /* State.SchemeChar */));
3001        }
3002    }
3003}
3004function statePhoneNumberSeparator(context, stateMachine, char, charCode) {
3005    if (isDigitChar(charCode)) {
3006        stateMachine.state = 38 /* State.PhoneNumberDigit */;
3007    }
3008    else if (charCode === 40 /* Char.OpenParen */ /* '(' */) {
3009        stateMachine.state = 32 /* State.PhoneNumberOpenParen */;
3010    }
3011    else {
3012        captureMatchIfValidAndRemove(context, stateMachine);
3013        // This character may start a new match. Add states for it
3014        stateNoMatch(context, char, charCode);
3015    }
3016}
3017// The ";" characters is "wait" in a phone number
3018// The "," characters is "pause" in a phone number
3019function statePhoneNumberControlChar(context, stateMachine, charCode) {
3020    if (isPhoneNumberControlChar(charCode)) ;
vendor: 9,602 bytes, lines 3020-3238
3020
3021    else if (charCode === 35 /* Char.NumberSign */ /* '#' */) {
3022        stateMachine.state = 41 /* State.PhoneNumberPoundChar */;
3023    }
3024    else if (isDigitChar(charCode)) {
3025        stateMachine.state = 38 /* State.PhoneNumberDigit */;
3026    }
3027    else {
3028        captureMatchIfValidAndRemove(context, stateMachine);
3029    }
3030}
3031// The "#" characters is "pound" in a phone number
3032function statePhoneNumberPoundChar(context, stateMachine, charCode) {
3033    if (isPhoneNumberControlChar(charCode)) {
3034        stateMachine.state = 40 /* State.PhoneNumberControlChar */;
3035    }
3036    else if (isDigitChar(charCode)) {
3037        // According to some of the older tests, if there's a digit
3038        // after a '#' sign, the match is invalid. TODO: Revisit if this is true
3039        context.removeMachine(stateMachine);
3040    }
3041    else {
3042        captureMatchIfValidAndRemove(context, stateMachine);
3043    }
3044}
3045/*
3046 * Captures a match if it is valid (i.e. has a full domain name for a
3047 * TLD match). If a match is not valid, it is possible that we want to
3048 * keep reading characters in order to make a full match.
3049 */
3050function captureMatchIfValidAndRemove(context, stateMachine) {
3051    var matches = context.matches, text = context.text, charIdx = context.charIdx, tagBuilder = context.tagBuilder, stripPrefix = context.stripPrefix, stripTrailingSlash = context.stripTrailingSlash, decodePercentEncoding = context.decodePercentEncoding, hashtagServiceName = context.hashtagServiceName, mentionServiceName = context.mentionServiceName;
3052    // Remove the state machine first. There are a number of code paths
3053    // which return out of this function early, so make sure we have
3054    // this done
3055    context.removeMachine(stateMachine);
3056    // Make sure the state machine being checked has actually reached an
3057    // "accept" state. If it hasn't reach one, it can't be a match
3058    if (!stateMachine.acceptStateReached) {
3059        return;
3060    }
3061    var startIdx = stateMachine.startIdx;
3062    var matchedText = text.slice(stateMachine.startIdx, charIdx);
3063    // Handle any unbalanced braces (parens, square brackets, or curly
3064    // brackets) inside the URL. This handles situations like:
3065    //     The link (google.com)
3066    // and
3067    //     Check out this link here (en.wikipedia.org/wiki/IANA_(disambiguation))
3068    //
3069    // And also remove any punctuation chars at the end such as:
3070    //     '?', ',', ':', '.', etc.
3071    matchedText = excludeUnbalancedTrailingBracesAndPunctuation(matchedText);
3072    switch (stateMachine.type) {
3073        case 0 /* StateMachineType.Url */: {
3074            // We don't want to accidentally match a URL that is preceded by an
3075            // '@' character, which would be an email address
3076            var charBeforeUrlMatch = text.charCodeAt(stateMachine.startIdx - 1);
3077            if (charBeforeUrlMatch === 64 /* Char.AtSign */ /* '@' */) {
3078                return;
3079            }
3080            switch (stateMachine.matchType) {
3081                case 0 /* UrlStateMachineMatchType.Scheme */: {
3082                    // Autolinker accepts many characters in a url's scheme (like `fake://test.com`).
3083                    // However, in cases where a URL is missing whitespace before an obvious link,
3084                    // (for example: `nowhitespacehttp://www.test.com`), we only want the match to start
3085                    // at the http:// part. We will check if the match contains a common scheme and then
3086                    // shift the match to start from there.
3087                    var httpSchemeMatch = httpSchemeRe.exec(matchedText);
3088                    if (httpSchemeMatch) {
3089                        // If we found an overmatched URL, we want to find the index
3090                        // of where the match should start and shift the match to
3091                        // start from the beginning of the common scheme
3092                        startIdx = startIdx + httpSchemeMatch.index;
3093                        matchedText = matchedText.slice(httpSchemeMatch.index);
3094                    }
3095                    if (!isValidSchemeUrl(matchedText)) {
3096                        return; // not a valid match
3097                    }
3098                    break;
3099                }
3100                case 1 /* UrlStateMachineMatchType.Tld */: {
3101                    if (!isValidTldMatch(matchedText)) {
3102                        return; // not a valid match
3103                    }
3104                    break;
3105                }
3106                case 2 /* UrlStateMachineMatchType.IpV4 */: {
3107                    if (!isValidIpV4Address(matchedText)) {
3108                        return; // not a valid match
3109                    }
3110                    break;
3111                }
3112                /* istanbul ignore next */
3113                default:
3114                    assertNever(stateMachine);
3115            }
3116            matches.push(new UrlMatch({
3117                tagBuilder: tagBuilder,
3118                matchedText: matchedText,
3119                offset: startIdx,
3120                urlMatchType: toUrlMatchType(stateMachine.matchType),
3121                url: matchedText,
3122                protocolRelativeMatch: matchedText.slice(0, 2) === '//',
3123                // TODO: Do these settings need to be passed to the match,
3124                // or should we handle them here in UrlMatcher?
3125                stripPrefix: stripPrefix,
3126                stripTrailingSlash: stripTrailingSlash,
3127                decodePercentEncoding: decodePercentEncoding,
3128            }));
3129            break;
3130        }
3131        case 1 /* StateMachineType.Email */: {
3132            // if the email address has a valid TLD, add it to the list of matches
3133            if (isValidEmail(matchedText)) {
3134                matches.push(new EmailMatch({
3135                    tagBuilder: tagBuilder,
3136                    matchedText: matchedText,
3137                    offset: startIdx,
3138                    email: matchedText.replace(mailtoSchemePrefixRe, ''),
3139                }));
3140            }
3141            break;
3142        }
3143        case 2 /* StateMachineType.Hashtag */: {
3144            if (isValidHashtag(matchedText)) {
3145                matches.push(new HashtagMatch({
3146                    tagBuilder: tagBuilder,
3147                    matchedText: matchedText,
3148                    offset: startIdx,
3149                    serviceName: hashtagServiceName,
3150                    hashtag: matchedText.slice(1),
3151                }));
3152            }
3153            break;
3154        }
3155        case 3 /* StateMachineType.Mention */: {
3156            if (isValidMention(matchedText, mentionServiceName)) {
3157                matches.push(new MentionMatch({
3158                    tagBuilder: tagBuilder,
3159                    matchedText: matchedText,
3160                    offset: startIdx,
3161                    serviceName: mentionServiceName,
3162                    mention: matchedText.slice(1), // strip off the '@' character at the beginning
3163                }));
3164            }
3165            break;
3166        }
3167        case 4 /* StateMachineType.Phone */: {
3168            // remove any trailing spaces that were considered as "separator"
3169            // chars by the state machine
3170            matchedText = matchedText.replace(/ +$/g, '');
3171            if (isValidPhoneNumber(matchedText)) {
3172                var cleanNumber = matchedText.replace(/[^0-9,;#]/g, ''); // strip out non-digit characters exclude comma semicolon and #
3173                matches.push(new PhoneMatch({
3174                    tagBuilder: tagBuilder,
3175                    matchedText: matchedText,
3176                    offset: startIdx,
3177                    number: cleanNumber,
3178                    plusSign: matchedText.charAt(0) === '+',
3179                }));
3180            }
3181            break;
3182        }
3183        /* istanbul ignore next */
3184        default:
3185            assertNever(stateMachine);
3186    }
3187}
3188/**
3189 * Helper function to convert a UrlStateMachineMatchType value to its
3190 * UrlMatchType equivalent.
3191 */
3192function toUrlMatchType(stateMachineMatchType) {
3193    switch (stateMachineMatchType) {
3194        case 0 /* UrlStateMachineMatchType.Scheme */:
3195            return 'scheme';
3196        case 1 /* UrlStateMachineMatchType.Tld */:
3197            return 'tld';
3198        case 2 /* UrlStateMachineMatchType.IpV4 */:
3199            return 'ipV4';
3200        /* istanbul ignore next */
3201        default:
3202            assertNever(stateMachineMatchType);
3203    }
3204}
3205var oppositeBrace = {
3206    ')': '(',
3207    '}': '{',
3208    ']': '[',
3209};
3210/**
3211 * Determines if a match found has unmatched closing parenthesis,
3212 * square brackets or curly brackets. If so, these unbalanced symbol(s) will be
3213 * removed from the URL match itself.
3214 *
3215 * A match may have an extra closing parenthesis/square brackets/curly brackets
3216 * at the end of the match because these are valid URL path characters. For
3217 * example, "wikipedia.com/something_(disambiguation)" should be auto-linked.
3218 *
3219 * However, an extra parenthesis *will* be included when the URL itself is
3220 * wrapped in parenthesis, such as in the case of:
3221 *
3222 *     "(wikipedia.com/something_(disambiguation))"
3223 *
3224 * In this case, the last closing parenthesis should *not* be part of the
3225 * URL itself, and this method will exclude it from the returned URL.
3226 *
3227 * For square brackets in URLs such as in PHP arrays, the same behavior as
3228 * parenthesis discussed above should happen:
3229 *
3230 *     "[http://www.example.com/foo.php?bar[]=1&bar[]=2&bar[]=3]"
3231 *
3232 * The very last closing square bracket should not be part of the URL itself,
3233 * and therefore this method will remove it.
3234 *
3235 * @param matchedText The full matched URL/email/hashtag/etc. from the state
3236 *   machine parser.
3237 * @return The updated matched text with extraneous suffix characters removed.
3238 */
3239function excludeUnbalancedTrailingBracesAndPunctuation(matchedText) {
3240    var braceCounts = {
3241        '(': 0,
3242        '{': 0,
3243        '[': 0,
3244    };
3245    for (var i = 0; i < matchedText.length; i++) {
3246        var char = matchedText.charAt(i);
vendor: 4,685 bytes, lines 3247-3386
3247        var charCode = matchedText.charCodeAt(i);
3248        if (isOpenBraceChar(charCode)) {
3249            braceCounts[char]++;
3250        }
3251        else if (isCloseBraceChar(charCode)) {
3252            braceCounts[oppositeBrace[char]]--;
3253        }
3254    }
3255    var endIdx = matchedText.length - 1;
3256    while (endIdx >= 0) {
3257        var char = matchedText.charAt(endIdx);
3258        var charCode = matchedText.charCodeAt(endIdx);
3259        if (isCloseBraceChar(charCode)) {
3260            var oppositeBraceChar = oppositeBrace[char];
3261            if (braceCounts[oppositeBraceChar] < 0) {
3262                braceCounts[oppositeBraceChar]++;
3263                endIdx--;
3264            }
3265            else {
3266                break;
3267            }
3268        }
3269        else if (isUrlSuffixNotAllowedAsFinalChar(charCode)) {
3270            // Walk back a punctuation char like '?', ',', ':', '.', etc.
3271            endIdx--;
3272        }
3273        else {
3274            break;
3275        }
3276    }
3277    return matchedText.slice(0, endIdx + 1);
3278}
3279function createSchemeUrlStateMachine(startIdx, state) {
3280    return {
3281        type: 0 /* StateMachineType.Url */,
3282        startIdx: startIdx,
3283        state: state,
3284        acceptStateReached: false,
3285        matchType: 0 /* UrlStateMachineMatchType.Scheme */,
3286    };
3287}
3288function createTldUrlStateMachine(startIdx, state) {
3289    return {
3290        type: 0 /* StateMachineType.Url */,
3291        startIdx: startIdx,
3292        state: state,
3293        acceptStateReached: false,
3294        matchType: 1 /* UrlStateMachineMatchType.Tld */,
3295    };
3296}
3297function createIpV4UrlStateMachine(startIdx, state) {
3298    return {
3299        type: 0 /* StateMachineType.Url */,
3300        startIdx: startIdx,
3301        state: state,
3302        acceptStateReached: false,
3303        matchType: 2 /* UrlStateMachineMatchType.IpV4 */,
3304        octetsEncountered: 1, // starts at 1 because we create this machine when encountering the first octet
3305    };
3306}
3307function createEmailStateMachine(startIdx, state) {
3308    return {
3309        type: 1 /* StateMachineType.Email */,
3310        startIdx: startIdx,
3311        state: state,
3312        acceptStateReached: false,
3313    };
3314}
3315function createHashtagStateMachine(startIdx, state) {
3316    return {
3317        type: 2 /* StateMachineType.Hashtag */,
3318        startIdx: startIdx,
3319        state: state,
3320        acceptStateReached: false,
3321    };
3322}
3323function createMentionStateMachine(startIdx, state) {
3324    return {
3325        type: 3 /* StateMachineType.Mention */,
3326        startIdx: startIdx,
3327        state: state,
3328        acceptStateReached: false,
3329    };
3330}
3331function createPhoneNumberStateMachine(startIdx, state) {
3332    return {
3333        type: 4 /* StateMachineType.Phone */,
3334        startIdx: startIdx,
3335        state: state,
3336        acceptStateReached: false,
3337    };
3338}
3339function isSchemeUrlStateMachine(machine) {
3340    return (machine.type === 0 /* StateMachineType.Url */ &&
3341        machine.matchType === 0 /* UrlStateMachineMatchType.Scheme */);
3342}
3343
3344// For debugging: search for other "For debugging" lines
3345// import CliTable from 'cli-table';
3346var CurrentTag = /** @class */ (function () {
3347    function CurrentTag(cfg) {
3348        if (cfg === void 0) { cfg = {}; }
3349        this.idx = cfg.idx !== undefined ? cfg.idx : -1;
3350        this.type = cfg.type || 'tag';
3351        this.name = cfg.name || '';
3352        this.isOpening = !!cfg.isOpening;
3353        this.isClosing = !!cfg.isClosing;
3354    }
3355    return CurrentTag;
3356}());
3357var noCurrentTag = new CurrentTag(); // shared reference for when there is no current tag currently being read
3358/**
3359 * Context object containing all the state needed by the HTML parsing state
3360 * machine function.
3361 *
3362 * ## Historical note
3363 *
3364 * In v4.1.5, we used nested functions to handle the context via closures, but
3365 * this necessitated re-creating the functions for each call to `parseHtml()`,
3366 * which made them difficult for v8 to JIT optimize. In v4.1.6, we lifted all of
3367 * the functions to the top-level scope and passed the context object between
3368 * them, which allows the functions to be JIT compiled once and reused.
3369 */
3370var ParseHtmlContext = /** @class */ (function () {
3371    function ParseHtmlContext(html, callbacks) {
3372        this.charIdx = 0; // Current character index being processed
3373        this.state = 0 /* State.Data */; // begin in the Data state
3374        this.currentDataIdx = 0; // where the current data start index is
3375        this.currentTag = noCurrentTag; // describes the current tag that is being read
3376        this.html = html;
3377        this.callbacks = callbacks;
3378    }
3379    return ParseHtmlContext;
3380}());
3381/**
3382 * Parses an HTML string, calling the callbacks to notify of tags and text.
3383 *
3384 * ## History
3385 *
3386 * This file previously used a regular expression to find html tags in the input
3387 * text. Unfortunately, we ran into a bunch of catastrophic backtracking issues
3388 * with certain input text, causing Autolinker to either hang or just take a
3389 * really long time to parse the string.
3390 *
3391 * The current code is intended to be a O(n) algorithm that walks through
3392 * the string in one pass, and tries to be as cheap as possible. We don't need
3393 * to implement the full HTML spec, but rather simply determine where the string
3394 * looks like an HTML tag, and where it looks like text (so that we can autolink
3395 * that).
3396 *
3397 * This state machine parser is intended just to be a simple but performant
3398 * parser of HTML for the subset of requirements we have. We simply need to:
3399 *
3400 * 1. Determine where HTML tags are
3401 * 2. Determine the tag name (Autolinker specifically only cares about <a>,
3402 *    <script>, and <style> tags, so as not to link any text within them)
3403 *
3404 * We don't need to:
3405 *
3406 * 1. Create a parse tree
3407 * 2. Auto-close tags with invalid markup
3408 * 3. etc.
3409 *
3410 * The other intention behind this is that we didn't want to add external
3411 * dependencies on the Autolinker utility which would increase its size. For
3412 * instance, adding htmlparser2 adds 125kb to the minified output file,
3413 * increasing its final size from 47kb to 172kb (at the time of writing). It
3414 * also doesn't work exactly correctly, treating the string "<3 blah blah blah"
3415 * as an HTML tag.
3416 *
3417 * Reference for HTML spec:
3418 *
3419 *     https://www.w3.org/TR/html51/syntax.html#sec-tokenization
3420 *
3421 * @param {String} html The HTML to parse
3422 * @param {Object} callbacks
3423 * @param {Function} callbacks.onOpenTag Callback function to call when an open
3424 *   tag is parsed. Called with the tagName as its argument.
3425 * @param {Function} callbacks.onCloseTag Callback function to call when a close
3426 *   tag is parsed. Called with the tagName as its argument. If a self-closing
3427 *   tag is found, `onCloseTag` is called immediately after `onOpenTag`.
3428 * @param {Function} callbacks.onText Callback function to call when text (i.e
3429 *   not an HTML tag) is parsed. Called with the text (string) as its first
3430 *   argument, and offset (number) into the string as its second.
3431 */
3432function parseHtml(html, callbacks) {
3433    var context = new ParseHtmlContext(html, callbacks);
3434    // For debugging: search for other "For debugging" lines
3435    // const table = new CliTable( {
3436    // 	head: [ 'charIdx', 'char', 'state', 'currentDataIdx', 'currentOpenTagIdx', 'tag.type' ]
3437    // } );
3438    var len = html.length;
3439    while (context.charIdx < len) {
3440        var char = html.charAt(context.charIdx);
3441        var charCode = html.charCodeAt(context.charIdx);
3442        // For debugging: search for other "For debugging" lines
3443        // ALSO: Temporarily remove the 'const' keyword on the State enum
3444        // table.push([
3445        //     String(charIdx),
3446        //     char,
3447        //     State[state],
3448        //     String(currentDataIdx),
3449        //     String(currentTag.idx),
3450        //     currentTag.idx === -1 ? '' : currentTag.type
3451        // ]);
3452        switch (context.state) {
3453            case 0 /* State.Data */:
3454                stateData(context, char);
3455                break;
3456            case 1 /* State.TagOpen */:
3457                stateTagOpen(context, char, charCode);
3458                break;
3459            case 2 /* State.EndTagOpen */:
3460                stateEndTagOpen(context, char, charCode);
3461                break;
3462            case 3 /* State.TagName */:
3463                stateTagName(context, char, charCode);
3464                break;
3465            case 4 /* State.BeforeAttributeName */:
3466                stateBeforeAttributeName(context, char, charCode);
3467                break;
3468            case 5 /* State.AttributeName */:
3469                stateAttributeName(context, char, charCode);
3470                break;
3471            case 6 /* State.AfterAttributeName */:
3472                stateAfterAttributeName(context, char, charCode);
3473                break;
3474            case 7 /* State.BeforeAttributeValue */:
3475                stateBeforeAttributeValue(context, char, charCode);
3476                break;
3477            case 8 /* State.AttributeValueDoubleQuoted */:
3478                stateAttributeValueDoubleQuoted(context, char);
3479                break;
3480            case 9 /* State.AttributeValueSingleQuoted */:
3481                stateAttributeValueSingleQuoted(context, char);
3482                break;
3483            case 10 /* State.AttributeValueUnquoted */:
3484                stateAttributeValueUnquoted(context, char, charCode);
3485                break;
3486            case 11 /* State.AfterAttributeValueQuoted */:
3487                stateAfterAttributeValueQuoted(context, char, charCode);
3488                break;
3489            case 12 /* State.SelfClosingStartTag */:
3490                stateSelfClosingStartTag(context, char);
3491                break;
3492            case 13 /* State.MarkupDeclarationOpenState */:
3493                stateMarkupDeclarationOpen(context);
3494                break;
3495            case 14 /* State.CommentStart */:
3496                stateCommentStart(context, char);
3497                break;
3498            case 15 /* State.CommentStartDash */:
3499                stateCommentStartDash(context, char);
3500                break;
3501            case 16 /* State.Comment */:
3502                stateComment(context, char);
3503                break;
3504            case 17 /* State.CommentEndDash */:
3505                stateCommentEndDash(context, char);
3506                break;
3507            case 18 /* State.CommentEnd */:
3508                stateCommentEnd(context, char);
3509                break;
3510            case 19 /* State.CommentEndBang */:
3511                stateCommentEndBang(context, char);
3512                break;
3513            case 20 /* State.Doctype */:
3514                stateDoctype(context, char);
3515                break;
3516            /* istanbul ignore next */
3517            default:
3518                assertNever(context.state);
3519        }
3520        // For debugging: search for other "For debugging" lines
3521        // ALSO: Temporarily remove the 'const' keyword on the State enum
3522        // table.push([
3523        //     String(context.charIdx),
3524        //     char,
3525        //     State[context.state],
3526        //     String(context.currentDataIdx),
3527        //     String(context.currentTag.idx),
3528        //     context.currentTag.idx === -1 ? '' : context.currentTag.type
3529        // ]);
3530        context.charIdx++;
3531    }
3532    if (context.currentDataIdx < context.charIdx) {
3533        emitText(context);
3534    }
3535    // For debugging: search for other "For debugging" lines
3536    // console.log( '\n' + table.toString() );
3537}
3538// Called when non-tags are being read (i.e. the text around HTML †ags)
3539// https://www.w3.org/TR/html51/syntax.html#data-state
3540function stateData(context, char) {
3541    if (char === '<') {
3542        startNewTag(context);
3543    }
3544}
3545// Called after a '<' is read from the Data state
3546// https://www.w3.org/TR/html51/syntax.html#tag-open-state
3547function stateTagOpen(context, char, charCode) {
3548    if (char === '!') {
3549        context.state = 13 /* State.MarkupDeclarationOpenState */;
3550    }
3551    else if (char === '/') {
vendor: 17,431 bytes, lines 3552-3992
3552        context.state = 2 /* State.EndTagOpen */;
3553        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { isClosing: true }));
3554    }
3555    else if (char === '<') {
3556        // start of another tag (ignore the previous, incomplete one)
3557        startNewTag(context);
3558    }
3559    else if (isAsciiLetterChar(charCode)) {
3560        // tag name start (and no '/' read)
3561        context.state = 3 /* State.TagName */;
3562        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { isOpening: true }));
3563    }
3564    else {
3565        // Any other
3566        context.state = 0 /* State.Data */;
3567        context.currentTag = noCurrentTag;
3568    }
3569}
3570// After a '<x', '</x' sequence is read (where 'x' is a letter character),
3571// this is to continue reading the tag name
3572// https://www.w3.org/TR/html51/syntax.html#tag-name-state
3573function stateTagName(context, char, charCode) {
3574    if (isWhitespaceChar(charCode)) {
3575        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { name: captureTagName(context) }));
3576        context.state = 4 /* State.BeforeAttributeName */;
3577    }
3578    else if (char === '<') {
3579        // start of another tag (ignore the previous, incomplete one)
3580        startNewTag(context);
3581    }
3582    else if (char === '/') {
3583        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { name: captureTagName(context) }));
3584        context.state = 12 /* State.SelfClosingStartTag */;
3585    }
3586    else if (char === '>') {
3587        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { name: captureTagName(context) }));
3588        emitTagAndPreviousTextNode(context); // resets to Data state as well
3589    }
3590    else if (!isAsciiLetterChar(charCode) && !isDigitChar(charCode) && char !== ':') {
3591        // Anything else that does not form an html tag. Note: the colon
3592        // character is accepted for XML namespaced tags
3593        resetToDataState(context);
3594    }
3595    else ;
3596}
3597// Called after the '/' is read from a '</' sequence
3598// https://www.w3.org/TR/html51/syntax.html#end-tag-open-state
3599function stateEndTagOpen(context, char, charCode) {
3600    if (char === '>') {
3601        // parse error. Encountered "</>". Skip it without treating as a tag
3602        resetToDataState(context);
3603    }
3604    else if (isAsciiLetterChar(charCode)) {
3605        context.state = 3 /* State.TagName */;
3606    }
3607    else {
3608        // some other non-tag-like character, don't treat this as a tag
3609        resetToDataState(context);
3610    }
3611}
3612// https://www.w3.org/TR/html51/syntax.html#before-attribute-name-state
3613function stateBeforeAttributeName(context, char, charCode) {
3614    if (isWhitespaceChar(charCode)) ;
3615    else if (char === '/') {
3616        context.state = 12 /* State.SelfClosingStartTag */;
3617    }
3618    else if (char === '>') {
3619        emitTagAndPreviousTextNode(context); // resets to Data state as well
3620    }
3621    else if (char === '<') {
3622        // start of another tag (ignore the previous, incomplete one)
3623        startNewTag(context);
3624    }
3625    else if (char === "=" || isQuoteChar(charCode) || isControlChar(charCode)) {
3626        // "Parse error" characters that, according to the spec, should be
3627        // appended to the attribute name, but we'll treat these characters
3628        // as not forming a real HTML tag
3629        resetToDataState(context);
3630    }
3631    else {
3632        // Any other char, start of a new attribute name
3633        context.state = 5 /* State.AttributeName */;
3634    }
3635}
3636// https://www.w3.org/TR/html51/syntax.html#attribute-name-state
3637function stateAttributeName(context, char, charCode) {
3638    if (isWhitespaceChar(charCode)) {
3639        context.state = 6 /* State.AfterAttributeName */;
3640    }
3641    else if (char === '/') {
3642        context.state = 12 /* State.SelfClosingStartTag */;
3643    }
3644    else if (char === '=') {
3645        context.state = 7 /* State.BeforeAttributeValue */;
3646    }
3647    else if (char === '>') {
3648        emitTagAndPreviousTextNode(context); // resets to Data state as well
3649    }
3650    else if (char === '<') {
3651        // start of another tag (ignore the previous, incomplete one)
3652        startNewTag(context);
3653    }
3654    else if (isQuoteChar(charCode)) {
3655        // "Parse error" characters that, according to the spec, should be
3656        // appended to the attribute name, but we'll treat these characters
3657        // as not forming a real HTML tag
3658        resetToDataState(context);
3659    }
3660    else ;
3661}
3662// https://www.w3.org/TR/html51/syntax.html#after-attribute-name-state
3663function stateAfterAttributeName(context, char, charCode) {
3664    if (isWhitespaceChar(charCode)) ;
3665    else if (char === '/') {
3666        context.state = 12 /* State.SelfClosingStartTag */;
3667    }
3668    else if (char === '=') {
3669        context.state = 7 /* State.BeforeAttributeValue */;
3670    }
3671    else if (char === '>') {
3672        emitTagAndPreviousTextNode(context);
3673    }
3674    else if (char === '<') {
3675        // start of another tag (ignore the previous, incomplete one)
3676        startNewTag(context);
3677    }
3678    else if (isQuoteChar(charCode)) {
3679        // "Parse error" characters that, according to the spec, should be
3680        // appended to the attribute name, but we'll treat these characters
3681        // as not forming a real HTML tag
3682        resetToDataState(context);
3683    }
3684    else {
3685        // Any other character, start a new attribute in the current tag
3686        context.state = 5 /* State.AttributeName */;
3687    }
3688}
3689// https://www.w3.org/TR/html51/syntax.html#before-attribute-value-state
3690function stateBeforeAttributeValue(context, char, charCode) {
3691    if (isWhitespaceChar(charCode)) ;
3692    else if (char === "\"") {
3693        context.state = 8 /* State.AttributeValueDoubleQuoted */;
3694    }
3695    else if (char === "'") {
3696        context.state = 9 /* State.AttributeValueSingleQuoted */;
3697    }
3698    else if (/[>=`]/.test(char)) {
3699        // Invalid chars after an '=' for an attribute value, don't count
3700        // the current tag as an HTML tag
3701        resetToDataState(context);
3702    }
3703    else if (char === '<') {
3704        // start of another tag (ignore the previous, incomplete one)
3705        startNewTag(context);
3706    }
3707    else {
3708        // Any other character, consider it an unquoted attribute value
3709        context.state = 10 /* State.AttributeValueUnquoted */;
3710    }
3711}
3712// https://www.w3.org/TR/html51/syntax.html#attribute-value-double-quoted-state
3713function stateAttributeValueDoubleQuoted(context, char) {
3714    if (char === "\"") {
3715        // end the current double-quoted attribute
3716        context.state = 11 /* State.AfterAttributeValueQuoted */;
3717    }
3718}
3719// https://www.w3.org/TR/html51/syntax.html#attribute-value-single-quoted-state
3720function stateAttributeValueSingleQuoted(context, char) {
3721    if (char === "'") {
3722        // end the current single-quoted attribute
3723        context.state = 11 /* State.AfterAttributeValueQuoted */;
3724    }
3725}
3726// https://www.w3.org/TR/html51/syntax.html#attribute-value-unquoted-state
3727function stateAttributeValueUnquoted(context, char, charCode) {
3728    if (isWhitespaceChar(charCode)) {
3729        context.state = 4 /* State.BeforeAttributeName */;
3730    }
3731    else if (char === '>') {
3732        emitTagAndPreviousTextNode(context);
3733    }
3734    else if (char === '<') {
3735        // start of another tag (ignore the previous, incomplete one)
3736        startNewTag(context);
3737    }
3738    else ;
3739}
3740// Called after a double-quoted or single-quoted attribute value is read
3741// (i.e. after the closing quote character)
3742// https://www.w3.org/TR/html51/syntax.html#after-attribute-value-quoted-state
3743function stateAfterAttributeValueQuoted(context, char, charCode) {
3744    if (isWhitespaceChar(charCode)) {
3745        context.state = 4 /* State.BeforeAttributeName */;
3746    }
3747    else if (char === '/') {
3748        context.state = 12 /* State.SelfClosingStartTag */;
3749    }
3750    else if (char === '>') {
3751        emitTagAndPreviousTextNode(context);
3752    }
3753    else if (char === '<') {
3754        // start of another tag (ignore the previous, incomplete one)
3755        startNewTag(context);
3756    }
3757    else {
3758        // Any other character, "parse error". Spec says to switch to the
3759        // BeforeAttributeState and re-consume the character, as it may be
3760        // the start of a new attribute name
3761        context.state = 4 /* State.BeforeAttributeName */;
3762        reconsumeCurrentChar(context);
3763    }
3764}
3765// A '/' has just been read in the current tag (presumably for '/>'), and
3766// this handles the next character
3767// https://www.w3.org/TR/html51/syntax.html#self-closing-start-tag-state
3768function stateSelfClosingStartTag(context, char) {
3769    if (char === '>') {
3770        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { isClosing: true }));
3771        emitTagAndPreviousTextNode(context); // resets to Data state as well
3772    }
3773    else {
3774        // Note: the spec calls for a character after a '/' within a start
3775        // tag to go back into the BeforeAttributeName state (in order to
3776        // read more attributes, but for the purposes of Autolinker, this is
3777        // most likely not a valid HTML tag. For example: "<something / other>"
3778        // state = State.BeforeAttributeName;
3779        // Instead, just treat as regular text
3780        resetToDataState(context);
3781    }
3782}
3783// https://www.w3.org/TR/html51/syntax.html#markup-declaration-open-state
3784// (HTML Comments or !DOCTYPE)
3785function stateMarkupDeclarationOpen(context) {
3786    var html = context.html, charIdx = context.charIdx;
3787    if (html.slice(charIdx, charIdx + 2) === '--') {
3788        // html comment
3789        context.charIdx++; // "consume" the second '-' character. Next loop iteration will consume the character after the '<!--' sequence
3790        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { type: 'comment' }));
3791        context.state = 14 /* State.CommentStart */;
3792    }
3793    else if (html.slice(charIdx, charIdx + 7).toUpperCase() === 'DOCTYPE') {
3794        context.charIdx += 6; // "consume" the characters "OCTYPE" (the current loop iteraction consumed the 'D'). Next loop iteration will consume the character after the '<!DOCTYPE' sequence
3795        context.currentTag = new CurrentTag(__assign(__assign({}, context.currentTag), { type: 'doctype' }));
3796        context.state = 20 /* State.Doctype */;
3797    }
3798    else {
3799        // At this point, the spec specifies that the state machine should
3800        // enter the "bogus comment" state, in which case any character(s)
3801        // after the '<!' that were read should become an HTML comment up
3802        // until the first '>' that is read (or EOF). Instead, we'll assume
3803        // that a user just typed '<!' as part of some piece of non-html
3804        // text
3805        resetToDataState(context);
3806    }
3807}
3808// Handles after the sequence '<!--' has been read
3809// https://www.w3.org/TR/html51/syntax.html#comment-start-state
3810function stateCommentStart(context, char) {
3811    if (char === '-') {
3812        // We've read the sequence '<!---' at this point (3 dashes)
3813        context.state = 15 /* State.CommentStartDash */;
3814    }
3815    else if (char === '>') {
3816        // At this point, we'll assume the comment wasn't a real comment
3817        // so we'll just emit it as data. We basically read the sequence
3818        // '<!-->'
3819        resetToDataState(context);
3820    }
3821    else {
3822        // Any other char, take it as part of the comment
3823        context.state = 16 /* State.Comment */;
3824    }
3825}
3826// We've read the sequence '<!---' at this point (3 dashes)
3827// https://www.w3.org/TR/html51/syntax.html#comment-start-dash-state
3828function stateCommentStartDash(context, char) {
3829    if (char === '-') {
3830        // We've read '<!----' (4 dashes) at this point
3831        context.state = 18 /* State.CommentEnd */;
3832    }
3833    else if (char === '>') {
3834        // At this point, we'll assume the comment wasn't a real comment
3835        // so we'll just emit it as data. We basically read the sequence
3836        // '<!--->'
3837        resetToDataState(context);
3838    }
3839    else {
3840        // Anything else, take it as a valid comment
3841        context.state = 16 /* State.Comment */;
3842    }
3843}
3844// Currently reading the comment's text (data)
3845// https://www.w3.org/TR/html51/syntax.html#comment-state
3846function stateComment(context, char) {
3847    if (char === '-') {
3848        context.state = 17 /* State.CommentEndDash */;
3849    }
3850}
3851// When we we've read the first dash inside a comment, it may signal the
3852// end of the comment if we read another dash
3853// https://www.w3.org/TR/html51/syntax.html#comment-end-dash-state
3854function stateCommentEndDash(context, char) {
3855    if (char === '-') {
3856        context.state = 18 /* State.CommentEnd */;
3857    }
3858    else {
3859        // Wasn't a dash, must still be part of the comment
3860        context.state = 16 /* State.Comment */;
3861    }
3862}
3863// After we've read two dashes inside a comment, it may signal the end of
3864// the comment if we then read a '>' char
3865// https://www.w3.org/TR/html51/syntax.html#comment-end-state
3866function stateCommentEnd(context, char) {
3867    if (char === '>') {
3868        emitTagAndPreviousTextNode(context);
3869    }
3870    else if (char === '!') {
3871        context.state = 19 /* State.CommentEndBang */;
3872    }
3873    else if (char === '-') ;
3874    else {
3875        // Anything else, switch back to the comment state since we didn't
3876        // read the full "end comment" sequence (i.e. '-->')
3877        context.state = 16 /* State.Comment */;
3878    }
3879}
3880// We've read the sequence '--!' inside of a comment
3881// https://www.w3.org/TR/html51/syntax.html#comment-end-bang-state
3882function stateCommentEndBang(context, char) {
3883    if (char === '-') {
3884        // We read the sequence '--!-' inside of a comment. The last dash
3885        // could signify that the comment is going to close
3886        context.state = 17 /* State.CommentEndDash */;
3887    }
3888    else if (char === '>') {
3889        // End of comment with the sequence '--!>'
3890        emitTagAndPreviousTextNode(context);
3891    }
3892    else {
3893        // The '--!' was not followed by a '>', continue reading the
3894        // comment's text
3895        context.state = 16 /* State.Comment */;
3896    }
3897}
3898/**
3899 * For DOCTYPES in particular, we don't care about the attributes. Just
3900 * advance to the '>' character and emit the tag, unless we find a '<'
3901 * character in which case we'll start a new tag.
3902 *
3903 * Example doctype tag:
3904 *    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
3905 *
3906 * Actual spec: https://www.w3.org/TR/html51/syntax.html#doctype-state
3907 */
3908function stateDoctype(context, char) {
3909    if (char === '>') {
3910        emitTagAndPreviousTextNode(context);
3911    }
3912    else if (char === '<') {
3913        startNewTag(context);
3914    }
3915    else ;
3916}
3917/**
3918 * Resets the state back to the Data state, and removes the current tag.
3919 *
3920 * We'll generally run this function whenever a "parse error" is
3921 * encountered, where the current tag that is being read no longer looks
3922 * like a real HTML tag.
3923 */
3924function resetToDataState(context) {
3925    context.state = 0 /* State.Data */;
3926    context.currentTag = noCurrentTag;
3927}
3928/**
3929 * Starts a new HTML tag at the current index, ignoring any previous HTML
3930 * tag that was being read.
3931 *
3932 * We'll generally run this function whenever we read a new '<' character,
3933 * including when we read a '<' character inside of an HTML tag that we were
3934 * previously reading.
3935 */
3936function startNewTag(context) {
3937    context.state = 1 /* State.TagOpen */;
3938    context.currentTag = new CurrentTag({ idx: context.charIdx });
3939}
3940/**
3941 * Once we've decided to emit an open tag, that means we can also emit the
3942 * text node before it.
3943 */
3944function emitTagAndPreviousTextNode(context) {
3945    var textBeforeTag = context.html.slice(context.currentDataIdx, context.currentTag.idx);
3946    if (textBeforeTag) {
3947        // the html tag was the first element in the html string, or two
3948        // tags next to each other, in which case we should not emit a text
3949        // node
3950        context.callbacks.onText(textBeforeTag, context.currentDataIdx);
3951    }
3952    var currentTag = context.currentTag;
3953    if (currentTag.type === 'comment') {
3954        context.callbacks.onComment(currentTag.idx);
3955    }
3956    else if (currentTag.type === 'doctype') {
3957        context.callbacks.onDoctype(currentTag.idx);
3958    }
3959    else {
3960        if (currentTag.isOpening) {
3961            context.callbacks.onOpenTag(currentTag.name, currentTag.idx);
3962        }
3963        if (currentTag.isClosing) {
3964            // note: self-closing tags will emit both opening and closing
3965            context.callbacks.onCloseTag(currentTag.name, currentTag.idx);
3966        }
3967    }
3968    // Since we just emitted a tag, reset to the data state for the next char
3969    resetToDataState(context);
3970    context.currentDataIdx = context.charIdx + 1;
3971}
3972function emitText(context) {
3973    var text = context.html.slice(context.currentDataIdx, context.charIdx);
3974    context.callbacks.onText(text, context.currentDataIdx);
3975    context.currentDataIdx = context.charIdx + 1;
3976}
3977/**
3978 * Captures the tag name from the start of the tag to the current character
3979 * index, and converts it to lower case
3980 */
3981function captureTagName(context) {
3982    var startIdx = context.currentTag.idx + (context.currentTag.isClosing ? 2 : 1);
3983    return context.html.slice(startIdx, context.charIdx).toLowerCase();
3984}
3985/**
3986 * Causes the main loop to re-consume the current character, such as after
3987 * encountering a "parse error" that changed state and needs to reconsume
3988 * the same character in that new state.
3989 */
3990function reconsumeCurrentChar(context) {
3991    context.charIdx--;
3992}
vendor: 38,308 bytes, lines 3993-4805
3993
3994/**
3995 * @class Autolinker
3996 * @extends Object
3997 *
3998 * Utility class used to process a given string of text, and wrap the matches in
3999 * the appropriate anchor (&lt;a&gt;) tags to turn them into links.
4000 *
4001 * Any of the configuration options may be provided in an Object provided
4002 * to the Autolinker constructor, which will configure how the {@link #link link()}
4003 * method will process the links.
4004 *
4005 * For example:
4006 *
4007 *     var autolinker = new Autolinker( {
4008 *         newWindow : false,
4009 *         truncate  : 30
4010 *     } );
4011 *
4012 *     var html = autolinker.link( "Joe went to www.yahoo.com" );
4013 *     // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>'
4014 *
4015 *
4016 * The {@link #static-link static link()} method may also be used to inline
4017 * options into a single call, which may be more convenient for one-off uses.
4018 * For example:
4019 *
4020 *     var html = Autolinker.link( "Joe went to www.yahoo.com", {
4021 *         newWindow : false,
4022 *         truncate  : 30
4023 *     } );
4024 *     // produces: 'Joe went to <a href="http://www.yahoo.com">yahoo.com</a>'
4025 *
4026 *
4027 * ## Custom Replacements of Links
4028 *
4029 * If the configuration options do not provide enough flexibility, a {@link #replaceFn}
4030 * may be provided to fully customize the output of Autolinker. This function is
4031 * called once for each URL/Email/Phone#/Hashtag/Mention (Twitter, Instagram, Soundcloud)
4032 * match that is encountered.
4033 *
4034 * For example:
4035 *
4036 *     var input = "...";  // string with URLs, Email Addresses, Phone #s, Hashtags, and Mentions (Twitter, Instagram, Soundcloud)
4037 *
4038 *     var linkedText = Autolinker.link( input, {
4039 *         replaceFn : function( match ) {
4040 *             console.log( "href = ", match.getAnchorHref() );
4041 *             console.log( "text = ", match.getAnchorText() );
4042 *
4043 *             switch( match.getType() ) {
4044 *                 case 'url' :
4045 *                     console.log( "url: ", match.getUrl() );
4046 *
4047 *                     if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) {
4048 *                         var tag = match.buildTag();  // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes
4049 *                         tag.setAttr( 'rel', 'nofollow' );
4050 *                         tag.addClass( 'external-link' );
4051 *
4052 *                         return tag;
4053 *
4054 *                     } else {
4055 *                         return true;  // let Autolinker perform its normal anchor tag replacement
4056 *                     }
4057 *
4058 *                 case 'email' :
4059 *                     var email = match.getEmail();
4060 *                     console.log( "email: ", email );
4061 *
4062 *                     if( email === "[email protected]" ) {
4063 *                         return false;  // don't auto-link this particular email address; leave as-is
4064 *                     } else {
4065 *                         return;  // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`)
4066 *                     }
4067 *
4068 *                 case 'phone' :
4069 *                     var phoneNumber = match.getPhoneNumber();
4070 *                     console.log( phoneNumber );
4071 *
4072 *                     return '<a href="http://newplace.to.link.phone.numbers.to/">' + phoneNumber + '</a>';
4073 *
4074 *                 case 'hashtag' :
4075 *                     var hashtag = match.getHashtag();
4076 *                     console.log( hashtag );
4077 *
4078 *                     return '<a href="http://newplace.to.link.hashtag.handles.to/">' + hashtag + '</a>';
4079 *
4080 *                 case 'mention' :
4081 *                     var mention = match.getMention();
4082 *                     console.log( mention );
4083 *
4084 *                     return '<a href="http://newplace.to.link.mention.to/">' + mention + '</a>';
4085 *             }
4086 *         }
4087 *     } );
4088 *
4089 *
4090 * The function may return the following values:
4091 *
4092 * - `true` (Boolean): Allow Autolinker to replace the match as it normally
4093 *   would.
4094 * - `false` (Boolean): Do not replace the current match at all - leave as-is.
4095 * - Any String: If a string is returned from the function, the string will be
4096 *   used directly as the replacement HTML for the match.
4097 * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify
4098 *   an HTML tag before writing out its HTML text.
4099 */
4100var Autolinker = /** @class */ (function () {
4101    /**
4102     * @method constructor
4103     * @param {Object} [cfg] The configuration options for the Autolinker instance,
4104     *   specified in an Object (map).
4105     */
4106    function Autolinker(cfg) {
4107        if (cfg === void 0) { cfg = {}; }
4108        /**
4109         * The Autolinker version number exposed on the instance itself.
4110         *
4111         * Ex: 0.25.1
4112         *
4113         * @property {String} version
4114         */
4115        this.version = Autolinker.version;
4116        /**
4117         * @cfg {Boolean/Object} [urls]
4118         *
4119         * `true` if URLs should be automatically linked, `false` if they should not
4120         * be. Defaults to `true`.
4121         *
4122         * Examples:
4123         *
4124         *     urls: true
4125         *
4126         *     // or
4127         *
4128         *     urls: {
4129         *         schemeMatches : true,
4130         *         tldMatches    : true,
4131         *         ipV4Matches   : true
4132         *     }
4133         *
4134         * As shown above, this option also accepts an Object form with 3 properties
4135         * to allow for more customization of what exactly gets linked. All default
4136         * to `true`:
4137         *
4138         * @cfg {Boolean} [urls.schemeMatches] `true` to match URLs found prefixed
4139         *   with a scheme, i.e. `http://google.com`, or `other+scheme://google.com`,
4140         *   `false` to prevent these types of matches.
4141         * @cfg {Boolean} [urls.tldMatches] `true` to match URLs with known top
4142         *   level domains (.com, .net, etc.) that are not prefixed with a scheme
4143         *   (such as 'http://'). This option attempts to match anything that looks
4144         *   like a URL in the given text. Ex: `google.com`, `asdf.org/?page=1`, etc.
4145         *   `false` to prevent these types of matches.
4146         * @cfg {Boolean} [urls.ipV4Matches] `true` to match IPv4 addresses in text
4147         *   that are not prefixed with a scheme (such as 'http://'). This option
4148         *   attempts to match anything that looks like an IPv4 address in text. Ex:
4149         *   `192.168.0.1`, `10.0.0.1/?page=1`, etc. `false` to prevent these types
4150         *   of matches.
4151         */
4152        this.urls = {}; // default value just to get the above doc comment in the ES5 output and documentation generator
4153        /**
4154         * @cfg {Boolean} [email=true]
4155         *
4156         * `true` if email addresses should be automatically linked, `false` if they
4157         * should not be.
4158         */
4159        this.email = true; // default value just to get the above doc comment in the ES5 output and documentation generator
4160        /**
4161         * @cfg {Boolean} [phone=true]
4162         *
4163         * `true` if Phone numbers ("(555)555-5555") should be automatically linked,
4164         * `false` if they should not be.
4165         */
4166        this.phone = true; // default value just to get the above doc comment in the ES5 output and documentation generator
4167        /**
4168         * @cfg {Boolean/String} [hashtag=false]
4169         *
4170         * A string for the service name to have hashtags (ex: "#myHashtag")
4171         * auto-linked to. The currently-supported values are:
4172         *
4173         * - 'twitter'
4174         * - 'facebook'
4175         * - 'instagram'
4176         * - 'tiktok'
4177         * - 'youtube'
4178         *
4179         * Pass `false` to skip auto-linking of hashtags.
4180         */
4181        this.hashtag = false; // default value just to get the above doc comment in the ES5 output and documentation generator
4182        /**
4183         * @cfg {String/Boolean} [mention=false]
4184         *
4185         * A string for the service name to have mentions (ex: "@myuser")
4186         * auto-linked to. The currently supported values are:
4187         *
4188         * - 'twitter'
4189         * - 'instagram'
4190         * - 'soundcloud'
4191         * - 'tiktok'
4192         * - 'youtube'
4193         *
4194         * Defaults to `false` to skip auto-linking of mentions.
4195         */
4196        this.mention = false; // default value just to get the above doc comment in the ES5 output and documentation generator
4197        /**
4198         * @cfg {Boolean} [newWindow=true]
4199         *
4200         * `true` if the links should open in a new window, `false` otherwise.
4201         */
4202        this.newWindow = true; // default value just to get the above doc comment in the ES5 output and documentation generator
4203        /**
4204         * @cfg {Boolean/Object} [stripPrefix=true]
4205         *
4206         * `true` if 'http://' (or 'https://') and/or the 'www.' should be stripped
4207         * from the beginning of URL links' text, `false` otherwise. Defaults to
4208         * `true`.
4209         *
4210         * Examples:
4211         *
4212         *     stripPrefix: true
4213         *
4214         *     // or
4215         *
4216         *     stripPrefix: {
4217         *         scheme : true,
4218         *         www    : true
4219         *     }
4220         *
4221         * As shown above, this option also accepts an Object form with 2 properties
4222         * to allow for more customization of what exactly is prevented from being
4223         * displayed. Both default to `true`:
4224         *
4225         * @cfg {Boolean} [stripPrefix.scheme] `true` to prevent the scheme part of
4226         *   a URL match from being displayed to the user. Example:
4227         *   `'http://google.com'` will be displayed as `'google.com'`. `false` to
4228         *   not strip the scheme. NOTE: Only an `'http://'` or `'https://'` scheme
4229         *   will be removed, so as not to remove a potentially dangerous scheme
4230         *   (such as `'file://'` or `'javascript:'`)
4231         * @cfg {Boolean} [stripPrefix.www] www (Boolean): `true` to prevent the
4232         *   `'www.'` part of a URL match from being displayed to the user. Ex:
4233         *   `'www.google.com'` will be displayed as `'google.com'`. `false` to not
4234         *   strip the `'www'`.
4235         */
4236        this.stripPrefix = {
4237            scheme: true,
4238            www: true,
4239        }; // default value just to get the above doc comment in the ES5 output and documentation generator
4240        /**
4241         * @cfg {Boolean} [stripTrailingSlash=true]
4242         *
4243         * `true` to remove the trailing slash from URL matches, `false` to keep
4244         *  the trailing slash.
4245         *
4246         *  Example when `true`: `http://google.com/` will be displayed as
4247         *  `http://google.com`.
4248         */
4249        this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator
4250        /**
4251         * @cfg {Boolean} [decodePercentEncoding=true]
4252         *
4253         * `true` to decode percent-encoded characters in URL matches, `false` to keep
4254         *  the percent-encoded characters.
4255         *
4256         *  Example when `true`: `https://en.wikipedia.org/wiki/San_Jos%C3%A9` will
4257         *  be displayed as `https://en.wikipedia.org/wiki/San_José`.
4258         */
4259        this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator
4260        /**
4261         * @cfg {Number/Object} [truncate=0]
4262         *
4263         * ## Number Form
4264         *
4265         * A number for how many characters matched text should be truncated to
4266         * inside the text of a link. If the matched text is over this number of
4267         * characters, it will be truncated to this length by adding a two period
4268         * ellipsis ('..') to the end of the string.
4269         *
4270         * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file'
4271         * truncated to 25 characters might look something like this:
4272         * 'yahoo.com/some/long/pat..'
4273         *
4274         * Example Usage:
4275         *
4276         *     truncate: 25
4277         *
4278         *
4279         *  Defaults to `0` for "no truncation."
4280         *
4281         *
4282         * ## Object Form
4283         *
4284         * An Object may also be provided with two properties: `length` (Number) and
4285         * `location` (String). `location` may be one of the following: 'end'
4286         * (default), 'middle', or 'smart'.
4287         *
4288         * Example Usage:
4289         *
4290         *     truncate: { length: 25, location: 'middle' }
4291         *
4292         * @cfg {Number} [truncate.length=0] How many characters to allow before
4293         *   truncation will occur. Defaults to `0` for "no truncation."
4294         * @cfg {"end"/"middle"/"smart"} [truncate.location="end"]
4295         *
4296         * - 'end' (default): will truncate up to the number of characters, and then
4297         *   add an ellipsis at the end. Ex: 'yahoo.com/some/long/pat..'
4298         * - 'middle': will truncate and add the ellipsis in the middle. Ex:
4299         *   'yahoo.com/s..th/to/a/file'
4300         * - 'smart': for URLs where the algorithm attempts to strip out unnecessary
4301         *   parts first (such as the 'www.', then URL scheme, hash, etc.),
4302         *   attempting to make the URL human-readable before looking for a good
4303         *   point to insert the ellipsis if it is still too long. Ex:
4304         *   'yahoo.com/some..to/a/file'. For more details, see
4305         *   {@link Autolinker.truncate.TruncateSmart}.
4306         */
4307        this.truncate = {
4308            length: 0,
4309            location: 'end',
4310        }; // default value just to get the above doc comment in the ES5 output and documentation generator
4311        /**
4312         * @cfg {String} className
4313         *
4314         * A CSS class name to add to the generated links. This class will be added
4315         * to all links, as well as this class plus match suffixes for styling
4316         * url/email/phone/hashtag/mention links differently.
4317         *
4318         * For example, if this config is provided as "myLink", then:
4319         *
4320         * - URL links will have the CSS classes: "myLink myLink-url"
4321         * - Email links will have the CSS classes: "myLink myLink-email", and
4322         * - Phone links will have the CSS classes: "myLink myLink-phone"
4323         * - Hashtag links will have the CSS classes: "myLink myLink-hashtag"
4324         * - Mention links will have the CSS classes: "myLink myLink-mention myLink-[type]"
4325         *   where [type] is either "instagram", "twitter" or "soundcloud"
4326         */
4327        this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator
4328        /**
4329         * @cfg {Function} replaceFn
4330         *
4331         * A function to individually process each match found in the input string.
4332         *
4333         * See the class's description for usage.
4334         *
4335         * The `replaceFn` can be called with a different context object (`this`
4336         * reference) using the {@link #context} cfg.
4337         *
4338         * This function is called with the following parameter:
4339         *
4340         * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which
4341         *   can be used to retrieve information about the match that the `replaceFn`
4342         *   is currently processing. See {@link Autolinker.match.Match} subclasses
4343         *   for details.
4344         */
4345        this.replaceFn = null; // default value just to get the above doc comment in the ES5 output and documentation generator
4346        /**
4347         * @cfg {Object} context
4348         *
4349         * The context object (`this` reference) to call the `replaceFn` with.
4350         *
4351         * Defaults to this Autolinker instance.
4352         */
4353        this.context = undefined; // default value just to get the above doc comment in the ES5 output and documentation generator
4354        /**
4355         * @cfg {Boolean} [sanitizeHtml=false]
4356         *
4357         * `true` to HTML-encode the start and end brackets of existing HTML tags found
4358         * in the input string. This will escape `<` and `>` characters to `&lt;` and
4359         * `&gt;`, respectively.
4360         *
4361         * Setting this to `true` will prevent XSS (Cross-site Scripting) attacks,
4362         * but will remove the significance of existing HTML tags in the input string. If
4363         * you would like to maintain the significance of existing HTML tags while also
4364         * making the output HTML string safe, leave this option as `false` and use a
4365         * tool like https://github.com/cure53/DOMPurify (or others) on the input string
4366         * before running Autolinker.
4367         */
4368        this.sanitizeHtml = false; // default value just to get the above doc comment in the ES5 output and documentation generator
4369        /**
4370         * @private
4371         * @property {Autolinker.AnchorTagBuilder} tagBuilder
4372         *
4373         * The AnchorTagBuilder instance used to build match replacement anchor tags.
4374         * Note: this is lazily instantiated in the {@link #getTagBuilder} method.
4375         */
4376        this.tagBuilder = null;
4377        // Note: when `this.something` is used in the rhs of these assignments,
4378        //       it refers to the default values set above the constructor
4379        this.urls = normalizeUrlsCfg(cfg.urls);
4380        this.email = isBoolean(cfg.email) ? cfg.email : this.email;
4381        this.phone = isBoolean(cfg.phone) ? cfg.phone : this.phone;
4382        this.hashtag = cfg.hashtag || this.hashtag;
4383        this.mention = cfg.mention || this.mention;
4384        this.newWindow = isBoolean(cfg.newWindow) ? cfg.newWindow : this.newWindow;
4385        this.stripPrefix = normalizeStripPrefixCfg(cfg.stripPrefix);
4386        this.stripTrailingSlash = isBoolean(cfg.stripTrailingSlash)
4387            ? cfg.stripTrailingSlash
4388            : this.stripTrailingSlash;
4389        this.decodePercentEncoding = isBoolean(cfg.decodePercentEncoding)
4390            ? cfg.decodePercentEncoding
4391            : this.decodePercentEncoding;
4392        this.sanitizeHtml = cfg.sanitizeHtml || false;
4393        // Validate the value of the `mention` cfg
4394        var mention = this.mention;
4395        if (mention !== false && mentionServices.indexOf(mention) === -1) {
4396            throw new Error("invalid `mention` cfg '".concat(mention, "' - see docs"));
4397        }
4398        // Validate the value of the `hashtag` cfg
4399        var hashtag = this.hashtag;
4400        if (hashtag !== false && hashtagServices.indexOf(hashtag) === -1) {
4401            throw new Error("invalid `hashtag` cfg '".concat(hashtag, "' - see docs"));
4402        }
4403        this.truncate = normalizeTruncateCfg(cfg.truncate);
4404        this.className = cfg.className || this.className;
4405        this.replaceFn = cfg.replaceFn || this.replaceFn;
4406        this.context = cfg.context || this;
4407    }
4408    /**
4409     * Automatically links URLs, Email addresses, Phone Numbers, Twitter handles,
4410     * Hashtags, and Mentions found in the given chunk of HTML. Does not link URLs
4411     * found within HTML tags.
4412     *
4413     * For instance, if given the text: `You should go to http://www.yahoo.com`,
4414     * then the result will be `You should go to &lt;a href="http://www.yahoo.com"&gt;http://www.yahoo.com&lt;/a&gt;`
4415     *
4416     * Example:
4417     *
4418     *     var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } );
4419     *     // Produces: "Go to <a href="http://google.com">google.com</a>"
4420     *
4421     * @static
4422     * @param {String} textOrHtml The HTML or text to find matches within (depending
4423     *   on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #mention},
4424     *   {@link #hashtag}, and {@link #mention} options are enabled).
4425     * @param {Object} [options] Any of the configuration options for the Autolinker
4426     *   class, specified in an Object (map). See the class description for an
4427     *   example call.
4428     * @return {String} The HTML text, with matches automatically linked.
4429     */
4430    Autolinker.link = function (textOrHtml, options) {
4431        var autolinker = new Autolinker(options);
4432        return autolinker.link(textOrHtml);
4433    };
4434    /**
4435     * Parses the input `textOrHtml` looking for URLs, email addresses, phone
4436     * numbers, username handles, and hashtags (depending on the configuration
4437     * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
4438     * objects describing those matches (without making any replacements).
4439     *
4440     * Note that if parsing multiple pieces of text, it is slightly more efficient
4441     * to create an Autolinker instance, and use the instance-level {@link #parse}
4442     * method.
4443     *
4444     * Example:
4445     *
4446     *     var matches = Autolinker.parse("Hello google.com, I am [email protected]", {
4447     *         urls: true,
4448     *         email: true
4449     *     });
4450     *
4451     *     console.log(matches.length);         // 2
4452     *     console.log(matches[0].getType());   // 'url'
4453     *     console.log(matches[0].getUrl());    // 'google.com'
4454     *     console.log(matches[1].getType());   // 'email'
4455     *     console.log(matches[1].getEmail());  // '[email protected]'
4456     *
4457     * @static
4458     * @param {String} textOrHtml The HTML or text to find matches within
4459     *   (depending on if the {@link #urls}, {@link #email}, {@link #phone},
4460     *   {@link #hashtag}, and {@link #mention} options are enabled).
4461     * @param {Object} [options] Any of the configuration options for the Autolinker
4462     *   class, specified in an Object (map). See the class description for an
4463     *   example call.
4464     * @return {Autolinker.match.Match[]} The array of Matches found in the
4465     *   given input `textOrHtml`.
4466     */
4467    Autolinker.parse = function (textOrHtml, options) {
4468        var autolinker = new Autolinker(options);
4469        return autolinker.parse(textOrHtml);
4470    };
4471    /**
4472     * Parses the input `textOrHtml` looking for URLs, email addresses, phone
4473     * numbers, username handles, and hashtags (depending on the configuration
4474     * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
4475     * objects describing those matches (without making any replacements).
4476     *
4477     * This method is used by the {@link #link} method, but can also be used to
4478     * simply do parsing of the input in order to discover what kinds of links
4479     * there are and how many.
4480     *
4481     * Example usage:
4482     *
4483     *     var autolinker = new Autolinker( {
4484     *         urls: true,
4485     *         email: true
4486     *     } );
4487     *
4488     *     var matches = autolinker.parse( "Hello google.com, I am [email protected]" );
4489     *
4490     *     console.log( matches.length );           // 2
4491     *     console.log( matches[ 0 ].getType() );   // 'url'
4492     *     console.log( matches[ 0 ].getUrl() );    // 'google.com'
4493     *     console.log( matches[ 1 ].getType() );   // 'email'
4494     *     console.log( matches[ 1 ].getEmail() );  // '[email protected]'
4495     *
4496     * @param {String} textOrHtml The HTML or text to find matches within
4497     *   (depending on if the {@link #urls}, {@link #email}, {@link #phone},
4498     *   {@link #hashtag}, and {@link #mention} options are enabled).
4499     * @return {Autolinker.match.Match[]} The array of Matches found in the
4500     *   given input `textOrHtml`.
4501     */
4502    Autolinker.prototype.parse = function (textOrHtml) {
4503        var _this = this;
4504        var skipTagNames = ['a', 'style', 'script'];
4505        var skipTagsStackCount = 0; // used to only Autolink text outside of anchor/script/style tags. We don't want to autolink something that is already linked inside of an <a> tag, for instance
4506        var matches = [];
4507        // Find all matches within the `textOrHtml` (but not matches that are
4508        // already nested within <a>, <style> and <script> tags)
4509        parseHtml(textOrHtml, {
4510            onOpenTag: function (tagName) {
4511                if (skipTagNames.indexOf(tagName) >= 0) {
4512                    skipTagsStackCount++;
4513                }
4514            },
4515            onText: function (text, offset) {
4516                // Only process text nodes that are not within an <a>, <style> or <script> tag
4517                if (skipTagsStackCount === 0) {
4518                    // "Walk around" common HTML entities. An '&nbsp;' (for example)
4519                    // could be at the end of a URL, but we don't want to
4520                    // include the trailing '&' in the URL. See issue #76
4521                    // TODO: Handle HTML entities separately in parseHtml() and
4522                    // don't emit them as "text" except for &amp; entities
4523                    var htmlCharacterEntitiesRegex = /(&nbsp;|&#160;|&lt;|&#60;|&gt;|&#62;|&quot;|&#34;|&#39;)/gi; // NOTE: capturing group is significant to include the split characters in the .split() call below
4524                    var textSplit = text.split(htmlCharacterEntitiesRegex);
4525                    var currentOffset_1 = offset;
4526                    textSplit.forEach(function (splitText, i) {
4527                        // even number matches are text, odd numbers are html entities
4528                        if (i % 2 === 0) {
4529                            var textNodeMatches = _this.parseText(splitText, currentOffset_1);
4530                            matches.push.apply(matches, __spreadArray([], __read(textNodeMatches), false));
4531                        }
4532                        currentOffset_1 += splitText.length;
4533                    });
4534                }
4535            },
4536            onCloseTag: function (tagName) {
4537                if (skipTagNames.indexOf(tagName) >= 0) {
4538                    skipTagsStackCount = Math.max(skipTagsStackCount - 1, 0); // attempt to handle extraneous </a> tags by making sure the stack count never goes below 0
4539                }
4540            },
4541            onComment: function ( /*_offset: number*/) { }, // no need to process comment nodes
4542            onDoctype: function ( /*_offset: number*/) { }, // no need to process doctype nodes
4543        });
4544        // After we have found all matches, remove subsequent matches that
4545        // overlap with a previous match. This can happen for instance with an
4546        // email address where the local-part of the email is also a top-level
4547        // domain, such as in "[email protected]". In this case, the entire
4548        // email address should be linked rather than just the 'google.com'
4549        // part.
4550        matches = this.compactMatches(matches);
4551        // And finally, remove matches for match types that have been turned
4552        // off. We needed to have all match types turned on initially so that
4553        // things like hashtags could be filtered out if they were really just
4554        // part of a URL match (for instance, as a named anchor).
4555        matches = this.removeUnwantedMatches(matches);
4556        return matches;
4557    };
4558    /**
4559     * After we have found all matches, we need to remove matches that overlap
4560     * with a previous match. This can happen for instance with an
4561     * email address where the local-part of the email is also a top-level
4562     * domain, such as in "[email protected]". In this case, the entire email
4563     * address should be linked rather than just the 'google.com' part.
4564     *
4565     * @private
4566     * @param {Autolinker.match.Match[]} matches
4567     * @return {Autolinker.match.Match[]}
4568     */
4569    Autolinker.prototype.compactMatches = function (matches) {
4570        // First, the matches need to be sorted in order of offset in the input
4571        // string
4572        matches.sort(byMatchOffset);
4573        var i = 0;
4574        while (i < matches.length - 1) {
4575            var match = matches[i];
4576            var offset = match.getOffset();
4577            var matchedTextLength = match.getMatchedText().length;
4578            if (i + 1 < matches.length) {
4579                // Remove subsequent matches that equal offset with current match
4580                // This can happen when matching the text "[email protected]"
4581                // where we have both a URL ('google.com') and an email. We
4582                // should only keep the email match in this case.
4583                if (matches[i + 1].getOffset() === offset) {
4584                    // Remove the shorter match
4585                    var removeIdx = matches[i + 1].getMatchedText().length > matchedTextLength ? i : i + 1;
4586                    matches.splice(removeIdx, 1);
4587                    continue;
4588                }
4589                // Remove subsequent matches that overlap with the current match
4590                //
4591                // NOTE: This was a fundamental snippet of the Autolinker.js v3
4592                // algorithm where we had multiple regular expressions searching
4593                // the input string for matches. The regexes would sometimes
4594                // overlap such as in the case of "google.com/#link", where we
4595                // would have both a URL match and a hashtag match.
4596                //
4597                // However, the Autolinker.js v4 algorithm uses a state machine
4598                // parser and knows that the '#link' part of 'google.com/#link'
4599                // is part of the URL that precedes it, so we don't need this
4600                // piece of code any more. Keeping it here commented for now in
4601                // case we need to put it back at some point, but none of the
4602                // test cases are currently able to trigger the need for it.
4603                // const endIdx = offset + matchedTextLength;
4604                // if (matches[i + 1].getOffset() < endIdx) {
4605                //     matches.splice(i + 1, 1);
4606                //     continue;
4607                // }
4608            }
4609            i++;
4610        }
4611        return matches;
4612    };
4613    /**
4614     * Removes matches for matchers that were turned off in the options. For
4615     * example, if {@link #hashtag hashtags} were not to be matched, we'll
4616     * remove them from the `matches` array here.
4617     *
4618     * Note: we *must* use all Matchers on the input string, and then filter
4619     * them out later. For example, if the options were `{ url: false, hashtag: true }`,
4620     * we wouldn't want to match the text '#link' as a HashTag inside of the text
4621     * 'google.com/#link'. The way the algorithm works is that we match the full
4622     * URL first (which prevents the accidental HashTag match), and then we'll
4623     * simply throw away the URL match.
4624     *
4625     * @private
4626     * @param {Autolinker.match.Match[]} matches The array of matches to remove
4627     *   the unwanted matches from. Note: this array is mutated for the
4628     *   removals.
4629     * @return {Autolinker.match.Match[]} The mutated input `matches` array.
4630     */
4631    Autolinker.prototype.removeUnwantedMatches = function (matches) {
4632        if (!this.hashtag)
4633            removeWithPredicate(matches, function (match) {
4634                return match.getType() === 'hashtag';
4635            });
4636        if (!this.email)
4637            removeWithPredicate(matches, function (match) {
4638                return match.getType() === 'email';
4639            });
4640        if (!this.phone)
4641            removeWithPredicate(matches, function (match) {
4642                return match.getType() === 'phone';
4643            });
4644        if (!this.mention)
4645            removeWithPredicate(matches, function (match) {
4646                return match.getType() === 'mention';
4647            });
4648        if (!this.urls.schemeMatches) {
4649            removeWithPredicate(matches, function (m) {
4650                return m.getType() === 'url' && m.getUrlMatchType() === 'scheme';
4651            });
4652        }
4653        if (!this.urls.tldMatches) {
4654            removeWithPredicate(matches, function (m) { return m.getType() === 'url' && m.getUrlMatchType() === 'tld'; });
4655        }
4656        if (!this.urls.ipV4Matches) {
4657            removeWithPredicate(matches, function (m) { return m.getType() === 'url' && m.getUrlMatchType() === 'ipV4'; });
4658        }
4659        return matches;
4660    };
4661    /**
4662     * Parses the input `text` looking for URLs, email addresses, phone
4663     * numbers, username handles, and hashtags (depending on the configuration
4664     * of the Autolinker instance), and returns an array of {@link Autolinker.match.Match}
4665     * objects describing those matches.
4666     *
4667     * This method processes a **non-HTML string**, and is used to parse and
4668     * match within the text nodes of an HTML string. This method is used
4669     * internally by {@link #parse}.
4670     *
4671     * @private
4672     * @param {String} text The text to find matches within (depending on if the
4673     *   {@link #urls}, {@link #email}, {@link #phone},
4674     *   {@link #hashtag}, and {@link #mention} options are enabled). This must be a non-HTML string.
4675     * @param {Number} [offset=0] The offset of the text node within the
4676     *   original string. This is used when parsing with the {@link #parse}
4677     *   method to generate correct offsets within the {@link Autolinker.match.Match}
4678     *   instances, but may be omitted if calling this method publicly.
4679     * @return {Autolinker.match.Match[]} The array of Matches found in the
4680     *   given input `text`.
4681     */
4682    Autolinker.prototype.parseText = function (text, offset) {
4683        offset = offset || 0;
4684        var matches = parseMatches(text, {
4685            tagBuilder: this.getTagBuilder(),
4686            stripPrefix: this.stripPrefix,
4687            stripTrailingSlash: this.stripTrailingSlash,
4688            decodePercentEncoding: this.decodePercentEncoding,
4689            hashtagServiceName: this.hashtag,
4690            mentionServiceName: this.mention || 'twitter',
4691        });
4692        // Correct the offset of each of the matches. They are originally
4693        // the offset of the match within the provided text node, but we
4694        // need to correct them to be relative to the original HTML input
4695        // string (i.e. the one provided to #parse).
4696        for (var i = 0, numTextMatches = matches.length; i < numTextMatches; i++) {
4697            matches[i].setOffset(offset + matches[i].getOffset());
4698        }
4699        return matches;
4700    };
4701    /**
4702     * Automatically links URLs, Email addresses, Phone numbers, Hashtags,
4703     * and Mentions (Twitter, Instagram, Soundcloud) found in the given chunk of HTML. Does not link
4704     * URLs found within HTML tags.
4705     *
4706     * For instance, if given the text: `You should go to http://www.yahoo.com`,
4707     * then the result will be `You should go to
4708     * &lt;a href="http://www.yahoo.com"&gt;http://www.yahoo.com&lt;/a&gt;`
4709     *
4710     * This method finds the text around any HTML elements in the input
4711     * `textOrHtml`, which will be the text that is processed. Any original HTML
4712     * elements will be left as-is, as well as the text that is already wrapped
4713     * in anchor (&lt;a&gt;) tags.
4714     *
4715     * @param {String} textOrHtml The HTML or text to autolink matches within
4716     *   (depending on if the {@link #urls}, {@link #email}, {@link #phone}, {@link #hashtag}, and {@link #mention} options are enabled).
4717     * @return {String} The HTML, with matches automatically linked.
4718     */
4719    Autolinker.prototype.link = function (textOrHtml) {
4720        if (!textOrHtml) {
4721            return '';
4722        } // handle `null` and `undefined` (for JavaScript users that don't have TypeScript support), and nothing to do with an empty string too
4723        /* We would want to sanitize the start and end characters of a tag
4724         * before processing the string in order to avoid an XSS scenario.
4725         * This behaviour can be changed by toggling the sanitizeHtml option.
4726         */
4727        if (this.sanitizeHtml) {
4728            textOrHtml = textOrHtml.replace(/</g, '&lt;').replace(/>/g, '&gt;');
4729        }
4730        var matches = this.parse(textOrHtml);
4731        var newHtml = new Array(matches.length * 2 + 1);
4732        var lastIndex = 0;
4733        for (var i = 0, len = matches.length; i < len; i++) {
4734            var match = matches[i];
4735            newHtml.push(textOrHtml.substring(lastIndex, match.getOffset()));
4736            newHtml.push(this.createMatchReturnVal(match));
4737            lastIndex = match.getOffset() + match.getMatchedText().length;
4738        }
4739        newHtml.push(textOrHtml.substring(lastIndex)); // handle the text after the last match
4740        return newHtml.join('');
4741    };
4742    /**
4743     * Creates the return string value for a given match in the input string.
4744     *
4745     * This method handles the {@link #replaceFn}, if one was provided.
4746     *
4747     * @private
4748     * @param {Autolinker.match.Match} match The Match object that represents
4749     *   the match.
4750     * @return {String} The string that the `match` should be replaced with.
4751     *   This is usually the anchor tag string, but may be the `matchStr` itself
4752     *   if the match is not to be replaced.
4753     */
4754    Autolinker.prototype.createMatchReturnVal = function (match) {
4755        // Handle a custom `replaceFn` being provided
4756        var replaceFnResult;
4757        if (this.replaceFn) {
4758            replaceFnResult = this.replaceFn.call(this.context, match); // Autolinker instance is the context
4759        }
4760        if (typeof replaceFnResult === 'string') {
4761            return replaceFnResult; // `replaceFn` returned a string, use that
4762        }
4763        else if (replaceFnResult === false) {
4764            return match.getMatchedText(); // no replacement for the match
4765        }
4766        else if (replaceFnResult instanceof HtmlTag) {
4767            return replaceFnResult.toAnchorString();
4768        }
4769        else {
4770            // replaceFnResult === true, or no/unknown return value from function
4771            // Perform Autolinker's default anchor tag generation
4772            var anchorTag = match.buildTag(); // returns an Autolinker.HtmlTag instance
4773            return anchorTag.toAnchorString();
4774        }
4775    };
4776    /**
4777     * Returns the {@link #tagBuilder} instance for this Autolinker instance,
4778     * lazily instantiating it if it does not yet exist.
4779     *
4780     * @private
4781     * @return {Autolinker.AnchorTagBuilder}
4782     */
4783    Autolinker.prototype.getTagBuilder = function () {
4784        var tagBuilder = this.tagBuilder;
4785        if (!tagBuilder) {
4786            tagBuilder = this.tagBuilder = new AnchorTagBuilder({
4787                newWindow: this.newWindow,
4788                truncate: this.truncate,
4789                className: this.className,
4790            });
4791        }
4792        return tagBuilder;
4793    };
4794    // NOTE: must be 'export default' here for UMD module
4795    /**
4796     * @static
4797     * @property {String} version
4798     *
4799     * The Autolinker version number in the form major.minor.patch
4800     *
4801     * Ex: 3.15.0
4802     */
4803    Autolinker.version = version;
4804    return Autolinker;
4805}());
4806/**
4807 * Normalizes the {@link #urls} config into an Object with its 2 properties:
4808 * `schemeMatches` and `tldMatches`, both booleans.
4809 *
4810 * See {@link #urls} config for details.
4811 *
4812 * @private
4813 * @param {Boolean/Object} urls
4814 * @return {Object}
4815 */
4816function normalizeUrlsCfg(urls) {
4817    if (urls == null)
4818        urls = true; // default to `true`
4819    if (isBoolean(urls)) {
4820        return { schemeMatches: urls, tldMatches: urls, ipV4Matches: urls };
4821    }
4822    else {
4823        // object form
4824        return {
4825            schemeMatches: isBoolean(urls.schemeMatches) ? urls.schemeMatches : true,
4826            tldMatches: isBoolean(urls.tldMatches) ? urls.tldMatches : true,
4827            ipV4Matches: isBoolean(urls.ipV4Matches) ? urls.ipV4Matches : true,
4828        };
4829    }
4830}
4831/**
4832 * Normalizes the {@link #stripPrefix} config into an Object with 2
4833 * properties: `scheme`, and `www` - both Booleans.
4834 *
4835 * See {@link #stripPrefix} config for details.
4836 *
4837 * @private
4838 * @param {Boolean/Object} stripPrefix
4839 * @return {Object}
4840 */
4841function normalizeStripPrefixCfg(stripPrefix) {
4842    if (stripPrefix == null)
4843        stripPrefix = true; // default to `true`
4844    if (isBoolean(stripPrefix)) {
4845        return { scheme: stripPrefix, www: stripPrefix };
4846    }
4847    else {
4848        // object form
4849        return {
4850            scheme: isBoolean(stripPrefix.scheme) ? stripPrefix.scheme : true,
4851            www: isBoolean(stripPrefix.www) ? stripPrefix.www : true,
4852        };
4853    }
4854}
4855/**
4856 * Normalizes the {@link #truncate} config into an Object with 2 properties:
4857 * `length` (Number), and `location` (String).
4858 *
4859 * See {@link #truncate} config for details.
4860 *
4861 * @private
4862 * @param {Number/Object} truncate
4863 * @return {Object}
4864 */
4865function normalizeTruncateCfg(truncate) {
4866    if (typeof truncate === 'number') {
4867        return { length: truncate, location: 'end' };
4868    }
4869    else {
4870        // object, or undefined/null
4871        return __assign({ length: Number.POSITIVE_INFINITY, location: 'end' }, truncate);
4872    }
4873}
4874/**
4875 * Helper function for Array.prototype.sort() to sort the Matches by
4876 * their offset in the input string.
4877 */
4878function byMatchOffset(a, b) {
4879    return a.getOffset() - b.getOffset();
4880}
4881
4882export { Autolinker as A, __decorate as _, __metadata as a, __param as b };
4883//# sourceMappingURL=autolinker-aZsZGYsK.js.map

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.