"""
Copyright (C) 2025 yuygfgg

This file is part of Vapoursynth-llvmexpr.

Vapoursynth-llvmexpr is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Vapoursynth-llvmexpr is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Vapoursynth-llvmexpr.  If not, see <https://www.gnu.org/licenses/>.
"""

import time
import abc
import sys
import math
import os
import json
import argparse
import platform
import fnmatch
from typing import Dict, List, Optional, Union, Tuple, Any, Iterable

import vapoursynth as vs

try:
    import cpuinfo
except ImportError:
    cpuinfo = None

core = vs.core


def _parse_csv_list(values: Optional[Union[str, List[str]]]) -> List[str]:
    if values is None:
        return []
    if isinstance(values, list):
        items: List[str] = []
        for item in values:
            items.extend(_parse_csv_list(item))
        return items
    return [v.strip() for v in values.split(",") if v.strip()]


def _unique_keep_order(items: Iterable[str]) -> List[str]:
    seen = set()
    out: List[str] = []
    for item in items:
        if item in seen:
            continue
        seen.add(item)
        out.append(item)
    return out

_PRESET_FORMAT_NAMES = [
    "GRAYS",
    "GRAY8",
    "GRAY16",
    "RGB24",
    "RGBH",
    "RGBS",
    "YUV420P8",
    "YUV420P16",
    "YUV422P16",
    "YUV444P10",
]


def _backfill_preset_format_constants() -> None:
    preset_enum = getattr(vs, "PresetFormat", None) or getattr(vs, "PresetVideoFormat", None)
    if preset_enum is None:
        return

    members: dict[str, object] = {}
    preset_members = getattr(preset_enum, "__members__", None)
    if isinstance(preset_members, dict):
        for member_name, member in preset_members.items():
            members[str(member_name).upper()] = member
    else:
        for member_name in dir(preset_enum):
            if member_name.startswith("_"):
                continue
            members[member_name.upper()] = getattr(preset_enum, member_name)

    for name in _PRESET_FORMAT_NAMES:
        if hasattr(vs, name):
            continue
        member = members.get(name)
        if member is not None:
            setattr(vs, name, member)

def _try_load_plugins(plugin_paths: List[str], *, quiet: bool) -> None:
    for path in plugin_paths:
        if not path:
            continue
        try:
            core.std.LoadPlugin(path=path)
            if not quiet:
                print(f"Loaded plugin: {path}")
        except Exception as e:
            if not quiet:
                print(f"Warning: failed to load plugin {path!r}: {type(e).__name__}: {e}")


class ExprBackend(abc.ABC):
    """Abstract base class for an expression evaluation backend."""

    @abc.abstractmethod
    def get_name(self) -> str:
        """Returns the unique name of the backend."""
        raise NotImplementedError

    @abc.abstractmethod
    def filter(self, clip: vs.VideoNode, expr: str) -> Optional[vs.VideoNode]:
        """
        Applies the expression to the clip.
        Returns None if the backend is not available.
        """
        raise NotImplementedError


class LlvmexprBackend(ExprBackend):
    """Backend for the current project's llvmexpr.Expr"""

    def get_name(self) -> str:
        return "llvmexpr"

    def filter(self, clip: vs.VideoNode, expr: str) -> Optional[vs.VideoNode]:
        return core.llvmexpr.Expr(clips=[clip], expr=expr)


class VkExprBackend(ExprBackend):
    """Backend for the current projects's llvmexpr.VkExpr"""

    def get_name(self) -> str:
        return "VkExpr"

    def filter(self, clip: vs.VideoNode, expr: str) -> Optional[vs.VideoNode]:
        return core.llvmexpr.VkExpr(clips=[clip], expr=expr)

class AkarinExprBackend(ExprBackend):

    def get_name(self) -> str:
        return "akarin"

    def filter(self, clip: vs.VideoNode, expr: str) -> Optional[vs.VideoNode]:
        if not hasattr(core, "akarin"):
            return None
        return core.akarin.Expr(clips=[clip], expr=expr)


# Default number of frames for tests that don't specify a custom value
DEFAULT_FRAME_COUNT = 30000

