# Path: esc/commands.py
# BINOP = 'binop'
# UNOP = 'unop'
# MAIN_DOC = """
#     The main menu. All other esc functions and menus are eventually accessible
#     from this menu.
# """
# class EscCommand:
# class EscMenu(EscCommand):
# class EscOperation(EscCommand):
# class EscBuiltin(EscCommand):
#     def __init__(self, key, description):
#     def help_title(self):
#     def signature_info(self):
#     def execute(self, access_key, ss, registry):
#     def register_child(self, child):
#     def simulated_result(self, ss, registry):  # pylint: disable=no-self-use, unused-argument
#     def test(self):
#     def __init__(self, key, description, doc, mode_display=None):
#     def __repr__(self):
#     def signature_info(self):
#     def is_main_menu(self):
#     def anonymous_children(self):
#     def named_children(self):
#     def child(self, access_key):
#     def execute(self, access_key, ss, registry):
#     def test(self):
#     def __init__(self, key, func, pop, push, description, menu, retain=False,
#                  log_as=None, simulate=True):
#     def __repr__(self):
#     def __doc__(self):
#     def signature_info(self):
#     def _describe_operation(self, args, retvals, registry):
#     def _insufficient_items_on_stack(self, pops_requested=None):
#     def _retrieve_arguments(self, ss):
#     def _simulated_description(self, args, log, results):
#     def _store_results(self, ss, args, return_values, registry):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def __init__(self):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def signature_info(self):
# def Menu(key, description, parent, doc, mode_display=None):  # pylint: disable=invalid-name
# def Constant(value, key, description, menu):  # pylint: disable=invalid-name
#     def func():
# def Operation(key, menu, push, description=None, retain=False, log_as=None, simulate=True):  # pylint: disable=invalid-name
#     def function_decorator(func):
#         def _bind_stack_parm(stack_item, parm):
#         def wrapper(stack, registry):
#         def ensure(before, after=None, raises=None, close=False):
# def Mode(name, default_value, allowable_values=None):  # pylint: disable=invalid-name
# def ModeChange(key, description, menu, mode_name, to_value):  # pylint: disable=invalid-name
# 
# Path: esc/consts.py
# CONSTANT_MENU_CHARACTER = 'i'
# 
# Path: esc/oops.py
# class InsufficientItemsError(FunctionExecutionError):
#     """
#     Raised directly by operations functions that request the entire stack to
#     indicate not enough items are on the stack to finish their work, or by
#     the menu logic when an operation requests more parameters than items on
#     the stack.
# 
#     Functions may use the simplified form of the exception, providing an int
#     describing the number of items that should have been on the stack for the
#     ``number_required`` constructor parameter. esc will then reraise the
#     exception with a more useful message; a fallback message is provided in
#     case this doesn't happen for some reason.
#     """
#     def __init__(self, number_required, msg=None):
#         super().__init__()
#         self.number_required = number_required
#         self.msg = msg
# 
#     def __str__(self):
#         if self.msg:
#             return self.msg
#         else:
#             return f"Insufficient items: needs at least {self.number_required}"
# 
# Path: esc/status.py
# class StatusState:
#     class Modality(Enum):
#     class SuccessCode(Enum):
#         READY = (' ', "Ready (<F1> for help)")
#         ENTERING_NUMBER = ('i', "Insert")
#         IN_MENU = ('m', "Expecting menu selection")
#         EXPECTING_REGISTER = ('r', "Expecting register identifier (any letter)")
#         EXPECTING_HELP = ('h', "Browsing help (select a command or menu)")
#         OK = auto()  # pylint: disable=invalid-name
#         ADVISORY = auto()
#         ERROR = auto()
#         def __init__(self, status_char, status_message):
#     def __init__(self):
#     def __repr__(self):
#     def status_char(self):
#     def status_message(self):
#     def _clear_errors(self):
#     def ready(self):
#     def entering_number(self):
#     def in_menu(self):
#     def expecting_register(self):
#     def expecting_help(self):
#     def advisory(self, msg):
#     def error(self, msg):
#     def mark_seen(self):
#     def push_state(self):
#     def pop_state(self):
#     def save_state(self):


