# Path: permuta/misc/display.py
# class HTMLViewer:
#     """A class for opening html text in browser."""
# 
#     _THREAD_WAIT_TIME: ClassVar[float] = 5  # seconds
# 
#     @staticmethod
#     def _remove_file_thread(fname: str) -> None:
#         time.sleep(HTMLViewer._THREAD_WAIT_TIME)
#         if os.path.exists(fname):
#             os.remove(fname)
# 
#     @staticmethod
#     def _remove_file(fname: str) -> None:
#         threading.Thread(target=HTMLViewer._remove_file_thread, args=(fname,)).start()
# 
#     @staticmethod
#     def open_html(html: str) -> None:
#         """Open and render html string in browser."""
#         with tempfile.NamedTemporaryFile(
#             "r+", suffix=".html", delete=False
#         ) as html_file:
#             html_file.write(html)
#             webbrowser.open_new_tab(f"file://{html_file.name}")
#             HTMLViewer._remove_file(html_file.name)
# 
#     @staticmethod
#     def open_svg(svg: str) -> None:
#         """Open and render svg image string in browser."""
#         HTMLViewer.open_html(f"<html><body>{svg}</body></html>")
# 
# Path: permuta/misc/math.py
# def is_prime(n: int) -> bool:
#     """Primality test using 6k+-1 optimization."""
#     if n <= 3:
#         return n > 1
#     if n % 2 == 0 or n % 3 == 0:
#         return False
#     i = 5
#     while i ** 2 <= n:
#         if n % i == 0 or n % (i + 2) == 0:
#             return False
#         i += 6
#     return True
# 
# Path: permuta/patterns/patt.py
# class Patt(abc.ABC):
#     """A permutation pattern, e.g. classical, bivincular and mesh patterns."""
# 
#     def avoided_by(self, *patts: "Patt") -> bool:
#         """Check if self is avoided by all the provided patterns."""
#         return all(self not in patt for patt in patts)
# 
#     def contained_in(self, *patts: "Patt") -> bool:
#         """Check if self is a pattern of all the provided patterns."""
#         return all(self in patt for patt in patts)
# 
#     def count_occurrences_in(self, patt: "Patt") -> int:
#         """Count the number of occurrences of self in the pattern."""
#         return sum(1 for _ in self.occurrences_in(patt))
# 
#     @abc.abstractmethod
#     def occurrences_in(
#         self, patt: "Patt", *args, **kwargs
#     ) -> Iterator[Tuple[int, ...]]:
#         """Find all indices of occurrences of self in pattern."""
# 
#     @abc.abstractmethod
#     def __len__(self) -> int:
#         """The length of the pattern."""
# 
#     @abc.abstractmethod
#     def get_perm(self) -> "Perm":
#         """Get the permutation part of the pattern"""
# 
#     @abc.abstractmethod
#     def __contains__(self, patt: object) -> bool:
#         """Does pattern contains another?"""


import bisect
import collections
import functools
import itertools
import math
import numbers
import operator
import random
from typing import (
    TYPE_CHECKING,
    Callable,
    Deque,
    Dict,
    Iterable,
    Iterator,
    List,
    Optional,
    Set,
    Tuple,
    TypeVar,
    Union,
)
from permuta.misc import HTMLViewer
from permuta.misc.math import is_prime
from .patt import Patt
        return "".join(
            [
                "\\begin{tikzpicture}[scale=.3,baseline=(current bounding box.center)]",
                f"\n{tab}\\foreach \\x in {{1,...,{n}}} {{\n{tab*2}",
                f"\\draw[ultra thin] (\\x,0)--(\\x,{n+1}); %vline\n{tab*2}",
                f"\\draw[ultra thin] (0,\\x)--({n+1},\\x); %hline\n{tab}}}\n{tab}",
                f"\n{tab}".join(
                    f"\\draw[fill=black] ({idx + 1},{val + 1}) circle (5pt);"
                    for (idx, val) in enumerate(self)
                ),
                "\n\\end{tikzpicture}",
            ]
        )

    def containment_to_tikz(self, pattern: "Perm") -> Iterator[str]:
        """Return the tikz picture of the pattern within self."""
        return (self._pattern_to_tikz(occ) for occ in self.occurrences_of(pattern))

    def _pattern_to_tikz(self, occurrence: Tuple[int, ...]) -> str:
        init = self.to_tikz()
        init = init[0 : init.rfind("\\end{tikzpicture}")]
        reds = "\n".join(
            f"    \\draw[red] ({idx + 1},{self[idx] + 1}) circle (10pt);"
            for idx in occurrence
        )
        return f"{init}{reds}\n\\end{{tikzpicture}}"

    def show(self, scale: float = 1.0) -> None:
        """Open a browser tab and display permutation graphically. Image can be
        enlarged with scale parameter"""