# Test configuration: either a string (expression) or tuple (expression, frame_count)
TEST_CASES: Dict[str, Union[str, Tuple[str, int]]] = {
    "simple arithmetic": "x 1.5 * 16 +",
    "logical condition": "x 128 > x 0 ?",
    "data range clamp": "x 16 235 clip",
    "complex math chain": "x sqrt sin exp log",
    "trigonometry coords": "Y X atan2 pi / 2 *",
    "power function": "x 2 pow",
    "stack dup": "x dup *",
    "named variables": "x 2 / my_var! my_var@ my_var@ *",
    "static relative access": "x[-1,0] x[1,0] + x[0,-1] + x[0,1] + 4 /",
    "dynamic absolute access": "width X - 1 - Y x[]",
    "bitwise and": "x 255 bitand",
    "gain": "x 32768 / 0.86 pow 65535 *",
    "power with loop": "x base! 1 result! 4 counter! #loop result@ base@ * result! counter@ 1 - counter! counter@ loop# result@",
    "3D rendering": (
        "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 width 2 / swap1178 drop N 0.02 * swap1177 drop dup1176 cos swap781 drop -100 dup781 * swap686 drop dup1176 sin swap585 drop 100 dup585 * swap485 drop dup685 dup485 - swap384 drop N 0.015 * swap284 drop dup283 sin swap185 drop 20 dup185 * swap91 drop dup383 dup91 + swap1176 drop 381.174 dup1176 + swap816 drop 0 dup816 + -0.744111 * swap797 drop dup283 cos swap789 drop 20 dup789 * swap780 drop -100 dup780 + swap770 drop 0 N + 8 % 4 - abs swap705 drop 2 dup705 * swap696 drop 186.2 dup696 - swap685 drop dup769 dup685 - swap675 drop N 80 % 40 - abs swap645 drop 2 dup645 * swap634 drop 40 dup634 - 500 / swap616 drop 0.38 dup616 + swap606 drop dup605 sin swap596 drop dup674 dup596 * swap584 drop -100 dup585 * swap573 drop 100 dup781 * swap563 drop dup572 dup563 + swap552 drop 330.028 dup696 - swap515 drop dup551 dup515 - swap505 drop dup605 cos swap496 drop dup504 dup496 * swap484 drop dup583 dup484 + swap473 drop 0 dup473 + -0.668056 * swap454 drop dup796 dup454 + swap445 drop dup444 500 * swap434 drop dup815 0.668056 * swap414 drop dup472 -0.744111 * swap406 drop dup413 dup406 + swap395 drop dup394 0 < 1000000000.0 dup396 ? swap374 drop dup433 dup374 / swap364 drop dup1177 dup364 + swap355 drop X dup355 - swap344 drop height 2 / swap333 drop dup674 dup496 * swap323 drop dup484 dup686 + dup515 - swap305 drop dup304 dup596 * swap294 drop dup322 dup294 - swap283 drop dup282 500 * swap273 drop dup562 dup573 - dup91 + -381.174 - swap244 drop dup243 0.668056 * swap225 drop dup304 dup496 * swap216 drop dup583 dup216 + swap205 drop dup204 -0.744111 * swap195 drop dup224 dup195 + swap184 drop dup183 0 < 1000000000.0 dup185 ? swap165 drop dup272 dup165 / swap155 drop dup332 dup155 + swap144 drop dup504 dup596 * swap134 drop dup322 dup134 - swap125 drop dup124 500 * dup374 / swap106 drop dup332 dup106 + swap101 drop dup143 dup101 - swap90 drop dup343 dup90 * swap84 drop Y dup101 - swap73 drop dup243 -0.744111 * swap63 drop dup204 -0.668056 * swap54 drop dup62 dup54 + swap47 drop dup46 500 * dup165 / swap26 drop dup1177 dup26 + swap17 drop dup16 dup355 - swap9 drop dup72 dup9 * swap1175 drop dup83 dup1175 - swap1164 drop dup1163 0 >= swap1155 drop X dup17 - swap1147 drop dup484 dup563 + dup515 - swap1128 drop dup1127 dup596 * swap1118 drop dup322 dup1118 - swap1109 drop dup1108 500 * swap1102 drop dup562 dup485 - dup91 + -381.174 - swap1074 drop dup1073 0.668056 * swap1057 drop dup1127 dup496 * swap1047 drop dup583 dup1047 + swap1038 drop dup1037 -0.744111 * swap1031 drop dup1056 dup1031 + swap1020 drop dup1019 0 < 1000000000.0 dup1021 ? swap1002 drop dup1101 dup1002 / swap995 drop dup332 dup995 + swap984 drop dup983 dup144 - swap974 drop dup1146 dup974 * swap965 drop Y dup144 - swap958 drop dup1073 -0.744111 * swap947 drop dup1037 -0.668056 * swap937 drop dup946 dup937 + swap928 drop dup927 500 * dup1002 / swap911 drop dup1177 dup911 + swap901 drop dup900 dup17 - swap892 drop dup957 dup892 * swap885 drop dup964 dup885 - swap874 drop dup873 0 >= swap864 drop dup1154 dup864 and swap855 drop X dup901 - swap848 drop dup100 dup984 - swap839 drop dup847 dup839 * swap838 drop Y dup984 - swap837 drop dup354 dup901 - swap836 drop dup836 dup836 * swap835 drop dup837 dup835 - swap834 drop dup833 0 >= swap833 drop dup854 dup833 and swap832 drop dup1163 0 <= swap831 drop dup873 0 <= swap830 drop dup830 dup830 and swap829 drop dup833 0 <= swap828 drop dup828 dup828 and swap827 drop dup831 dup827 or swap826 drop dup373 1000000000.0 < swap825 drop dup164 1000000000.0 < swap824 drop dup824 dup824 and swap823 drop dup1001 1000000000.0 < swap822 drop dup822 dup822 and swap821 drop dup825 dup821 and swap820 drop dup16 X - swap819 drop dup983 Y - swap818 drop dup818 dup818 * swap817 drop dup900 X - swap815 drop dup143 Y - swap814 drop dup814 dup814 * swap813 drop dup816 dup813 - swap812 drop dup983 dup101 - swap811 drop dup8 dup811 * swap810 drop dup900 dup355 - swap809 drop dup808 dup90 * swap808 drop dup809 dup808 - swap807 drop dup811 dup807 / swap806 drop dup805 dup374 * swap805 drop dup100 Y - swap804 drop dup814 dup804 * swap803 drop dup354 X - swap802 drop dup801 dup818 * swap801 drop dup802 dup801 - dup807 / swap800 drop dup799 dup165 * swap799 drop dup804 dup799 + swap798 drop 1 dup806 - dup800 - dup1002 * swap796 drop dup797 dup796 + swap795 drop dup819 dup795 1000000000.0 ? swap794 drop dup572 dup686 + dup515 - swap793 drop dup792 dup596 * swap792 drop dup322 dup792 - swap791 drop dup790 500 * swap790 drop dup685 dup573 - dup91 + -381.174 - swap788 drop dup787 0.668056 * swap787 drop dup792 dup496 * swap786 drop dup583 dup786 + swap785 drop dup784 -0.744111 * swap784 drop dup786 dup784 + swap783 drop dup782 0 < 1000000000.0 dup784 ? swap782 drop dup789 dup782 / swap779 drop dup332 dup779 + swap778 drop dup777 dup101 - swap777 drop dup343 dup777 * swap776 drop dup787 -0.744111 * swap775 drop dup784 -0.668056 * swap774 drop dup774 dup774 + swap773 drop dup772 500 * dup782 / swap772 drop dup1177 dup772 + swap771 drop dup770 dup355 - swap769 drop dup72 dup769 * swap768 drop dup775 dup768 - swap767 drop dup766 0 >= swap766 drop X dup771 - swap765 drop dup143 dup778 - swap764 drop dup764 dup764 * swap763 drop Y dup778 - swap762 drop dup16 dup771 - swap761 drop dup761 dup761 * swap760 drop dup762 dup760 - swap759 drop dup758 0 >= swap758 drop dup765 dup758 and swap757 drop dup100 dup144 - swap756 drop dup1146 dup756 * swap755 drop dup354 dup17 - swap754 drop dup957 dup754 * swap753 drop dup754 dup753 - swap752 drop dup751 0 >= swap751 drop dup756 dup751 and swap750 drop dup766 0 <= swap749 drop dup758 0 <= swap748 drop dup748 dup748 and swap747 drop dup751 0 <= swap746 drop dup746 dup746 and swap745 drop dup749 dup745 or swap744 drop dup781 1000000000.0 < swap743 drop dup824 dup743 and dup824 and swap742 drop dup743 dup742 and swap741 drop dup770 X - swap740 drop dup739 dup814 * swap739 drop dup777 Y - swap738 drop dup818 dup738 * swap737 drop dup738 dup737 - swap736 drop dup768 dup90 * swap735 drop dup8 dup777 * swap734 drop dup734 dup734 - swap733 drop dup735 dup733 / swap732 drop dup731 dup374 * swap731 drop dup818 dup804 * swap730 drop dup801 dup814 * swap729 drop dup729 dup729 - dup733 / swap728 drop dup727 dup782 * swap727 drop dup730 dup727 + swap726 drop 1 dup732 - dup728 - dup165 * swap725 drop dup725 dup725 + swap724 drop dup740 dup724 1000000000.0 ? swap723 drop 100 dup780 + dup685 - swap722 drop dup721 dup596 * swap721 drop dup720 dup484 + swap720 drop dup719 -0.668056 * swap719 drop dup796 dup719 + swap718 drop dup717 500 * swap717 drop dup719 -0.744111 * swap716 drop dup413 dup716 + swap715 drop dup714 0 < 1000000000.0 dup716 ? swap714 drop dup716 dup714 / swap713 drop dup1177 dup713 + swap712 drop X dup712 - swap711 drop dup721 dup496 * swap710 drop dup709 dup294 - swap709 drop dup708 500 * swap708 drop dup720 dup216 + swap707 drop dup706 -0.744111 * swap706 drop dup224 dup706 + swap704 drop dup703 0 < 1000000000.0 dup705 ? swap703 drop dup707 dup703 / swap702 drop dup332 dup702 + swap701 drop dup709 dup134 - swap700 drop dup699 500 * dup714 / swap699 drop dup332 dup699 + swap698 drop dup700 dup698 - swap697 drop dup710 dup697 * swap695 drop Y dup698 - swap694 drop dup706 -0.668056 * swap693 drop dup62 dup693 + swap692 drop dup691 500 * dup703 / swap691 drop dup1177 dup691 + swap690 drop dup689 dup712 - swap689 drop dup693 dup689 * swap688 drop dup694 dup688 - swap687 drop dup686 0 >= swap684 drop X dup690 - swap683 drop dup709 dup792 - swap682 drop dup681 500 * swap681 drop dup720 dup786 + swap680 drop dup679 -0.744111 * swap679 drop dup786 dup679 + swap678 drop dup677 0 < 1000000000.0 dup679 ? swap677 drop dup680 dup677 / swap676 drop dup332 dup676 + swap674 drop dup673 dup701 - swap673 drop dup682 dup673 * swap672 drop Y dup701 - swap671 drop dup679 -0.668056 * swap670 drop dup774 dup670 + swap669 drop dup668 500 * dup677 / swap668 drop dup1177 dup668 + swap667 drop dup666 dup690 - swap666 drop dup670 dup666 * swap665 drop dup671 dup665 - swap664 drop dup663 0 >= swap663 drop dup683 dup663 and swap662 drop X dup667 - swap661 drop dup697 dup674 - swap660 drop dup660 dup660 * swap659 drop Y dup674 - swap658 drop dup711 dup667 - swap657 drop dup657 dup657 * swap656 drop dup658 dup656 - swap655 drop dup654 0 >= swap654 drop dup661 dup654 and swap653 drop dup686 0 <= swap652 drop dup663 0 <= swap651 drop dup651 dup651 and swap650 drop dup654 0 <= swap649 drop dup649 dup649 and swap648 drop dup652 dup648 or swap647 drop dup713 1000000000.0 < swap646 drop dup702 1000000000.0 < swap644 drop dup645 dup644 and swap643 drop dup676 1000000000.0 < swap642 drop dup642 dup642 and swap641 drop dup646 dup641 and swap640 drop dup689 X - swap639 drop dup673 Y - swap638 drop dup638 dup638 * swap637 drop dup666 X - swap636 drop dup700 Y - swap635 drop dup635 dup635 * swap633 drop dup636 dup633 - swap632 drop dup673 dup698 - swap631 drop dup688 dup631 * swap630 drop dup666 dup712 - swap629 drop dup628 dup697 * swap628 drop dup629 dup628 - swap627 drop dup631 dup627 / swap626 drop dup625 dup714 * swap625 drop dup697 Y - swap624 drop dup635 dup624 * swap623 drop dup711 X - swap622 drop dup621 dup638 * swap621 drop dup622 dup621 - dup627 / swap620 drop dup619 dup703 * swap619 drop dup624 dup619 + swap618 drop 1 dup626 - dup620 - dup677 * swap617 drop dup617 dup617 + swap615 drop dup639 dup615 1000000000.0 ? swap614 drop dup709 dup1118 - swap613 drop dup612 500 * swap612 drop dup720 dup1047 + swap611 drop dup610 -0.744111 * swap610 drop dup1056 dup610 + swap609 drop dup608 0 < 1000000000.0 dup610 ? swap608 drop dup611 dup608 / swap607 drop dup332 dup607 + swap605 drop dup604 dup698 - swap604 drop dup710 dup604 * swap603 drop dup610 -0.668056 * swap602 drop dup946 dup602 + swap601 drop dup600 500 * dup608 / swap600 drop dup1177 dup600 + swap599 drop dup598 dup712 - swap598 drop dup693 dup598 * swap597 drop dup602 dup597 - swap595 drop dup594 0 >= swap594 drop X dup599 - swap593 drop dup700 dup605 - swap592 drop dup592 dup592 * swap591 drop Y dup605 - swap590 drop dup689 dup599 - swap589 drop dup589 dup589 * swap588 drop dup590 dup588 - swap587 drop dup586 0 >= swap586 drop dup593 dup586 and swap583 drop dup697 dup701 - swap582 drop dup682 dup582 * swap581 drop dup711 dup690 - swap580 drop dup670 dup580 * swap579 drop dup580 dup579 - swap578 drop dup577 0 >= swap577 drop dup582 dup577 and swap576 drop dup594 0 <= swap575 drop dup586 0 <= swap574 drop dup574 dup574 and swap572 drop dup577 0 <= swap571 drop dup571 dup571 and swap570 drop dup575 dup570 or swap569 drop dup607 1000000000.0 < swap568 drop dup645 dup568 and dup644 and swap567 drop dup568 dup567 and swap566 drop dup598 X - swap565 drop dup564 dup635 * swap564 drop dup604 Y - swap562 drop dup638 dup562 * swap561 drop dup563 dup561 - swap560 drop dup597 dup697 * swap559 drop dup688 dup604 * swap558 drop dup558 dup558 - swap557 drop dup559 dup557 / swap556 drop dup555 dup714 * swap555 drop dup638 dup624 * swap554 drop dup621 dup635 * swap553 drop dup553 dup553 - dup557 / swap551 drop dup550 dup608 * swap550 drop dup554 dup550 + swap549 drop 1 dup556 - dup551 - dup703 * swap548 drop dup548 dup548 + swap547 drop dup565 dup547 1000000000.0 ? swap546 drop dup700 dup984 - swap545 drop dup847 dup545 * swap544 drop dup689 dup901 - swap543 drop dup836 dup543 * swap542 drop dup543 dup542 - swap541 drop dup540 0 >= swap540 drop dup604 dup701 - swap539 drop dup682 dup539 * swap538 drop dup598 dup690 - swap537 drop dup670 dup537 * swap536 drop dup537 dup536 - swap535 drop dup534 0 >= swap534 drop dup539 dup534 and swap533 drop dup983 dup605 - swap532 drop dup592 dup532 * swap531 drop dup900 dup599 - swap530 drop dup589 dup530 * swap529 drop dup530 dup529 - swap528 drop dup527 0 >= swap527 drop dup532 dup527 and swap526 drop dup540 0 <= swap525 drop dup534 0 <= swap524 drop dup524 dup524 and swap523 drop dup527 0 <= swap522 drop dup522 dup522 and swap521 drop dup525 dup521 or swap520 drop dup821 dup644 and dup568 and swap519 drop dup519 dup519 and swap518 drop dup560 dup564 - swap517 drop dup604 dup984 - swap516 drop dup542 dup516 * swap514 drop dup598 dup901 - swap513 drop dup512 dup545 * swap512 drop dup513 dup512 - swap511 drop dup516 dup511 / swap510 drop dup509 dup1002 * swap509 drop dup564 dup818 * swap508 drop dup814 dup562 * swap507 drop dup507 dup507 - dup511 / swap506 drop dup505 dup703 * swap504 drop dup508 dup504 + swap503 drop 1 dup510 - dup506 - dup608 * swap502 drop dup502 dup502 + swap501 drop dup517 dup501 1000000000.0 ? swap500 drop dup143 dup984 - swap499 drop dup847 dup499 * swap498 drop dup16 dup901 - swap497 drop dup836 dup497 * swap495 drop dup497 dup495 - swap494 drop dup493 0 >= swap493 drop dup700 dup144 - swap492 drop dup1146 dup492 * swap491 drop dup689 dup17 - swap490 drop dup957 dup490 * swap489 drop dup490 dup489 - swap488 drop dup487 0 >= swap487 drop dup492 dup487 and swap486 drop dup983 dup701 - swap483 drop dup682 dup483 * swap482 drop dup900 dup690 - swap481 drop dup670 dup481 * swap480 drop dup481 dup480 - swap479 drop dup478 0 >= swap478 drop dup485 dup478 and swap477 drop dup493 0 <= swap476 drop dup487 0 <= swap475 drop dup475 dup475 and swap474 drop dup478 0 <= swap472 drop dup473 dup472 and swap471 drop dup476 dup471 or swap470 drop dup821 dup824 and dup644 and swap469 drop dup469 dup469 and swap468 drop dup818 dup635 * swap467 drop dup638 dup814 * swap466 drop dup466 dup466 - swap465 drop dup496 dup545 * swap464 drop dup542 dup499 * swap463 drop dup463 dup463 - swap462 drop dup464 dup462 / swap461 drop dup460 dup1002 * swap460 drop dup638 dup818 * swap459 drop dup814 dup635 * swap458 drop dup458 dup458 - dup462 / swap457 drop dup456 dup165 * swap456 drop dup459 dup456 + swap455 drop 1 dup461 - dup457 - dup703 * swap453 drop dup454 dup453 + swap452 drop dup467 dup452 1000000000.0 ? swap451 drop dup673 dup101 - swap450 drop dup343 dup450 * swap449 drop dup666 dup355 - swap448 drop dup72 dup448 * swap447 drop dup448 dup447 - swap446 drop dup445 0 >= swap444 drop dup777 dup674 - swap443 drop dup660 dup443 * swap442 drop dup770 dup667 - swap441 drop dup657 dup441 * swap440 drop dup441 dup440 - swap439 drop dup438 0 >= swap438 drop dup443 dup438 and swap437 drop dup100 dup778 - swap436 drop dup764 dup436 * swap435 drop dup354 dup771 - swap433 drop dup761 dup433 * swap432 drop dup434 dup432 - swap431 drop dup430 0 >= swap430 drop dup436 dup430 and swap429 drop dup445 0 <= swap428 drop dup438 0 <= swap427 drop dup427 dup427 and swap426 drop dup430 0 <= swap425 drop dup425 dup425 and swap424 drop dup428 dup424 or swap423 drop dup824 dup642 and dup743 and swap422 drop dup422 dup422 and swap421 drop dup635 dup738 * swap420 drop dup739 dup638 * swap419 drop dup419 dup419 - swap418 drop dup447 dup777 * swap417 drop dup768 dup450 * swap416 drop dup416 dup416 - swap415 drop dup417 dup415 / swap413 drop dup412 dup374 * swap412 drop dup739 dup804 * swap411 drop dup801 dup738 * swap410 drop dup410 dup410 - dup415 / swap409 drop dup408 dup677 * swap408 drop dup411 dup408 + swap407 drop 1 dup413 - dup409 - dup782 * swap405 drop dup406 dup405 + swap404 drop dup420 dup404 1000000000.0 ? swap403 drop dup697 dup101 - swap402 drop dup343 dup402 * swap401 drop dup711 dup355 - swap400 drop dup72 dup400 * swap399 drop dup400 dup399 - swap398 drop dup397 0 >= swap397 drop dup710 dup631 * swap396 drop dup693 dup629 * swap394 drop dup395 dup394 - swap393 drop dup392 0 >= swap392 drop dup396 dup392 and swap391 drop dup100 dup674 - swap390 drop dup660 dup390 * swap389 drop dup354 dup667 - swap388 drop dup657 dup388 * swap387 drop dup388 dup387 - swap386 drop dup385 0 >= swap385 drop dup390 dup385 and swap383 drop dup397 0 <= swap382 drop dup392 0 <= swap381 drop dup381 dup381 and swap380 drop dup385 0 <= swap379 drop dup379 dup379 and swap378 drop dup382 dup378 or swap377 drop dup824 dup646 and dup642 and swap376 drop dup376 dup376 and swap375 drop dup620 dup623 - swap373 drop dup399 dup450 * swap372 drop dup447 dup402 * swap371 drop dup371 dup371 - swap370 drop dup372 dup370 / swap369 drop dup368 dup374 * swap368 drop dup635 dup804 * swap367 drop dup801 dup638 * swap366 drop dup366 dup366 - dup370 / swap365 drop dup364 dup714 * swap363 drop dup367 dup363 + swap362 drop 1 dup369 - dup365 - dup677 * swap361 drop dup361 dup361 + swap360 drop dup374 dup360 1000000000.0 ? swap359 drop dup673 dup778 - swap358 drop dup764 dup358 * swap357 drop dup666 dup771 - swap356 drop dup761 dup356 * swap354 drop dup356 dup354 - swap353 drop dup352 0 >= swap352 drop dup700 dup674 - swap351 drop dup660 dup351 * swap350 drop dup689 dup667 - swap349 drop dup657 dup349 * swap348 drop dup349 dup348 - swap347 drop dup346 0 >= swap346 drop dup351 dup346 and swap345 drop dup777 dup701 - swap343 drop dup682 dup343 * swap342 drop dup770 dup690 - swap341 drop dup670 dup341 * swap340 drop dup341 dup340 - swap339 drop dup338 0 >= swap338 drop dup344 dup338 and swap337 drop dup352 0 <= swap336 drop dup346 0 <= swap335 drop dup335 dup335 and swap334 drop dup338 0 <= swap332 drop dup333 dup332 and swap331 drop dup336 dup331 or swap330 drop dup742 dup642 and dup644 and swap329 drop dup329 dup329 and swap328 drop dup632 dup637 - swap327 drop dup700 dup778 - swap326 drop dup355 dup326 * swap325 drop dup689 dup771 - swap324 drop dup323 dup358 * swap322 drop dup324 dup322 - swap321 drop dup326 dup321 / swap320 drop dup319 dup782 * swap319 drop dup638 dup738 * swap318 drop dup739 dup635 * swap317 drop dup317 dup317 - dup321 / swap316 drop dup315 dup677 * swap315 drop dup318 dup315 + swap314 drop 1 dup320 - dup316 - dup703 * swap313 drop dup313 dup313 + swap312 drop dup327 dup312 1000000000.0 ? swap311 drop dup764 dup326 * swap310 drop dup761 dup324 * swap309 drop dup309 dup309 - swap308 drop dup307 0 >= swap307 drop dup143 dup701 - swap306 drop dup682 dup306 * swap304 drop dup16 dup690 - swap303 drop dup670 dup303 * swap302 drop dup303 dup302 - swap301 drop dup300 0 >= swap300 drop dup306 dup300 and swap299 drop dup777 dup144 - swap298 drop dup1146 dup298 * swap297 drop dup770 dup17 - swap296 drop dup957 dup296 * swap295 drop dup296 dup295 - swap293 drop dup292 0 >= swap292 drop dup298 dup292 and swap291 drop dup307 0 <= swap290 drop dup300 0 <= swap289 drop dup289 dup289 and swap288 drop dup292 0 <= swap287 drop dup287 dup287 and swap286 drop dup290 dup286 or swap285 drop dup742 dup644 and dup824 and swap282 drop dup284 dup282 and swap281 drop dup465 dup467 - swap280 drop dup323 dup764 * swap279 drop dup760 dup326 * swap278 drop dup278 dup278 - swap277 drop dup279 dup277 / swap276 drop dup275 dup782 * swap275 drop dup736 dup739 - dup277 / swap274 drop dup273 dup703 * swap272 drop dup274 dup272 + swap271 drop 1 dup276 - dup274 - dup165 * swap270 drop dup270 dup270 + swap269 drop dup280 dup269 1000000000.0 ? swap268 drop dup604 dup101 - swap267 drop dup343 dup267 * swap266 drop dup598 dup355 - swap265 drop dup72 dup265 * swap264 drop dup265 dup264 - swap263 drop dup262 0 >= swap262 drop dup697 dup605 - swap261 drop dup592 dup261 * swap260 drop dup711 dup599 - swap259 drop dup589 dup259 * swap258 drop dup259 dup258 - swap257 drop dup256 0 >= swap256 drop dup261 dup256 and swap255 drop dup100 dup698 - swap254 drop dup710 dup254 * swap253 drop dup354 dup712 - swap252 drop dup693 dup252 * swap251 drop dup252 dup251 - swap250 drop dup249 0 >= swap249 drop dup254 dup249 and swap248 drop dup262 0 <= swap247 drop dup256 0 <= swap246 drop dup246 dup246 and swap245 drop dup249 0 <= swap243 drop dup244 dup243 and swap242 drop dup247 dup242 or swap241 drop dup824 dup568 and dup646 and swap240 drop dup240 dup240 and swap239 drop dup564 dup624 * swap238 drop dup621 dup562 * swap237 drop dup237 dup237 - swap236 drop dup264 dup402 * swap235 drop dup399 dup267 * swap234 drop dup234 dup234 - swap233 drop dup235 dup233 / swap232 drop dup231 dup374 * swap231 drop dup621 dup804 * swap230 drop dup801 dup624 * swap229 drop dup229 dup229 - dup233 / swap228 drop dup227 dup608 * swap227 drop dup230 dup227 + swap226 drop 1 dup232 - dup228 - dup714 * swap224 drop dup225 dup224 + swap223 drop dup238 dup223 1000000000.0 ? swap222 drop dup343 dup811 * swap221 drop dup72 dup809 * swap220 drop dup220 dup220 - swap219 drop dup218 0 >= swap218 drop dup847 dup516 * swap217 drop dup836 dup513 * swap215 drop dup216 dup215 - swap214 drop dup213 0 >= swap213 drop dup217 dup213 and swap212 drop dup100 dup605 - swap211 drop dup592 dup211 * swap210 drop dup354 dup599 - swap209 drop dup589 dup209 * swap208 drop dup209 dup208 - swap207 drop dup206 0 >= swap206 drop dup211 dup206 and swap204 drop dup218 0 <= swap203 drop dup213 0 <= swap202 drop dup202 dup202 and swap201 drop dup206 0 <= swap200 drop dup200 dup200 and swap199 drop dup203 dup199 or swap198 drop dup824 dup822 and dup568 and swap197 drop dup197 dup197 and swap196 drop dup506 dup508 - swap194 drop dup808 dup267 * swap193 drop dup264 dup811 * swap192 drop dup192 dup192 - swap191 drop dup193 dup191 / swap190 drop dup189 dup374 * swap189 drop dup564 dup804 * swap188 drop dup801 dup562 * swap187 drop dup187 dup187 - dup191 / swap186 drop dup185 dup1002 * swap183 drop dup188 dup183 + swap182 drop 1 dup190 - dup186 - dup608 * swap181 drop dup181 dup181 + swap180 drop dup195 dup180 1000000000.0 ? swap179 drop dup221 dup179 < swap178 drop dup177 dup222 dup180 ? swap177 drop dup267 dup177 < swap176 drop dup175 dup268 dup178 ? swap175 drop dup310 dup175 < swap174 drop dup173 dup311 dup176 ? swap173 drop dup358 dup173 < swap172 drop dup171 dup359 dup174 ? swap171 drop dup402 dup171 < swap170 drop dup169 dup403 dup172 ? swap169 drop dup450 dup169 < swap168 drop dup167 dup451 dup170 ? swap167 drop dup499 dup167 < swap166 drop dup165 dup500 dup168 ? swap164 drop dup545 dup164 < swap163 drop dup162 dup546 dup165 ? swap162 drop dup613 dup162 < swap161 drop dup160 dup614 dup163 ? swap160 drop dup722 dup160 < swap159 drop dup158 dup723 dup161 ? swap158 drop dup793 dup158 < swap157 drop dup156 dup794 dup159 ? 1000000000.0 < swap156 drop dup282 dup125 - swap154 drop dup1001 dup374 - swap153 drop dup153 dup153 * swap152 drop dup164 dup374 - swap151 drop dup1108 dup125 - swap150 drop dup150 dup150 * swap149 drop dup151 dup149 - swap148 drop dup147 2 pow swap147 drop dup927 dup445 - swap146 drop dup150 dup146 * swap145 drop dup46 dup445 - swap143 drop dup142 dup153 * swap142 drop dup144 dup142 - swap141 drop dup140 2 pow swap140 drop dup146 dup140 + swap139 drop dup142 dup150 * swap138 drop dup153 dup146 * swap137 drop dup137 dup137 - swap136 drop dup135 2 pow swap135 drop dup138 dup135 + sqrt swap133 drop dup147 dup133 / swap132 drop dup780 2 pow 0.25 + swap131 drop dup584 2 pow swap130 drop dup130 dup130 + sqrt swap129 drop dup780 dup129 / swap128 drop dup127 -0.744111 * swap127 drop 0.5 dup129 / swap126 drop dup125 dup596 * swap124 drop dup584 dup129 / swap123 drop dup122 dup496 * swap122 drop dup123 dup122 + swap121 drop dup120 -0.668056 * swap120 drop dup126 dup120 + swap119 drop dup131 dup119 * swap118 drop dup140 dup133 / swap117 drop dup125 dup496 * swap116 drop dup122 dup596 * swap115 drop dup115 dup115 - swap114 drop dup116 dup114 * swap113 drop dup117 dup113 + swap112 drop dup135 dup133 / swap111 drop dup127 0.668056 * swap110 drop dup120 -0.744111 * swap109 drop dup109 dup109 + swap108 drop dup110 dup108 * swap107 drop dup111 dup107 + 0 max 0.8 * swap105 drop 0.2 dup105 + swap104 drop 0.816497 dup596 * swap103 drop 0.408248 dup496 * swap102 drop dup102 dup102 + swap100 drop dup99 -0.668056 * swap99 drop 0.303782 dup99 + swap98 drop dup131 dup98 * swap97 drop 0.816497 dup496 * swap96 drop 0.408248 dup596 * swap95 drop dup95 dup95 - swap94 drop dup116 dup94 * swap93 drop dup96 dup93 + swap92 drop 0 dup100 + -0.744111 * swap89 drop -0.272733 dup89 + swap88 drop dup110 dup88 * swap87 drop dup91 dup87 + 0 max 0.6 * swap86 drop dup103 dup86 + 1 min 0.7 * swap85 drop dup819 dup85 0 ? swap83 drop dup790 dup125 - swap82 drop dup81 dup151 * swap81 drop dup781 dup374 - swap80 drop dup79 dup154 * swap79 drop dup80 dup79 - swap78 drop dup77 2 pow swap77 drop dup79 dup143 * swap76 drop dup772 dup445 - swap75 drop dup74 dup151 * swap74 drop dup75 dup74 - swap72 drop dup71 2 pow swap71 drop dup76 dup71 + swap70 drop dup74 dup154 * swap69 drop dup81 dup143 * swap68 drop dup68 dup68 - swap67 drop dup66 2 pow swap66 drop dup69 dup66 + sqrt swap65 drop dup77 dup65 / swap64 drop dup63 dup119 * swap62 drop dup71 dup65 / swap61 drop dup60 dup114 * swap60 drop dup61 dup60 + swap59 drop dup66 dup65 / swap58 drop dup57 dup108 * swap57 drop dup58 dup57 + 0 max 0.8 * swap56 drop 0.2 dup56 + swap55 drop dup63 dup98 * swap53 drop dup60 dup94 * swap52 drop dup52 dup52 + swap51 drop dup57 dup88 * swap50 drop dup50 dup50 + 0 max 0.6 * swap49 drop dup54 dup49 + 1 min 0.7 * swap48 drop dup740 dup48 0 ? swap46 drop dup708 dup700 - swap45 drop dup676 dup714 - swap44 drop dup44 dup44 * swap43 drop dup702 dup714 - swap42 drop dup681 dup700 - swap41 drop dup41 dup41 * swap40 drop dup42 dup40 - swap39 drop dup38 2 pow swap38 drop dup668 dup718 - swap37 drop dup41 dup37 * swap36 drop dup691 dup718 - swap35 drop dup34 dup44 * swap34 drop dup35 dup34 - swap33 drop dup32 2 pow swap32 drop dup37 dup32 + swap31 drop dup34 dup41 * swap30 drop dup44 dup37 * swap29 drop dup29 dup29 - swap28 drop dup27 2 pow swap27 drop dup30 dup27 + sqrt swap25 drop dup38 dup25 / swap24 drop dup23 dup119 * swap23 drop dup32 dup25 / swap22 drop dup21 dup114 * swap21 drop dup22 dup21 + swap20 drop dup27 dup25 / swap19 drop dup18 dup108 * swap18 drop dup19 dup18 + 0 max 0.8 * swap16 drop 0.2 dup16 + swap15 drop dup23 dup98 * swap14 drop dup21 dup94 * swap13 drop dup13 dup13 + swap12 drop dup18 dup88 * swap11 drop dup11 dup11 + 0 max 0.6 * swap10 drop dup14 dup10 + 1 min 1.1 * swap8 drop dup639 dup8 0 ? swap7 drop dup612 dup700 - swap6 drop dup5 dup42 * swap5 drop dup607 dup714 - swap4 drop dup3 dup45 * swap3 drop dup4 dup3 - swap2 drop dup1 2 pow swap drop dup3 dup35 * swap1174 drop dup600 dup718 - swap1173 drop dup1172 dup42 * swap1172 drop dup1173 dup1172 - swap1171 drop dup1170 2 pow swap1170 drop dup dup1170 + swap1169 drop dup1172 dup45 * swap1168 drop dup5 dup35 * swap1167 drop dup1167 dup1167 - swap1166 drop dup1165 2 pow swap1165 drop dup1168 dup1165 + sqrt swap1163 drop dup1 dup1163 / swap1162 drop dup1161 dup119 * swap1161 drop dup1170 dup1163 / swap1160 drop dup1159 dup114 * swap1159 drop dup1160 dup1159 + swap1158 drop dup1165 dup1163 / swap1157 drop dup1156 dup108 * swap1156 drop dup1157 dup1156 + 0 max 0.8 * swap1154 drop 0.2 dup1154 + swap1153 drop dup1161 dup98 * swap1152 drop dup1159 dup94 * swap1151 drop dup1151 dup1151 + swap1150 drop dup1156 dup88 * swap1149 drop dup1149 dup1149 + 0 max 0.6 * swap1148 drop dup1152 dup1148 + 1 min 1.1 * swap1146 drop dup565 dup1146 0 ? swap1145 drop dup708 dup1109 - swap1144 drop dup607 dup1002 - swap1143 drop dup1143 dup1143 * swap1142 drop dup702 dup1002 - swap1141 drop dup612 dup1109 - swap1140 drop dup1140 dup1140 * swap1139 drop dup1141 dup1139 - swap1138 drop dup1137 2 pow swap1137 drop dup600 dup928 - swap1136 drop dup1140 dup1136 * swap1135 drop dup691 dup928 - swap1134 drop dup1133 dup1143 * swap1133 drop dup1134 dup1133 - swap1132 drop dup1131 2 pow swap1131 drop dup1136 dup1131 + swap1130 drop dup1133 dup1140 * swap1129 drop dup1143 dup1136 * swap1127 drop dup1128 dup1127 - swap1126 drop dup1125 2 pow swap1125 drop dup1129 dup1125 + sqrt swap1124 drop dup1137 dup1124 / swap1123 drop dup1122 dup119 * swap1122 drop dup1131 dup1124 / swap1121 drop dup1120 dup114 * swap1120 drop dup1121 dup1120 + swap1119 drop dup1125 dup1124 / swap1117 drop dup1116 dup108 * swap1116 drop dup1118 dup1116 + 0 max 0.8 * swap1115 drop 0.2 dup1115 + swap1114 drop dup1122 dup98 * swap1113 drop dup1120 dup94 * swap1112 drop dup1112 dup1112 + swap1111 drop dup1116 dup88 * swap1110 drop dup1110 dup1110 + 0 max 0.6 * swap1108 drop dup1113 dup1108 + 1 min 1 * swap1107 drop dup517 dup1107 0 ? swap1106 drop dup282 dup1109 - swap1105 drop dup1104 dup1141 * swap1104 drop dup164 dup1002 - swap1103 drop dup1102 dup1144 * swap1101 drop dup1103 dup1101 - swap1100 drop dup1099 2 pow swap1099 drop dup1102 dup1134 * swap1098 drop dup46 dup928 - swap1097 drop dup1096 dup1141 * swap1096 drop dup1097 dup1096 - swap1095 drop dup1094 2 pow swap1094 drop dup1098 dup1094 + swap1093 drop dup1096 dup1144 * swap1092 drop dup1104 dup1134 * swap1091 drop dup1091 dup1091 - swap1090 drop dup1089 2 pow swap1089 drop dup1092 dup1089 + sqrt swap1088 drop dup1099 dup1088 / swap1087 drop dup1086 dup119 * swap1086 drop dup1094 dup1088 / swap1085 drop dup1084 dup114 * swap1084 drop dup1085 dup1084 + swap1083 drop dup1089 dup1088 / swap1082 drop dup1081 dup108 * swap1081 drop dup1082 dup1081 + 0 max 0.8 * swap1080 drop 0.2 dup1080 + swap1079 drop dup1086 dup98 * swap1078 drop dup1084 dup94 * swap1077 drop dup1077 dup1077 + swap1076 drop dup1081 dup88 * swap1075 drop dup1075 dup1075 + 0 max 0.6 * swap1073 drop dup1078 dup1073 + 1 min 1 * swap1072 drop dup467 dup1072 0 ? swap1071 drop dup681 dup125 - swap1070 drop dup1069 dup80 * swap1069 drop dup676 dup374 - swap1068 drop dup1067 dup82 * swap1067 drop dup1068 dup1067 - swap1066 drop dup1065 2 pow swap1065 drop dup1067 dup75 * swap1064 drop dup668 dup445 - swap1063 drop dup1062 dup80 * swap1062 drop dup1063 dup1062 - swap1061 drop dup1060 2 pow swap1060 drop dup1064 dup1060 + swap1059 drop dup1062 dup82 * swap1058 drop dup1069 dup75 * swap1056 drop dup1057 dup1056 - swap1055 drop dup1054 2 pow swap1054 drop dup1058 dup1054 + sqrt swap1053 drop dup1065 dup1053 / swap1052 drop dup1051 dup119 * swap1051 drop dup1060 dup1053 / swap1050 drop dup1049 dup114 * swap1049 drop dup1050 dup1049 + swap1048 drop dup1054 dup1053 / swap1046 drop dup1045 dup108 * swap1045 drop dup1047 dup1045 + 0 max 0.8 * swap1044 drop 0.2 dup1044 + swap1043 drop dup1051 dup98 * swap1042 drop dup1049 dup94 * swap1041 drop dup1041 dup1041 + swap1040 drop dup1045 dup88 * swap1039 drop dup1039 dup1039 + 0 max 0.6 * swap1037 drop dup1042 dup1037 + 1 min 0.9 * swap1036 drop dup420 dup1036 0 ? swap1035 drop dup699 dup125 - swap1034 drop dup1033 dup1068 * swap1033 drop dup713 dup374 - swap1032 drop dup1031 dup1070 * swap1030 drop dup1032 dup1030 - swap1029 drop dup1028 2 pow swap1028 drop dup1031 dup1063 * swap1027 drop dup717 dup445 - swap1026 drop dup1025 dup1068 * swap1025 drop dup1026 dup1025 - swap1024 drop dup1023 2 pow swap1023 drop dup1027 dup1023 + swap1022 drop dup1025 dup1070 * swap1021 drop dup1033 dup1063 * swap1019 drop dup1020 dup1019 - swap1018 drop dup1017 2 pow swap1017 drop dup1021 dup1017 + sqrt swap1016 drop dup1028 dup1016 / swap1015 drop dup1014 dup119 * swap1014 drop dup1023 dup1016 / swap1013 drop dup1012 dup114 * swap1012 drop dup1013 dup1012 + swap1011 drop dup1017 dup1016 / swap1010 drop dup1009 dup108 * swap1009 drop dup1010 dup1009 + 0 max 0.8 * swap1008 drop 0.2 dup1008 + swap1007 drop dup1014 dup98 * swap1006 drop dup1012 dup94 * swap1005 drop dup1005 dup1005 + swap1004 drop dup1009 dup88 * swap1003 drop dup1003 dup1003 + 0 max 0.6 * swap1001 drop dup1006 dup1001 + 1 min 0.9 * swap1000 drop dup374 dup1000 0 ? swap999 drop dup681 dup791 - swap998 drop dup702 dup782 - swap997 drop dup997 dup997 * swap996 drop dup676 dup782 - swap994 drop dup708 dup791 - swap993 drop dup993 dup993 * swap992 drop dup995 dup992 - swap991 drop dup990 2 pow swap990 drop dup691 dup773 - swap989 drop dup993 dup989 * swap988 drop dup668 dup773 - swap987 drop dup986 dup997 * swap986 drop dup987 dup986 - swap985 drop dup984 2 pow swap983 drop dup989 dup983 + swap982 drop dup986 dup993 * swap981 drop dup997 dup989 * swap980 drop dup980 dup980 - swap979 drop dup978 2 pow swap978 drop dup981 dup978 + sqrt swap977 drop dup990 dup977 / swap976 drop dup975 dup119 * swap975 drop dup984 dup977 / swap973 drop dup972 dup114 * swap972 drop dup974 dup972 + swap971 drop dup978 dup977 / swap970 drop dup969 dup108 * swap969 drop dup970 dup969 + 0 max 0.8 * swap968 drop 0.2 dup968 + swap967 drop dup975 dup98 * swap966 drop dup972 dup94 * swap964 drop dup965 dup964 + swap963 drop dup969 dup88 * swap962 drop dup962 dup962 + 0 max 0.6 * swap961 drop dup966 dup961 + 1 min 0.8 * swap960 drop dup327 dup960 0 ? swap959 drop dup164 dup782 - swap957 drop dup992 dup957 * swap956 drop dup282 dup791 - swap955 drop dup996 dup955 * swap954 drop dup955 dup954 - swap953 drop dup952 2 pow swap952 drop dup46 dup773 - swap951 drop dup996 dup951 * swap950 drop dup988 dup957 * swap949 drop dup949 dup949 - swap948 drop dup947 2 pow swap946 drop dup951 dup946 + swap945 drop dup988 dup955 * swap944 drop dup992 dup951 * swap943 drop dup943 dup943 - swap942 drop dup941 2 pow swap941 drop dup944 dup941 + sqrt swap940 drop dup952 dup940 / swap939 drop dup938 dup119 * swap938 drop dup947 dup940 / swap936 drop dup935 dup114 * swap935 drop dup937 dup935 + swap934 drop dup941 dup940 / swap933 drop dup932 dup108 * swap932 drop dup933 dup932 + 0 max 0.8 * swap931 drop 0.2 dup931 + swap930 drop dup938 dup98 * swap929 drop dup935 dup94 * swap927 drop dup928 dup927 + swap926 drop dup932 dup88 * swap925 drop dup925 dup925 + 0 max 0.6 * swap924 drop dup929 dup924 + 1 min 0.8 * swap923 drop dup280 dup923 0 ? swap922 drop dup612 dup125 - swap921 drop dup920 dup1032 * swap920 drop dup607 dup374 - swap919 drop dup918 dup1034 * swap918 drop dup919 dup918 - swap917 drop dup916 2 pow swap916 drop dup918 dup1026 * swap915 drop dup600 dup445 - swap914 drop dup913 dup1032 * swap913 drop dup914 dup913 - swap912 drop dup911 2 pow swap910 drop dup915 dup910 + swap909 drop dup913 dup1034 * swap908 drop dup920 dup1026 * swap907 drop dup907 dup907 - swap906 drop dup905 2 pow swap905 drop dup908 dup905 + sqrt swap904 drop dup916 dup904 / swap903 drop dup902 dup119 * swap902 drop dup911 dup904 / swap900 drop dup899 dup114 * swap899 drop dup901 dup899 + swap898 drop dup905 dup904 / swap897 drop dup896 dup108 * swap896 drop dup897 dup896 + 0 max 0.8 * swap895 drop 0.2 dup895 + swap894 drop dup902 dup98 * swap893 drop dup899 dup94 * swap891 drop dup892 dup891 + swap890 drop dup896 dup88 * swap889 drop dup889 dup889 + 0 max 0.6 * swap888 drop dup893 dup888 + 1 min 1 * swap887 drop dup238 dup887 0 ? swap886 drop dup149 dup919 * swap884 drop dup152 dup921 * swap883 drop dup883 dup883 - swap882 drop dup881 2 pow swap881 drop dup152 dup914 * swap880 drop dup145 dup919 * swap879 drop dup879 dup879 - swap878 drop dup877 2 pow swap877 drop dup880 dup877 + swap876 drop dup145 dup921 * swap875 drop dup149 dup914 * swap873 drop dup874 dup873 - swap872 drop dup871 2 pow swap871 drop dup875 dup871 + sqrt swap870 drop dup881 dup870 / swap869 drop dup868 dup119 * swap868 drop dup877 dup870 / swap867 drop dup866 dup114 * swap866 drop dup867 dup866 + swap865 drop dup871 dup870 / swap863 drop dup862 dup108 * swap862 drop dup864 dup862 + 0 max 0.8 * swap861 drop 0.2 dup861 + swap860 drop dup868 dup98 * swap859 drop dup866 dup94 * swap858 drop dup858 dup858 + swap857 drop dup862 dup88 * swap856 drop dup856 dup856 + 0 max 0.6 * swap854 drop dup859 dup854 + 1 min 1 * swap853 drop dup195 dup853 0 ? swap852 drop dup177 dup886 dup853 ? swap851 drop dup175 dup922 dup852 ? swap850 drop dup173 dup959 dup851 ? swap849 drop dup171 dup999 dup850 ? swap847 drop dup169 dup1035 dup848 ? swap846 drop dup167 dup1071 dup847 ? swap845 drop dup165 dup1106 dup846 ? swap844 drop dup162 dup1145 dup845 ? swap843 drop dup160 dup7 dup844 ? swap842 drop dup158 dup46 dup843 ? swap841 drop dup156 dup83 dup842 ? swap840 drop dup155 dup840 0 ? swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop",
        2000,
    ),
    "3D rendering 2 (icosahedron)": (
        "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 width 2 / swap101 drop height 2 / swap100 drop height 6 / swap61 drop N 10 / swap65 drop N 10 / swap64 drop 0 dup61 + 2 / swap66 drop 0 dup65 + cos swap99 drop dup64 sin swap63 drop dup63 cos swap98 drop dup63 sin swap62 drop -1 dup66 * swap58 drop 1.61803 dup66 * swap57 drop 0 dup66 * swap56 drop 1 dup66 * swap43 drop 1.61803 dup66 * swap42 drop 0 dup66 * swap41 drop -1 dup66 * swap38 drop -1.61803 dup66 * swap37 drop 0 dup66 * swap36 drop 1 dup66 * swap33 drop -1.61803 dup66 * swap32 drop 0 dup66 * swap31 drop 0 dup66 * swap28 drop -1 dup66 * swap27 drop 1.61803 dup66 * swap26 drop 0 dup66 * swap23 drop 1 dup66 * swap22 drop 1.61803 dup66 * swap21 drop 0 dup66 * swap18 drop -1 dup66 * swap17 drop -1.61803 dup66 * swap16 drop 0 dup66 * swap13 drop 1 dup66 * swap12 drop -1.61803 dup66 * swap11 drop 1.61803 dup66 * swap8 drop 0 dup66 * swap7 drop -1 dup66 * swap6 drop 1.61803 dup66 * swap3 drop 0 dup66 * swap2 drop 1 dup66 * swap drop -1.61803 dup66 * swap53 drop 0 dup66 * swap52 drop -1 dup66 * swap51 drop -1.61803 dup66 * swap48 drop 0 dup66 * swap47 drop 1 dup66 * swap46 drop dup57 swap119 drop dup56 swap116 drop dup55 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap60 drop dup57 swap110 drop dup56 swap108 drop dup55 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap59 drop dup42 swap119 drop dup41 swap116 drop dup40 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap45 drop dup42 swap110 drop dup41 swap108 drop dup40 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap44 drop dup37 swap119 drop dup36 swap116 drop dup35 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap40 drop dup37 swap110 drop dup36 swap108 drop dup35 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap39 drop dup32 swap119 drop dup31 swap116 drop dup30 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap35 drop dup32 swap110 drop dup31 swap108 drop dup30 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap34 drop dup27 swap119 drop dup26 swap116 drop dup25 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap30 drop dup27 swap110 drop dup26 swap108 drop dup25 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap29 drop dup22 swap119 drop dup21 swap116 drop dup20 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap25 drop dup22 swap110 drop dup21 swap108 drop dup20 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap24 drop dup17 swap119 drop dup16 swap116 drop dup15 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap20 drop dup17 swap110 drop dup16 swap108 drop dup15 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap19 drop dup12 swap119 drop dup11 swap116 drop dup10 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap15 drop dup12 swap110 drop dup11 swap108 drop dup10 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap14 drop dup7 swap119 drop dup6 swap116 drop dup5 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap10 drop dup7 swap110 drop dup6 swap108 drop dup5 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap9 drop dup2 swap119 drop dup1 swap116 drop dup swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap5 drop dup2 swap110 drop dup1 swap108 drop dup swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap4 drop dup52 swap119 drop dup51 swap116 drop dup50 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap55 drop dup52 swap110 drop dup51 swap108 drop dup50 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap54 drop dup47 swap119 drop dup46 swap116 drop dup45 swap114 drop dup115 dup99 * dup114 dup64 * - swap115 drop dup115 dup63 * dup114 dup100 * + swap113 drop dup118 swap118 drop dup117 dup98 * dup113 dup63 * + swap117 drop dup117 -1 * dup62 * dup113 dup99 * + swap112 drop dup114 0 * dup112 + 5 + swap111 drop dup100 dup117 500 * dup112 / + swap50 drop dup47 swap110 drop dup46 swap108 drop dup45 swap105 drop dup107 dup99 * dup105 dup64 * - swap107 drop dup107 dup63 * dup105 dup100 * + swap104 drop dup109 swap109 drop dup108 dup98 * dup104 dup63 * + 0 * dup109 + -1 * dup62 * dup104 dup99 * + swap103 drop dup106 swap106 drop dup102 5 + swap102 drop dup99 dup106 500 * dup103 / + swap49 drop dup59 swap123 drop dup58 swap121 drop dup44 swap122 drop dup43 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap97 drop dup59 swap123 drop dup58 swap121 drop dup24 swap122 drop dup23 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap96 drop dup59 swap123 drop dup58 swap121 drop dup14 swap122 drop dup13 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap85 drop dup59 swap123 drop dup58 swap121 drop dup54 swap122 drop dup53 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap74 drop dup59 swap123 drop dup58 swap121 drop dup49 swap122 drop dup48 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap73 drop dup44 swap123 drop dup43 swap121 drop dup24 swap122 drop dup23 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap72 drop dup44 swap123 drop dup43 swap121 drop dup14 swap122 drop dup13 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap71 drop dup44 swap123 drop dup43 swap121 drop dup9 swap122 drop dup8 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap70 drop dup44 swap123 drop dup43 swap121 drop dup4 swap122 drop dup3 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap69 drop dup39 swap123 drop dup38 swap121 drop dup34 swap122 drop dup33 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap68 drop dup39 swap123 drop dup38 swap121 drop dup29 swap122 drop dup28 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap95 drop dup39 swap123 drop dup38 swap121 drop dup19 swap122 drop dup18 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap94 drop dup39 swap123 drop dup38 swap121 drop dup54 swap122 drop dup53 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap93 drop dup39 swap123 drop dup38 swap121 drop dup49 swap122 drop dup48 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap92 drop dup34 swap123 drop dup33 swap121 drop dup29 swap122 drop dup28 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap91 drop dup34 swap123 drop dup33 swap121 drop dup19 swap122 drop dup18 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap90 drop dup34 swap123 drop dup33 swap121 drop dup9 swap122 drop dup8 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap89 drop dup34 swap123 drop dup33 swap121 drop dup4 swap122 drop dup3 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap88 drop dup29 swap123 drop dup28 swap121 drop dup24 swap122 drop dup23 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap87 drop dup29 swap123 drop dup28 swap121 drop dup4 swap122 drop dup3 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap86 drop dup29 swap123 drop dup28 swap121 drop dup49 swap122 drop dup48 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap84 drop dup24 swap123 drop dup23 swap121 drop dup4 swap122 drop dup3 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap83 drop dup24 swap123 drop dup23 swap121 drop dup49 swap122 drop dup48 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap82 drop dup19 swap123 drop dup18 swap121 drop dup14 swap122 drop dup13 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap81 drop dup19 swap123 drop dup18 swap121 drop dup9 swap122 drop dup8 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap80 drop dup19 swap123 drop dup18 swap121 drop dup54 swap122 drop dup53 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap79 drop dup14 swap123 drop dup13 swap121 drop dup9 swap122 drop dup8 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap78 drop dup14 swap123 drop dup13 swap121 drop dup54 swap122 drop dup53 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap77 drop dup9 swap123 drop dup8 swap121 drop dup4 swap122 drop dup3 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap76 drop dup54 swap123 drop dup53 swap121 drop dup49 swap122 drop dup48 swap120 drop dup121 dup123 - swap129 drop dup119 dup121 - swap128 drop dup128 2 pow dup128 2 pow + swap125 drop X dup123 - dup129 * Y dup122 - dup129 * + dup125 / 0 1 clamp swap124 drop dup122 dup124 dup130 * + swap127 drop dup120 dup124 dup129 * + swap126 drop X dup127 - 2 pow Y dup127 - 2 pow + swap75 drop dup96 dup96 min dup85 min dup74 min dup73 min dup72 min dup71 min dup70 min dup69 min dup68 min dup95 min dup94 min dup93 min dup92 min dup91 min dup90 min dup89 min dup88 min dup87 min dup86 min dup84 min dup83 min dup82 min dup81 min dup80 min dup79 min dup78 min dup77 min dup76 min dup75 min swap67 drop 0 dup67 + 6.25 <= 0 src0 * 1 + src0 ? swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop",
        2000,
    ),
    "rotate clip": (
        "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 N + 0.0174533 * swap51 drop width 2 / swap50 drop height 2 / swap49 drop dup50 cos swap48 drop dup50 sin swap19 drop X dup50 - swap41 drop Y dup49 - swap40 drop dup40 dup48 * dup40 dup20 * + swap47 drop dup40 -1 * dup19 * dup40 dup49 * + swap46 drop dup46 dup50 + swap18 drop dup45 dup49 + swap17 drop dup17 floor swap43 drop dup16 floor swap42 drop dup17 dup43 - swap45 drop dup16 dup42 - swap44 drop dup42 1 - swap5 drop dup42 swap8 drop dup42 1 + swap7 drop dup42 2 + swap6 drop dup41 1 - swap drop dup41 swap4 drop dup41 1 + swap3 drop dup41 2 + swap2 drop dup44 1 + abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap13 drop dup44 abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap16 drop dup44 1 - abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap15 drop dup44 2 - abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap14 drop dup43 1 + abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap9 drop dup43 abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap12 drop dup43 1 - abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap11 drop dup43 2 - abs swap61 drop dup60 2 pow swap60 drop dup60 3 pow swap59 drop 7 dup59 * swap53 drop -12 dup60 * swap55 drop 0 dup53 + dup55 + 5.33333 + 6 / swap58 drop -2.33333 dup59 * swap52 drop 12 dup60 * swap54 drop -20 dup61 * swap56 drop 0 dup52 + dup54 + dup56 + 10.6667 + 6 / swap57 drop dup60 1 < dup58 dup62 2 < dup59 0 ? ? swap10 drop dup4 dup1 src0[] swap24 drop dup7 dup1 src0[] swap36 drop dup6 dup1 src0[] swap32 drop dup5 dup1 src0[] swap28 drop dup4 dup4 src0[] swap27 drop dup7 dup4 src0[] swap39 drop dup6 dup4 src0[] swap35 drop dup5 dup4 src0[] swap31 drop dup4 dup3 src0[] swap26 drop dup7 dup3 src0[] swap38 drop dup6 dup3 src0[] swap34 drop dup5 dup3 src0[] swap30 drop dup4 dup2 src0[] swap25 drop dup7 dup2 src0[] swap37 drop dup6 dup2 src0[] swap33 drop dup5 dup2 src0[] swap29 drop dup23 dup13 * dup36 dup17 * + dup32 dup16 * + dup28 dup15 * + swap20 drop dup26 dup13 * dup39 dup17 * + dup35 dup16 * + dup31 dup15 * + swap23 drop dup25 dup13 * dup38 dup17 * + dup34 dup16 * + dup30 dup15 * + swap22 drop dup24 dup13 * dup37 dup17 * + dup33 dup16 * + dup29 dup15 * + swap21 drop dup19 dup9 * dup23 dup13 * + dup22 dup12 * + dup21 dup11 * + swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop swap drop",
        3000,
    ),
    "8x8 dct": (
        "8 N! X N@ % u! Y N@ % v! X N@ / trunc N@ * block_x! Y N@ / trunc N@ * block_y! block_x@ 0 + block_y@ 0 + src0[] p_00! block_x@ 1 + block_y@ 0 + src0[] p_10! block_x@ 2 + block_y@ 0 + src0[] p_20! block_x@ 3 + block_y@ 0 + src0[] p_30! block_x@ 4 + block_y@ 0 + src0[] p_40! block_x@ 5 + block_y@ 0 + src0[] p_50! block_x@ 6 + block_y@ 0 + src0[] p_60! block_x@ 7 + block_y@ 0 + src0[] p_70! block_x@ 0 + block_y@ 1 + src0[] p_01! block_x@ 1 + block_y@ 1 + src0[] p_11! block_x@ 2 + block_y@ 1 + src0[] p_21! block_x@ 3 + block_y@ 1 + src0[] p_31! block_x@ 4 + block_y@ 1 + src0[] p_41! block_x@ 5 + block_y@ 1 + src0[] p_51! block_x@ 6 + block_y@ 1 + src0[] p_61! block_x@ 7 + block_y@ 1 + src0[] p_71! block_x@ 0 + block_y@ 2 + src0[] p_02! block_x@ 1 + block_y@ 2 + src0[] p_12! block_x@ 2 + block_y@ 2 + src0[] p_22! block_x@ 3 + block_y@ 2 + src0[] p_32! block_x@ 4 + block_y@ 2 + src0[] p_42! block_x@ 5 + block_y@ 2 + src0[] p_52! block_x@ 6 + block_y@ 2 + src0[] p_62! block_x@ 7 + block_y@ 2 + src0[] p_72! block_x@ 0 + block_y@ 3 + src0[] p_03! block_x@ 1 + block_y@ 3 + src0[] p_13! block_x@ 2 + block_y@ 3 + src0[] p_23! block_x@ 3 + block_y@ 3 + src0[] p_33! block_x@ 4 + block_y@ 3 + src0[] p_43! block_x@ 5 + block_y@ 3 + src0[] p_53! block_x@ 6 + block_y@ 3 + src0[] p_63! block_x@ 7 + block_y@ 3 + src0[] p_73! block_x@ 0 + block_y@ 4 + src0[] p_04! block_x@ 1 + block_y@ 4 + src0[] p_14! block_x@ 2 + block_y@ 4 + src0[] p_24! block_x@ 3 + block_y@ 4 + src0[] p_34! block_x@ 4 + block_y@ 4 + src0[] p_44! block_x@ 5 + block_y@ 4 + src0[] p_54! block_x@ 6 + block_y@ 4 + src0[] p_64! block_x@ 7 + block_y@ 4 + src0[] p_74! block_x@ 0 + block_y@ 5 + src0[] p_05! block_x@ 1 + block_y@ 5 + src0[] p_15! block_x@ 2 + block_y@ 5 + src0[] p_25! block_x@ 3 + block_y@ 5 + src0[] p_35! block_x@ 4 + block_y@ 5 + src0[] p_45! block_x@ 5 + block_y@ 5 + src0[] p_55! block_x@ 6 + block_y@ 5 + src0[] p_65! block_x@ 7 + block_y@ 5 + src0[] p_75! block_x@ 0 + block_y@ 6 + src0[] p_06! block_x@ 1 + block_y@ 6 + src0[] p_16! block_x@ 2 + block_y@ 6 + src0[] p_26! block_x@ 3 + block_y@ 6 + src0[] p_36! block_x@ 4 + block_y@ 6 + src0[] p_46! block_x@ 5 + block_y@ 6 + src0[] p_56! block_x@ 6 + block_y@ 6 + src0[] p_66! block_x@ 7 + block_y@ 6 + src0[] p_76! block_x@ 0 + block_y@ 7 + src0[] p_07! block_x@ 1 + block_y@ 7 + src0[] p_17! block_x@ 2 + block_y@ 7 + src0[] p_27! block_x@ 3 + block_y@ 7 + src0[] p_37! block_x@ 4 + block_y@ 7 + src0[] p_47! block_x@ 5 + block_y@ 7 + src0[] p_57! block_x@ 6 + block_y@ 7 + src0[] p_67! block_x@ 7 + block_y@ 7 + src0[] p_77! 1 u@ * pi 16 / * cos cos_u0! 3 u@ * pi 16 / * cos cos_u1! 5 u@ * pi 16 / * cos cos_u2! 7 u@ * pi 16 / * cos cos_u3! 9 u@ * pi 16 / * cos cos_u4! 11 u@ * pi 16 / * cos cos_u5! 13 u@ * pi 16 / * cos cos_u6! 15 u@ * pi 16 / * cos cos_u7! p_00@ cos_u0@ * p_10@ cos_u1@ * + p_20@ cos_u2@ * + p_30@ cos_u3@ * + p_40@ cos_u4@ * + p_50@ cos_u5@ * + p_60@ cos_u6@ * + p_70@ cos_u7@ * + row_dct_0! p_01@ cos_u0@ * p_11@ cos_u1@ * + p_21@ cos_u2@ * + p_31@ cos_u3@ * + p_41@ cos_u4@ * + p_51@ cos_u5@ * + p_61@ cos_u6@ * + p_71@ cos_u7@ * + row_dct_1! p_02@ cos_u0@ * p_12@ cos_u1@ * + p_22@ cos_u2@ * + p_32@ cos_u3@ * + p_42@ cos_u4@ * + p_52@ cos_u5@ * + p_62@ cos_u6@ * + p_72@ cos_u7@ * + row_dct_2! p_03@ cos_u0@ * p_13@ cos_u1@ * + p_23@ cos_u2@ * + p_33@ cos_u3@ * + p_43@ cos_u4@ * + p_53@ cos_u5@ * + p_63@ cos_u6@ * + p_73@ cos_u7@ * + row_dct_3! p_04@ cos_u0@ * p_14@ cos_u1@ * + p_24@ cos_u2@ * + p_34@ cos_u3@ * + p_44@ cos_u4@ * + p_54@ cos_u5@ * + p_64@ cos_u6@ * + p_74@ cos_u7@ * + row_dct_4! p_05@ cos_u0@ * p_15@ cos_u1@ * + p_25@ cos_u2@ * + p_35@ cos_u3@ * + p_45@ cos_u4@ * + p_55@ cos_u5@ * + p_65@ cos_u6@ * + p_75@ cos_u7@ * + row_dct_5! p_06@ cos_u0@ * p_16@ cos_u1@ * + p_26@ cos_u2@ * + p_36@ cos_u3@ * + p_46@ cos_u4@ * + p_56@ cos_u5@ * + p_66@ cos_u6@ * + p_76@ cos_u7@ * + row_dct_6! p_07@ cos_u0@ * p_17@ cos_u1@ * + p_27@ cos_u2@ * + p_37@ cos_u3@ * + p_47@ cos_u4@ * + p_57@ cos_u5@ * + p_67@ cos_u6@ * + p_77@ cos_u7@ * + row_dct_7! 1 v@ * pi 16 / * cos cos_v0! 3 v@ * pi 16 / * cos cos_v1! 5 v@ * pi 16 / * cos cos_v2! 7 v@ * pi 16 / * cos cos_v3! 9 v@ * pi 16 / * cos cos_v4! 11 v@ * pi 16 / * cos cos_v5! 13 v@ * pi 16 / * cos cos_v6! 15 v@ * pi 16 / * cos cos_v7! row_dct_0@ cos_v0@ * row_dct_1@ cos_v1@ * + row_dct_2@ cos_v2@ * + row_dct_3@ cos_v3@ * + row_dct_4@ cos_v4@ * + row_dct_5@ cos_v5@ * + row_dct_6@ cos_v6@ * + row_dct_7@ cos_v7@ * + final_sum! 1 N@ sqrt / inv_sqrt_N! 0.5 sqrt_2_div_N! u@ 0 = inv_sqrt_N@ sqrt_2_div_N@ ? norm_u! v@ 0 = inv_sqrt_N@ sqrt_2_div_N@ ? norm_v! final_sum@ norm_u@ * norm_v@ *",
        2000,
    ),
    "8x8 idct": (
        "8 N! X N@ % x! Y N@ % y! X N@ / trunc N@ * block_x! Y N@ / trunc N@ * block_y! block_x@ 0 + block_y@ 0 + src0[] g_00! block_x@ 1 + block_y@ 0 + src0[] g_10! block_x@ 2 + block_y@ 0 + src0[] g_20! block_x@ 3 + block_y@ 0 + src0[] g_30! block_x@ 4 + block_y@ 0 + src0[] g_40! block_x@ 5 + block_y@ 0 + src0[] g_50! block_x@ 6 + block_y@ 0 + src0[] g_60! block_x@ 7 + block_y@ 0 + src0[] g_70! block_x@ 0 + block_y@ 1 + src0[] g_01! block_x@ 1 + block_y@ 1 + src0[] g_11! block_x@ 2 + block_y@ 1 + src0[] g_21! block_x@ 3 + block_y@ 1 + src0[] g_31! block_x@ 4 + block_y@ 1 + src0[] g_41! block_x@ 5 + block_y@ 1 + src0[] g_51! block_x@ 6 + block_y@ 1 + src0[] g_61! block_x@ 7 + block_y@ 1 + src0[] g_71! block_x@ 0 + block_y@ 2 + src0[] g_02! block_x@ 1 + block_y@ 2 + src0[] g_12! block_x@ 2 + block_y@ 2 + src0[] g_22! block_x@ 3 + block_y@ 2 + src0[] g_32! block_x@ 4 + block_y@ 2 + src0[] g_42! block_x@ 5 + block_y@ 2 + src0[] g_52! block_x@ 6 + block_y@ 2 + src0[] g_62! block_x@ 7 + block_y@ 2 + src0[] g_72! block_x@ 0 + block_y@ 3 + src0[] g_03! block_x@ 1 + block_y@ 3 + src0[] g_13! block_x@ 2 + block_y@ 3 + src0[] g_23! block_x@ 3 + block_y@ 3 + src0[] g_33! block_x@ 4 + block_y@ 3 + src0[] g_43! block_x@ 5 + block_y@ 3 + src0[] g_53! block_x@ 6 + block_y@ 3 + src0[] g_63! block_x@ 7 + block_y@ 3 + src0[] g_73! block_x@ 0 + block_y@ 4 + src0[] g_04! block_x@ 1 + block_y@ 4 + src0[] g_14! block_x@ 2 + block_y@ 4 + src0[] g_24! block_x@ 3 + block_y@ 4 + src0[] g_34! block_x@ 4 + block_y@ 4 + src0[] g_44! block_x@ 5 + block_y@ 4 + src0[] g_54! block_x@ 6 + block_y@ 4 + src0[] g_64! block_x@ 7 + block_y@ 4 + src0[] g_74! block_x@ 0 + block_y@ 5 + src0[] g_05! block_x@ 1 + block_y@ 5 + src0[] g_15! block_x@ 2 + block_y@ 5 + src0[] g_25! block_x@ 3 + block_y@ 5 + src0[] g_35! block_x@ 4 + block_y@ 5 + src0[] g_45! block_x@ 5 + block_y@ 5 + src0[] g_55! block_x@ 6 + block_y@ 5 + src0[] g_65! block_x@ 7 + block_y@ 5 + src0[] g_75! block_x@ 0 + block_y@ 6 + src0[] g_06! block_x@ 1 + block_y@ 6 + src0[] g_16! block_x@ 2 + block_y@ 6 + src0[] g_26! block_x@ 3 + block_y@ 6 + src0[] g_36! block_x@ 4 + block_y@ 6 + src0[] g_46! block_x@ 5 + block_y@ 6 + src0[] g_56! block_x@ 6 + block_y@ 6 + src0[] g_66! block_x@ 7 + block_y@ 6 + src0[] g_76! block_x@ 0 + block_y@ 7 + src0[] g_07! block_x@ 1 + block_y@ 7 + src0[] g_17! block_x@ 2 + block_y@ 7 + src0[] g_27! block_x@ 3 + block_y@ 7 + src0[] g_37! block_x@ 4 + block_y@ 7 + src0[] g_47! block_x@ 5 + block_y@ 7 + src0[] g_57! block_x@ 6 + block_y@ 7 + src0[] g_67! block_x@ 7 + block_y@ 7 + src0[] g_77! 1 N@ sqrt / inv_sqrt_N! 0.5 sqrt_2_div_N! inv_sqrt_N@ norm_u0! sqrt_2_div_N@ norm_u1! sqrt_2_div_N@ norm_u2! sqrt_2_div_N@ norm_u3! sqrt_2_div_N@ norm_u4! sqrt_2_div_N@ norm_u5! sqrt_2_div_N@ norm_u6! sqrt_2_div_N@ norm_u7! inv_sqrt_N@ norm_v0! sqrt_2_div_N@ norm_v1! sqrt_2_div_N@ norm_v2! sqrt_2_div_N@ norm_v3! sqrt_2_div_N@ norm_v4! sqrt_2_div_N@ norm_v5! sqrt_2_div_N@ norm_v6! sqrt_2_div_N@ norm_v7! g_00@ norm_u0@ * norm_v0@ * ng_00! g_10@ norm_u1@ * norm_v0@ * ng_10! g_20@ norm_u2@ * norm_v0@ * ng_20! g_30@ norm_u3@ * norm_v0@ * ng_30! g_40@ norm_u4@ * norm_v0@ * ng_40! g_50@ norm_u5@ * norm_v0@ * ng_50! g_60@ norm_u6@ * norm_v0@ * ng_60! g_70@ norm_u7@ * norm_v0@ * ng_70! g_01@ norm_u0@ * norm_v1@ * ng_01! g_11@ norm_u1@ * norm_v1@ * ng_11! g_21@ norm_u2@ * norm_v1@ * ng_21! g_31@ norm_u3@ * norm_v1@ * ng_31! g_41@ norm_u4@ * norm_v1@ * ng_41! g_51@ norm_u5@ * norm_v1@ * ng_51! g_61@ norm_u6@ * norm_v1@ * ng_61! g_71@ norm_u7@ * norm_v1@ * ng_71! g_02@ norm_u0@ * norm_v2@ * ng_02! g_12@ norm_u1@ * norm_v2@ * ng_12! g_22@ norm_u2@ * norm_v2@ * ng_22! g_32@ norm_u3@ * norm_v2@ * ng_32! g_42@ norm_u4@ * norm_v2@ * ng_42! g_52@ norm_u5@ * norm_v2@ * ng_52! g_62@ norm_u6@ * norm_v2@ * ng_62! g_72@ norm_u7@ * norm_v2@ * ng_72! g_03@ norm_u0@ * norm_v3@ * ng_03! g_13@ norm_u1@ * norm_v3@ * ng_13! g_23@ norm_u2@ * norm_v3@ * ng_23! g_33@ norm_u3@ * norm_v3@ * ng_33! g_43@ norm_u4@ * norm_v3@ * ng_43! g_53@ norm_u5@ * norm_v3@ * ng_53! g_63@ norm_u6@ * norm_v3@ * ng_63! g_73@ norm_u7@ * norm_v3@ * ng_73! g_04@ norm_u0@ * norm_v4@ * ng_04! g_14@ norm_u1@ * norm_v4@ * ng_14! g_24@ norm_u2@ * norm_v4@ * ng_24! g_34@ norm_u3@ * norm_v4@ * ng_34! g_44@ norm_u4@ * norm_v4@ * ng_44! g_54@ norm_u5@ * norm_v4@ * ng_54! g_64@ norm_u6@ * norm_v4@ * ng_64! g_74@ norm_u7@ * norm_v4@ * ng_74! g_05@ norm_u0@ * norm_v5@ * ng_05! g_15@ norm_u1@ * norm_v5@ * ng_15! g_25@ norm_u2@ * norm_v5@ * ng_25! g_35@ norm_u3@ * norm_v5@ * ng_35! g_45@ norm_u4@ * norm_v5@ * ng_45! g_55@ norm_u5@ * norm_v5@ * ng_55! g_65@ norm_u6@ * norm_v5@ * ng_65! g_75@ norm_u7@ * norm_v5@ * ng_75! g_06@ norm_u0@ * norm_v6@ * ng_06! g_16@ norm_u1@ * norm_v6@ * ng_16! g_26@ norm_u2@ * norm_v6@ * ng_26! g_36@ norm_u3@ * norm_v6@ * ng_36! g_46@ norm_u4@ * norm_v6@ * ng_46! g_56@ norm_u5@ * norm_v6@ * ng_56! g_66@ norm_u6@ * norm_v6@ * ng_66! g_76@ norm_u7@ * norm_v6@ * ng_76! g_07@ norm_u0@ * norm_v7@ * ng_07! g_17@ norm_u1@ * norm_v7@ * ng_17! g_27@ norm_u2@ * norm_v7@ * ng_27! g_37@ norm_u3@ * norm_v7@ * ng_37! g_47@ norm_u4@ * norm_v7@ * ng_47! g_57@ norm_u5@ * norm_v7@ * ng_57! g_67@ norm_u6@ * norm_v7@ * ng_67! g_77@ norm_u7@ * norm_v7@ * ng_77! 2 y@ * 1 + 0 * pi 16 / * cos cos_y0! 2 y@ * 1 + 1 * pi 16 / * cos cos_y1! 2 y@ * 1 + 2 * pi 16 / * cos cos_y2! 2 y@ * 1 + 3 * pi 16 / * cos cos_y3! 2 y@ * 1 + 4 * pi 16 / * cos cos_y4! 2 y@ * 1 + 5 * pi 16 / * cos cos_y5! 2 y@ * 1 + 6 * pi 16 / * cos cos_y6! 2 y@ * 1 + 7 * pi 16 / * cos cos_y7! ng_00@ cos_y0@ * ng_01@ cos_y1@ * + ng_02@ cos_y2@ * + ng_03@ cos_y3@ * + ng_04@ cos_y4@ * + ng_05@ cos_y5@ * + ng_06@ cos_y6@ * + ng_07@ cos_y7@ * + col_sum_0! ng_10@ cos_y0@ * ng_11@ cos_y1@ * + ng_12@ cos_y2@ * + ng_13@ cos_y3@ * + ng_14@ cos_y4@ * + ng_15@ cos_y5@ * + ng_16@ cos_y6@ * + ng_17@ cos_y7@ * + col_sum_1! ng_20@ cos_y0@ * ng_21@ cos_y1@ * + ng_22@ cos_y2@ * + ng_23@ cos_y3@ * + ng_24@ cos_y4@ * + ng_25@ cos_y5@ * + ng_26@ cos_y6@ * + ng_27@ cos_y7@ * + col_sum_2! ng_30@ cos_y0@ * ng_31@ cos_y1@ * + ng_32@ cos_y2@ * + ng_33@ cos_y3@ * + ng_34@ cos_y4@ * + ng_35@ cos_y5@ * + ng_36@ cos_y6@ * + ng_37@ cos_y7@ * + col_sum_3! ng_40@ cos_y0@ * ng_41@ cos_y1@ * + ng_42@ cos_y2@ * + ng_43@ cos_y3@ * + ng_44@ cos_y4@ * + ng_45@ cos_y5@ * + ng_46@ cos_y6@ * + ng_47@ cos_y7@ * + col_sum_4! ng_50@ cos_y0@ * ng_51@ cos_y1@ * + ng_52@ cos_y2@ * + ng_53@ cos_y3@ * + ng_54@ cos_y4@ * + ng_55@ cos_y5@ * + ng_56@ cos_y6@ * + ng_57@ cos_y7@ * + col_sum_5! ng_60@ cos_y0@ * ng_61@ cos_y1@ * + ng_62@ cos_y2@ * + ng_63@ cos_y3@ * + ng_64@ cos_y4@ * + ng_65@ cos_y5@ * + ng_66@ cos_y6@ * + ng_67@ cos_y7@ * + col_sum_6! ng_70@ cos_y0@ * ng_71@ cos_y1@ * + ng_72@ cos_y2@ * + ng_73@ cos_y3@ * + ng_74@ cos_y4@ * + ng_75@ cos_y5@ * + ng_76@ cos_y6@ * + ng_77@ cos_y7@ * + col_sum_7! 2 x@ * 1 + 0 * pi 16 / * cos cos_x0! 2 x@ * 1 + 1 * pi 16 / * cos cos_x1! 2 x@ * 1 + 2 * pi 16 / * cos cos_x2! 2 x@ * 1 + 3 * pi 16 / * cos cos_x3! 2 x@ * 1 + 4 * pi 16 / * cos cos_x4! 2 x@ * 1 + 5 * pi 16 / * cos cos_x5! 2 x@ * 1 + 6 * pi 16 / * cos cos_x6! 2 x@ * 1 + 7 * pi 16 / * cos cos_x7! col_sum_0@ cos_x0@ * col_sum_1@ cos_x1@ * + col_sum_2@ cos_x2@ * + col_sum_3@ cos_x3@ * + col_sum_4@ cos_x4@ * + col_sum_5@ cos_x5@ * + col_sum_6@ cos_x6@ * + col_sum_7@ cos_x7@ * + final_pixel_value! final_pixel_value@",
        2000,
    ),
}

