# Path: wikitextparser/_config.py
# def _plant_trie(strings: _Iterable[str]) -> dict:
# def _pattern(trie: dict) -> str:
# def regex_pattern(words: _Iterable[str]) -> bytes:
# _HTML_TAG_NAME = regex_pattern(_valid_html_tag_names) + br'\b'
# 
# Path: wikitextparser/_spans.py
# BARE_EXTERNAL_LINK = BARE_EXTERNAL_LINK_SCHEMES + EXTERNAL_LINK_URL_TAIL
# 
# END_TAG_PATTERN = rb'(?<end_tag></{name}(?:>|[' + SPACE_CHARS + rb'][^>]*+>))'
# 
# EXTERNAL_LINK_URL_TAIL = (
#     rb'(?>' + LITERAL_IPV6_AND_TAIL + rb'|' + VALID_URL_CHARS + rb')')
# 
# INVALID_URL_CHARS = rb' \t\n"<>\[\]'
# 
# PARSABLE_TAG_EXTENSION_NAME = regex_pattern(
#     _parsable_tag_extensions)
# 
# START_TAG_PATTERN = ( # noqa
#     rb'(?<start_tag>'
#         rb'<{name}' + ATTRS_PATTERN +
#         rb'[' + SPACE_CHARS + rb']*+'
#         rb'(?:(?<self_closing>/[' + SPACE_CHARS + b']*+>)|>)'
#     rb')')
# 
# def parse_to_spans(byte_array: bytearray) -> Dict[str, list]:
#     """Calculate and set self._type_to_spans.
# 
#     Extracted spans will be removed from byte_array.
#     The result is a dictionary containing lists of spans:
#     {
#         'Comment': comment_spans,
#         'ExtTag': extension_tag_spans,
#         'Parameter': parameter_spans,
#         'ParserFunction': parser_function_spans,
#         'Template': template_spans,
#         'WikiLink': wikilink_spans,
#     }
#     """
#     comment_spans = []
#     cms_append = comment_spans.append
#     extension_tag_spans = []
#     ets_append = extension_tag_spans.append
#     wikilink_spans = []
#     wls_append = wikilink_spans.append
#     parameter_spans = []
#     pms_append = parameter_spans.append
#     parser_function_spans = []
#     pfs_append = parser_function_spans.append
#     template_spans = []
#     tls_append = template_spans.append
#     # <extension tags>
#     extract_tag_extensions(
#         byte_array, ets_append, cms_append, None, None,
#         pms_append, pfs_append, tls_append, wls_append)
#     _parse_sub_spans(
#         byte_array, 0, None, pms_append, pfs_append, tls_append, wls_append)
#     return {
#         'Comment': comment_spans,
#         'ExtensionTag': sorted(extension_tag_spans),
#         'Parameter': sorted(parameter_spans),
#         'ParserFunction': sorted(parser_function_spans),
#         'Template': sorted(template_spans),
#         'WikiLink': sorted(wikilink_spans)}


from bisect import bisect_left, bisect_right, insort_right
from copy import deepcopy
from html import unescape
from itertools import islice
from operator import attrgetter
from typing import (
    Dict, Generator, Iterable, List, MutableSequence, Optional, Tuple, Union)
from warnings import warn
from regex import DOTALL, IGNORECASE, MULTILINE, VERBOSE, \
    compile as regex_compile, finditer, search, match
from wcwidth import wcswidth
from ._config import (
    _HTML_TAG_NAME, _bare_external_link_schemes, _tag_extensions,
    regex_pattern, _parsable_tag_extensions)
from ._spans import (
    BARE_EXTERNAL_LINK, END_TAG_PATTERN, EXTERNAL_LINK_URL_TAIL,
    INVALID_URL_CHARS, PARSABLE_TAG_EXTENSION_NAME, START_TAG_PATTERN,
    parse_to_spans)
    from ._tag import Tag
    from ._parser_function import ParserFunction
    from ._template import Template
    from ._wikilink import WikiLink
    from ._comment_bold_italic import Comment, Bold, Italic
    from ._externallink import ExternalLink
    from ._section import Section
    from ._wikilist import WikiList, LIST_PATTERN_FORMAT
    from ._table import Table
    from ._parameter import Parameter
                'stop index out of range or start is after the stop')
        return start + ss, stop + ss

    def __setitem__(self, key: Union[slice, int], value: str) -> None:
        """Set a new string for the given slice or character index.

        Use this method instead of calling `insert` and `del` consecutively.
        By doing so only one of the `_insert_update` and
        `_shrink_update` functions will be called and the performance
        will improve.
        """
        abs_start, abs_stop = self._check_index(key)
        # Update lststr
        lststr = self._lststr
        lststr0 = lststr[0]
        lststr[0] = lststr0[:abs_start] + value + lststr0[abs_stop:]
        # Set the length of all subspans to zero because
        # they are all being replaced.
        self._close_subspans(abs_start, abs_stop)
        # Update the other spans according to the new length.
        val_ba = bytearray(value, 'ascii', 'replace')
        len_change = len(value) + abs_start - abs_stop
        if len_change > 0:
            self._insert_update(abs_start, len_change)
        elif len_change < 0:
            self._del_update(
                rmstart=abs_stop + len_change,  # new stop
                rmstop=abs_stop)  # old stop
        # Add the newly added spans contained in the value.
        type_to_spans = self._type_to_spans