from decimal import Decimal, InvalidOperation
from subprocess import Popen, PIPE
from .commands import BINOP, Constant, Operation, Menu, main_menu
from .consts import CONSTANT_MENU_CHARACTER
from .oops import InsufficientItemsError
from .status import status
import math
import platform
    Swap bos and sos. Useful if you enter numbers in the wrong order or when
    you need to divide a more recent result by an older one.
    """
    return bos, sos

exchange.ensure(before=[1, 2, 3], after=[1, 3, 2])


@Operation('p', menu=main_menu, push=0, description='pop off bos', log_as="pop bos {0}")
def pop(_):
    "Remove and discard the bottom item from the stack."
    return None

pop.ensure(before=[1, 5], after=[1])
pop.ensure(before=[5], after=[])
pop.ensure(before=[], raises=InsufficientItemsError)


@Operation('r', menu=main_menu, push=-1,
           description='roll up',
           log_as="roll tos {0} to bos")
def roll(*stack):
    "Move the top item on the stack to the bottom."
    if len(stack) < 2:
        raise InsufficientItemsError(number_required=2)
    return (*stack[1:], stack[0])

roll.ensure(before=[1, 2, 3], after=[2, 3, 1])
roll.ensure(before=[1, 2], after=[2, 1])
roll.ensure(before=[1], raises=InsufficientItemsError)

# Path: esc/commands.py
# BINOP = 'binop'
# UNOP = 'unop'
# MAIN_DOC = """
#     The main menu. All other esc functions and menus are eventually accessible
#     from this menu.
# """
# class EscCommand:
# class EscMenu(EscCommand):
# class EscOperation(EscCommand):
# class EscBuiltin(EscCommand):
#     def __init__(self, key, description):
#     def help_title(self):
#     def signature_info(self):
#     def execute(self, access_key, ss, registry):
#     def register_child(self, child):
#     def simulated_result(self, ss, registry):  # pylint: disable=no-self-use, unused-argument
#     def test(self):
#     def __init__(self, key, description, doc, mode_display=None):
#     def __repr__(self):
#     def signature_info(self):
#     def is_main_menu(self):
#     def anonymous_children(self):
#     def named_children(self):
#     def child(self, access_key):
#     def execute(self, access_key, ss, registry):
#     def test(self):
#     def __init__(self, key, func, pop, push, description, menu, retain=False,
#                  log_as=None, simulate=True):
#     def __repr__(self):
#     def __doc__(self):
#     def signature_info(self):
#     def _describe_operation(self, args, retvals, registry):
#     def _insufficient_items_on_stack(self, pops_requested=None):
#     def _retrieve_arguments(self, ss):
#     def _simulated_description(self, args, log, results):
#     def _store_results(self, ss, args, return_values, registry):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def __init__(self):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def signature_info(self):
# def Menu(key, description, parent, doc, mode_display=None):  # pylint: disable=invalid-name
# def Constant(value, key, description, menu):  # pylint: disable=invalid-name
#     def func():
# def Operation(key, menu, push, description=None, retain=False, log_as=None, simulate=True):  # pylint: disable=invalid-name
#     def function_decorator(func):
#         def _bind_stack_parm(stack_item, parm):
#         def wrapper(stack, registry):
#         def ensure(before, after=None, raises=None, close=False):
# def Mode(name, default_value, allowable_values=None):  # pylint: disable=invalid-name
# def ModeChange(key, description, menu, mode_name, to_value):  # pylint: disable=invalid-name
# 
# Path: esc/consts.py
# CONSTANT_MENU_CHARACTER = 'i'
# 
# Path: esc/oops.py
# class InsufficientItemsError(FunctionExecutionError):
#     """
#     Raised directly by operations functions that request the entire stack to
#     indicate not enough items are on the stack to finish their work, or by
#     the menu logic when an operation requests more parameters than items on
#     the stack.
# 
#     Functions may use the simplified form of the exception, providing an int
#     describing the number of items that should have been on the stack for the
#     ``number_required`` constructor parameter. esc will then reraise the
#     exception with a more useful message; a fallback message is provided in
#     case this doesn't happen for some reason.
#     """
#     def __init__(self, number_required, msg=None):
#         super().__init__()
#         self.number_required = number_required
#         self.msg = msg
# 
#     def __str__(self):
#         if self.msg:
#             return self.msg
#         else:
#             return f"Insufficient items: needs at least {self.number_required}"
# 
# Path: esc/status.py
# class StatusState:
#     class Modality(Enum):
#     class SuccessCode(Enum):
#         READY = (' ', "Ready (<F1> for help)")
#         ENTERING_NUMBER = ('i', "Insert")
#         IN_MENU = ('m', "Expecting menu selection")
#         EXPECTING_REGISTER = ('r', "Expecting register identifier (any letter)")
#         EXPECTING_HELP = ('h', "Browsing help (select a command or menu)")
#         OK = auto()  # pylint: disable=invalid-name
#         ADVISORY = auto()
#         ERROR = auto()
#         def __init__(self, status_char, status_message):
#     def __init__(self):
#     def __repr__(self):
#     def status_char(self):
#     def status_message(self):
#     def _clear_errors(self):
#     def ready(self):
#     def entering_number(self):
#     def in_menu(self):
#     def expecting_register(self):
#     def expecting_help(self):
#     def advisory(self, msg):
#     def error(self, msg):
#     def mark_seen(self):
#     def push_state(self):
#     def pop_state(self):
#     def save_state(self):


# Path: esc/functions.py
from decimal import Decimal, InvalidOperation
from subprocess import Popen, PIPE
from .commands import BINOP, Constant, Operation, Menu, main_menu
from .consts import CONSTANT_MENU_CHARACTER
from .oops import InsufficientItemsError
from .status import status
import math
import platform

    Swap bos and sos. Useful if you enter numbers in the wrong order or when
    you need to divide a more recent result by an older one.
    """
    return bos, sos

exchange.ensure(before=[1, 2, 3], after=[1, 3, 2])


@Operation('p', menu=main_menu, push=0, description='pop off bos', log_as="pop bos {0}")
def pop(_):
    "Remove and discard the bottom item from the stack."
    return None

pop.ensure(before=[1, 5], after=[1])
pop.ensure(before=[5], after=[])
pop.ensure(before=[], raises=InsufficientItemsError)


@Operation('r', menu=main_menu, push=-1,
           description='roll up',
           log_as="roll tos {0} to bos")
def roll(*stack):
    "Move the top item on the stack to the bottom."
    if len(stack) < 2:
        raise InsufficientItemsError(number_required=2)
    return (*stack[1:], stack[0])

roll.ensure(before=[1, 2, 3], after=[2, 3, 1])
roll.ensure(before=[1, 2], after=[2, 1])
roll.ensure(before=[1], raises=InsufficientItemsError)

roll.ensure(before=[], raises=InsufficientItemsError)