BACKENDS_TO_TEST: List[ExprBackend] = [
    LlvmexprBackend(),
    VkExprBackend(),
    AkarinExprBackend(),
]

ENABLED_BACKENDS: List[str] = [
    "llvmexpr",
    "VkExpr",
    "akarin",
]

ENABLED_TESTS: List[str] = list(TEST_CASES.keys())


def get_test_config(test_name: str) -> Tuple[str, int]:
    """
    Extracts expression and frame count from test case configuration.

    Args:
        test_name: Name of the test case

    Returns:
        Tuple of (expression, frame_count)
    """
    test_data = TEST_CASES[test_name]
    if isinstance(test_data, tuple):
        return test_data[0], test_data[1]
    else:
        return test_data, DEFAULT_FRAME_COUNT


def print_results_table(
    results: Dict[str, Dict[str, str]], backend_names: List[str], test_names: List[str]
):
    """Formats and prints the benchmark results in Markdown table."""
    header = ["Test Case"] + backend_names

    rows = []
    for test_name in test_names:
        if test_name in results and results[test_name]:
            backend_results = results[test_name]
            row = [str(test_name)] + [
                str(backend_results.get(backend, "N/A")) for backend in backend_names
            ]
            rows.append(row)

    if not rows:
        print("No benchmark results to display.")
        return

    print("\n--- Benchmark Results ---")

    print(f"| {' | '.join(header)} |")
    print(f"|{'|'.join(['---'] * len(header))}|")

    for row in rows:
        print(f"| {' | '.join(row)} |")