# Path: permuta/misc/display.py
# class HTMLViewer:
#     """A class for opening html text in browser."""
# 
#     _THREAD_WAIT_TIME: ClassVar[float] = 5  # seconds
# 
#     @staticmethod
#     def _remove_file_thread(fname: str) -> None:
#         time.sleep(HTMLViewer._THREAD_WAIT_TIME)
#         if os.path.exists(fname):
#             os.remove(fname)
# 
#     @staticmethod
#     def _remove_file(fname: str) -> None:
#         threading.Thread(target=HTMLViewer._remove_file_thread, args=(fname,)).start()
# 
#     @staticmethod
#     def open_html(html: str) -> None:
#         """Open and render html string in browser."""
#         with tempfile.NamedTemporaryFile(
#             "r+", suffix=".html", delete=False
#         ) as html_file:
#             html_file.write(html)
#             webbrowser.open_new_tab(f"file://{html_file.name}")
#             HTMLViewer._remove_file(html_file.name)
# 
#     @staticmethod
#     def open_svg(svg: str) -> None:
#         """Open and render svg image string in browser."""
#         HTMLViewer.open_html(f"<html><body>{svg}</body></html>")
# 
# Path: permuta/misc/math.py
# def is_prime(n: int) -> bool:
#     """Primality test using 6k+-1 optimization."""
#     if n <= 3:
#         return n > 1
#     if n % 2 == 0 or n % 3 == 0:
#         return False
#     i = 5
#     while i ** 2 <= n:
#         if n % i == 0 or n % (i + 2) == 0:
#             return False
#         i += 6
#     return True
# 
# Path: permuta/patterns/patt.py
# class Patt(abc.ABC):
#     """A permutation pattern, e.g. classical, bivincular and mesh patterns."""
# 
#     def avoided_by(self, *patts: "Patt") -> bool:
#         """Check if self is avoided by all the provided patterns."""
#         return all(self not in patt for patt in patts)
# 
#     def contained_in(self, *patts: "Patt") -> bool:
#         """Check if self is a pattern of all the provided patterns."""
#         return all(self in patt for patt in patts)
# 
#     def count_occurrences_in(self, patt: "Patt") -> int:
#         """Count the number of occurrences of self in the pattern."""
#         return sum(1 for _ in self.occurrences_in(patt))
# 
#     @abc.abstractmethod
#     def occurrences_in(
#         self, patt: "Patt", *args, **kwargs
#     ) -> Iterator[Tuple[int, ...]]:
#         """Find all indices of occurrences of self in pattern."""
# 
#     @abc.abstractmethod
#     def __len__(self) -> int:
#         """The length of the pattern."""
# 
#     @abc.abstractmethod
#     def get_perm(self) -> "Perm":
#         """Get the permutation part of the pattern"""
# 
#     @abc.abstractmethod
#     def __contains__(self, patt: object) -> bool:
#         """Does pattern contains another?"""


# Path: permuta/patterns/perm.py
import bisect
import collections
import functools
import itertools
import math
import numbers
import operator
import random
from typing import (
    TYPE_CHECKING,
    Callable,
    Deque,
    Dict,
    Iterable,
    Iterator,
    List,
    Optional,
    Set,
    Tuple,
    TypeVar,
    Union,
)
from permuta.misc import HTMLViewer
from permuta.misc.math import is_prime
from .patt import Patt

        return "".join(
            [
                "\\begin{tikzpicture}[scale=.3,baseline=(current bounding box.center)]",
                f"\n{tab}\\foreach \\x in {{1,...,{n}}} {{\n{tab*2}",
                f"\\draw[ultra thin] (\\x,0)--(\\x,{n+1}); %vline\n{tab*2}",
                f"\\draw[ultra thin] (0,\\x)--({n+1},\\x); %hline\n{tab}}}\n{tab}",
                f"\n{tab}".join(
                    f"\\draw[fill=black] ({idx + 1},{val + 1}) circle (5pt);"
                    for (idx, val) in enumerate(self)
                ),
                "\n\\end{tikzpicture}",
            ]
        )

    def containment_to_tikz(self, pattern: "Perm") -> Iterator[str]:
        """Return the tikz picture of the pattern within self."""
        return (self._pattern_to_tikz(occ) for occ in self.occurrences_of(pattern))

    def _pattern_to_tikz(self, occurrence: Tuple[int, ...]) -> str:
        init = self.to_tikz()
        init = init[0 : init.rfind("\\end{tikzpicture}")]
        reds = "\n".join(
            f"    \\draw[red] ({idx + 1},{self[idx] + 1}) circle (10pt);"
            for idx in occurrence
        )
        return f"{init}{reds}\n\\end{{tikzpicture}}"

    def show(self, scale: float = 1.0) -> None:
        """Open a browser tab and display permutation graphically. Image can be
        enlarged with scale parameter"""

        HTMLViewer.open_svg(self.to_svg(image_scale=scale))