# Path: wikitextparser/_config.py
# def _plant_trie(strings: _Iterable[str]) -> dict:
# def _pattern(trie: dict) -> str:
# def regex_pattern(words: _Iterable[str]) -> bytes:
# _HTML_TAG_NAME = regex_pattern(_valid_html_tag_names) + br'\b'
# 
# Path: wikitextparser/_spans.py
# BARE_EXTERNAL_LINK = BARE_EXTERNAL_LINK_SCHEMES + EXTERNAL_LINK_URL_TAIL
# 
# END_TAG_PATTERN = rb'(?<end_tag></{name}(?:>|[' + SPACE_CHARS + rb'][^>]*+>))'
# 
# EXTERNAL_LINK_URL_TAIL = (
#     rb'(?>' + LITERAL_IPV6_AND_TAIL + rb'|' + VALID_URL_CHARS + rb')')
# 
# INVALID_URL_CHARS = rb' \t\n"<>\[\]'
# 
# PARSABLE_TAG_EXTENSION_NAME = regex_pattern(
#     _parsable_tag_extensions)
# 
# START_TAG_PATTERN = ( # noqa
#     rb'(?<start_tag>'
#         rb'<{name}' + ATTRS_PATTERN +
#         rb'[' + SPACE_CHARS + rb']*+'
#         rb'(?:(?<self_closing>/[' + SPACE_CHARS + b']*+>)|>)'
#     rb')')
# 
# def parse_to_spans(byte_array: bytearray) -> Dict[str, list]:
#     """Calculate and set self._type_to_spans.
# 
#     Extracted spans will be removed from byte_array.
#     The result is a dictionary containing lists of spans:
#     {
#         'Comment': comment_spans,
#         'ExtTag': extension_tag_spans,
#         'Parameter': parameter_spans,
#         'ParserFunction': parser_function_spans,
#         'Template': template_spans,
#         'WikiLink': wikilink_spans,
#     }
#     """
#     comment_spans = []
#     cms_append = comment_spans.append
#     extension_tag_spans = []
#     ets_append = extension_tag_spans.append
#     wikilink_spans = []
#     wls_append = wikilink_spans.append
#     parameter_spans = []
#     pms_append = parameter_spans.append
#     parser_function_spans = []
#     pfs_append = parser_function_spans.append
#     template_spans = []
#     tls_append = template_spans.append
#     # <extension tags>
#     extract_tag_extensions(
#         byte_array, ets_append, cms_append, None, None,
#         pms_append, pfs_append, tls_append, wls_append)
#     _parse_sub_spans(
#         byte_array, 0, None, pms_append, pfs_append, tls_append, wls_append)
#     return {
#         'Comment': comment_spans,
#         'ExtensionTag': sorted(extension_tag_spans),
#         'Parameter': sorted(parameter_spans),
#         'ParserFunction': sorted(parser_function_spans),
#         'Template': sorted(template_spans),
#         'WikiLink': sorted(wikilink_spans)}


# Path: wikitextparser/_wikitext.py
from bisect import bisect_left, bisect_right, insort_right
from copy import deepcopy
from html import unescape
from itertools import islice
from operator import attrgetter
from typing import (
    Dict, Generator, Iterable, List, MutableSequence, Optional, Tuple, Union)
from warnings import warn
from regex import DOTALL, IGNORECASE, MULTILINE, VERBOSE, \
    compile as regex_compile, finditer, search, match
from wcwidth import wcswidth
from ._config import (
    _HTML_TAG_NAME, _bare_external_link_schemes, _tag_extensions,
    regex_pattern, _parsable_tag_extensions)
from ._spans import (
    BARE_EXTERNAL_LINK, END_TAG_PATTERN, EXTERNAL_LINK_URL_TAIL,
    INVALID_URL_CHARS, PARSABLE_TAG_EXTENSION_NAME, START_TAG_PATTERN,
    parse_to_spans)
    from ._tag import Tag
    from ._parser_function import ParserFunction
    from ._template import Template
    from ._wikilink import WikiLink
    from ._comment_bold_italic import Comment, Bold, Italic
    from ._externallink import ExternalLink
    from ._section import Section
    from ._wikilist import WikiList, LIST_PATTERN_FORMAT
    from ._table import Table
    from ._parameter import Parameter

                'stop index out of range or start is after the stop')
        return start + ss, stop + ss

    def __setitem__(self, key: Union[slice, int], value: str) -> None:
        """Set a new string for the given slice or character index.

        Use this method instead of calling `insert` and `del` consecutively.
        By doing so only one of the `_insert_update` and
        `_shrink_update` functions will be called and the performance
        will improve.
        """
        abs_start, abs_stop = self._check_index(key)
        # Update lststr
        lststr = self._lststr
        lststr0 = lststr[0]
        lststr[0] = lststr0[:abs_start] + value + lststr0[abs_stop:]
        # Set the length of all subspans to zero because
        # they are all being replaced.
        self._close_subspans(abs_start, abs_stop)
        # Update the other spans according to the new length.
        val_ba = bytearray(value, 'ascii', 'replace')
        len_change = len(value) + abs_start - abs_stop
        if len_change > 0:
            self._insert_update(abs_start, len_change)
        elif len_change < 0:
            self._del_update(
                rmstart=abs_stop + len_change,  # new stop
                rmstop=abs_stop)  # old stop
        # Add the newly added spans contained in the value.
        type_to_spans = self._type_to_spans

        for type_, value_spans in parse_to_spans(val_ba).items():