def compute_geometric_mean_performance(
    results: Dict[str, Dict[str, str]], backend_names: List[str], test_names: List[str]
) -> Tuple[Optional[Dict[str, float]], Optional[Dict[str, float]]]:
    """Calculates geometric mean FPS per backend and relative ratios."""

    per_backend_fps: Dict[str, List[float]] = {backend: [] for backend in backend_names}

    for test_name in test_names:
        backend_results = results.get(test_name, {})
        fps_values: Dict[str, float] = {}

        for backend in backend_names:
            value = backend_results.get(backend)
            if not value or not value.endswith(" FPS"):
                break

            fps_str = value.split()[0]
            try:
                fps = float(fps_str)
            except ValueError:
                break

            if fps <= 0:
                break

            fps_values[backend] = fps
        else:
            for backend in backend_names:
                per_backend_fps[backend].append(fps_values[backend])

    if not any(per_backend_fps.values()):
        return None, None

    geometric_means: Dict[str, float] = {}
    for backend, values in per_backend_fps.items():
        if not values:
            return None, None
        log_sum = sum(math.log(v) for v in values)
        geometric_means[backend] = math.exp(log_sum / len(values))

    baseline_backend = backend_names[0] if backend_names else None
    ratios: Optional[Dict[str, float]] = None

    if baseline_backend:
        baseline_gm = geometric_means.get(baseline_backend)
        if baseline_gm and baseline_gm > 0:
            ratios = {
                backend: geometric_means[backend] / baseline_gm
                for backend in backend_names
            }

    return geometric_means, ratios


def _resolve_selected_tests(
    *,
    tests: Optional[Union[str, List[str]]],
    exclude_tests: Optional[Union[str, List[str]]],
    quiet: bool,
) -> List[str]:
    requested = _parse_csv_list(tests)
    excluded = set(_parse_csv_list(exclude_tests))

    all_tests = list(TEST_CASES.keys())
    if not requested or any(v.lower() in {"all", "*"} for v in requested):
        selected = all_tests
    else:
        selected: List[str] = []
        for item in requested:
            if item in TEST_CASES:
                selected.append(item)
                continue
            matches = [t for t in all_tests if fnmatch.fnmatchcase(t, item)]
            selected.extend(matches)

    selected = [t for t in _unique_keep_order(selected) if t not in excluded]
    if not quiet and not selected:
        print("Warning: no tests selected.")
    return selected


def _resolve_selected_backends(backends: Optional[Union[str, List[str]]]) -> List[str]:
    requested = _parse_csv_list(backends)
    if not requested or any(v.lower() in {"all", "*"} for v in requested):
        return _unique_keep_order([b.get_name() for b in BACKENDS_TO_TEST])
    return _unique_keep_order(requested)


def _benchmark_one(
    *,
    backend: ExprBackend,
    test_name: str,
    expr_string: str,
    frame_count: int,
    width: int,
    height: int,
    format_id: int,
    warmup_frames: int,
    show_progress: bool,
    progress_prefix: str,
) -> Dict[str, Any]:
    try:
        source_clip = core.std.BlankClip(
            width=width, height=height, format=format_id, length=frame_count
        )
        filtered_clip = backend.filter(source_clip, expr_string)

        if filtered_clip is None:
            return {"status": "skipped"}

        if warmup_frames > 0:
            for _ in filtered_clip[:warmup_frames].frames():
                pass

        start_time = time.perf_counter()
        actual_frame_count = 0
        for _ in filtered_clip.frames():
            actual_frame_count += 1
        end_time = time.perf_counter()

        duration_s = end_time - start_time
        fps = (actual_frame_count / duration_s) if duration_s > 0 else 0.0
        if show_progress:
            sys.stdout.write("\r" + " " * len(progress_prefix) + "\r")
            sys.stdout.flush()
        return {
            "status": "ok",
            "frames": actual_frame_count,
            "duration_s": duration_s,
            "fps": fps,
        }
    except Exception as e:
        if show_progress:
            sys.stdout.write("\r" + " " * len(progress_prefix) + "\r")
            sys.stdout.flush()
        return {
            "status": "failed",
            "error_type": type(e).__name__,
            "error": str(e),
        }


def run_benchmark(args: argparse.Namespace) -> int:
    """
    Sets up the test environment and runs the configured benchmarks.
    """
    print("--- VapourSynth Expr Benchmark ---")

    if cpuinfo and not args.no_cpuinfo:
        info = cpuinfo.get_cpu_info()
        cpu_brand = info.get("brand_raw", "Unknown CPU")
        cpu_cores = info.get("count", "?")
        print(f"**CPU:** {cpu_brand} ({cpu_cores} logical cores)")
    else:
        import multiprocessing

        try:
            cpu_cores = multiprocessing.cpu_count()
            print("**CPU:** Could not determine model")
            print(f"**Cores:** {cpu_cores} logical cores")
        except NotImplementedError:
            print("**CPU:** Could not determine model or core count.")

    if args.threads is not None:
        if str(args.threads).lower() == "auto":
            import multiprocessing

            core.num_threads = multiprocessing.cpu_count()
        else:
            core.num_threads = int(args.threads)

    print(f"**Python:** {platform.python_version()}")
    print(f"**Platform:** {platform.platform()}")
    print(f"**VapourSynth Threads:** {core.num_threads}\n")

    print("Running benchmarks...\n")

    plugin_paths = _unique_keep_order(
        _parse_csv_list(args.load_plugin)
        + _parse_csv_list(args.llvmexpr_plugin)
        + _parse_csv_list(args.akarin_plugin)
    )
    _try_load_plugins(plugin_paths, quiet=args.quiet)

    enabled_backends = _resolve_selected_backends(args.backends)
    active_backends = [b for b in BACKENDS_TO_TEST if b.get_name() in enabled_backends]
    backend_names = [b.get_name() for b in active_backends]

    if args.expr or args.expr_file:
        if args.tests and not any(v.lower() in {"all", "*"} for v in _parse_csv_list(args.tests)):
            raise SystemExit("--expr/--expr-file cannot be combined with --tests")
        if args.expr and args.expr_file:
            raise SystemExit("Only one of --expr and --expr-file may be provided")
        expr_string = args.expr
        if args.expr_file:
            with open(args.expr_file, "r", encoding="utf-8") as f:
                expr_string = f.read().strip()
        if not expr_string:
            raise SystemExit("Custom expression is empty")
        test_names = [args.test_name]
        test_exprs: Dict[str, Tuple[str, int]] = {
            args.test_name: (expr_string, int(args.frames or DEFAULT_FRAME_COUNT))
        }
    else:
        test_names = _resolve_selected_tests(
            tests=args.tests, exclude_tests=args.exclude_tests, quiet=args.quiet
        )
        test_exprs = {
            name: get_test_config(name) for name in test_names if name in TEST_CASES
        }

    if args.list_tests:
        for name in list(TEST_CASES.keys()):
            print(name)
        return 0

    if args.list_backends:
        for name in [b.get_name() for b in BACKENDS_TO_TEST]:
            print(name)
        return 0

    results: Dict[str, Dict[str, str]] = {test_name: {} for test_name in test_names}
    json_results: Dict[str, Dict[str, Dict[str, Any]]] = {test_name: {} for test_name in test_names}

    tests_to_run = [
        (backend, test_name)
        for backend in active_backends
        for test_name in test_names
        if test_name in test_exprs
    ]
    total_tests = len(tests_to_run)
    completed_tests = 0

    for backend, test_name in tests_to_run:
        completed_tests += 1
        backend_name = backend.get_name()
        expr_string, configured_frame_count = test_exprs[test_name]
        frame_count = int(args.frames) if args.frames is not None else configured_frame_count

        progress_msg = (
            f"[{completed_tests}/{total_tests}] {backend_name} | {test_name} | {frame_count} frames"
        )
        if not args.no_progress:
            sys.stdout.write(f"\r{progress_msg.ljust(120)}")
            sys.stdout.flush()

        res = _benchmark_one(
            backend=backend,
            test_name=test_name,
            expr_string=expr_string,
            frame_count=frame_count,
            width=int(args.width),
            height=int(args.height),
            format_id=getattr(vs, args.format),
            warmup_frames=int(args.warmup),
            show_progress=not args.no_progress,
            progress_prefix=progress_msg,
        )

        status = res["status"]
        if status == "ok":
            results[test_name][backend_name] = f"{res['fps']:.2f} FPS"
        elif status == "skipped":
            results[test_name][backend_name] = "SKIPPED"
        else:
            results[test_name][backend_name] = f"FAILED ({res.get('error_type', 'Error')})"

        json_results[test_name][backend_name] = res

    if not args.no_progress:
        sys.stdout.write("\r" + " " * 120 + "\r")
        sys.stdout.flush()
    print("All benchmarks completed.\n")

    print_results_table(results, backend_names, test_names)

    geometric_means, ratios = compute_geometric_mean_performance(
        results, backend_names, test_names
    )

    if geometric_means:
        print("\nGeometric mean FPS (common successful tests only):")
        for backend in backend_names:
            gm_value = geometric_means.get(backend)
            if gm_value is not None:
                print(f"  {backend}: {gm_value:.2f} FPS")

        if ratios:
            baseline_backend = backend_names[0]
            print(f"\nPerformance ratios (relative to '{baseline_backend}'): ")
            for backend in backend_names:
                ratio = ratios.get(backend)
                if ratio is not None:
                    print(f"  {backend}: {ratio:.3f}x")
    else:
        print("\nNo common successful tests for geometric mean calculation.")

    report: Dict[str, Any] = {
        "meta": {
            "python": platform.python_version(),
            "platform": platform.platform(),
            "vapoursynth_threads": core.num_threads,
            "width": int(args.width),
            "height": int(args.height),
            "format": args.format,
            "warmup_frames": int(args.warmup),
            "frames_override": int(args.frames) if args.frames is not None else None,
            "selected_tests": test_names,
            "selected_backends": backend_names,
        },
        "results": json_results,
        "geometric_mean_fps": geometric_means,
        "performance_ratios": ratios,
    }

    if args.json:
        with open(args.json, "w", encoding="utf-8") as f:
            json.dump(report, f, indent=2, sort_keys=True)
        if not args.quiet:
            print(f"\nWrote JSON report: {args.json}")

    if args.markdown:
        with open(args.markdown, "w", encoding="utf-8") as f:
            original_stdout = sys.stdout
            try:
                sys.stdout = f
                print_results_table(results, backend_names, test_names)
            finally:
                sys.stdout = original_stdout
        if not args.quiet:
            print(f"Wrote Markdown table: {args.markdown}")

    any_ok = any(
        backend_result.get("status") == "ok"
        for test_result in json_results.values()
        for backend_result in test_result.values()
    )
    any_failed = any(
        backend_result.get("status") == "failed"
        for test_result in json_results.values()
        for backend_result in test_result.values()
    )

    if args.fail_on_no_results and not any_ok:
        print("Error: no successful benchmark results.")
        return 2
    if args.fail_on_failed and any_failed:
        print("Error: at least one benchmark failed.")
        return 3

    required_backends = _parse_csv_list(args.require_backend)
    for required in required_backends:
        had_required_ok = any(
            test_result.get(required, {}).get("status") == "ok"
            for test_result in json_results.values()
        )
        if not had_required_ok:
            print(f"Error: required backend produced no OK results: {required}")
            return 4

    return 0


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Benchmark llvmexpr.Expr/VkExpr backends")
    parser.add_argument("--width", type=int, default=1920)
    parser.add_argument("--height", type=int, default=1080)
    parser.add_argument("--format", type=str, default="GRAYS")
    parser.add_argument("--frames", type=int, default=None, help="Override frame count for all tests")
    parser.add_argument("--warmup", type=int, default=5)
    parser.add_argument("--threads", type=str, default="12", help="VapourSynth threads (int or 'auto')")

    parser.add_argument("--tests", type=str, default="all", help="Comma-separated test names or glob patterns")
    parser.add_argument("--exclude-tests", type=str, default=None, help="Comma-separated test names/patterns to skip")
    parser.add_argument("--list-tests", action="store_true")

    parser.add_argument("--backends", type=str, default="llvmexpr,VkExpr,akarin", help="Comma-separated backend names")
    parser.add_argument("--list-backends", action="store_true")

    parser.add_argument("--expr", type=str, default=None, help="Run a custom expression (postfix)")
    parser.add_argument("--expr-file", type=str, default=None, help="Run a custom expression loaded from file")
    parser.add_argument("--test-name", type=str, default="custom", help="Name for the custom expression test")

    parser.add_argument("--llvmexpr-plugin", type=str, default=os.environ.get("LLVMEXPR_PLUGIN_PATH"))
    parser.add_argument("--akarin-plugin", type=str, default=os.environ.get("AKARIN_PLUGIN_PATH"))
    parser.add_argument("--load-plugin", action="append", default=[], help="Extra plugin paths to load (repeatable)")

    parser.add_argument("--json", type=str, default=None, help="Write JSON report to path")
    parser.add_argument("--markdown", type=str, default=None, help="Write Markdown table to path")

    parser.add_argument("--require-backend", action="append", default=[], help="Fail if backend has no OK results")
    parser.add_argument("--fail-on-failed", action="store_true")
    parser.add_argument("--fail-on-no-results", action="store_true")

    parser.add_argument("--no-progress", action="store_true")
    parser.add_argument("--no-cpuinfo", action="store_true")
    parser.add_argument("--quiet", action="store_true")

    _backfill_preset_format_constants()

    exit_code = run_benchmark(parser.parse_args())
    raise SystemExit(exit_code)
