################################################################################
# Copyright (C) 2015-2016 by Arena of Titans Contributors.
#
# This file is part of Arena of Titans.
#
# Arena of Titans is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Arena of Titans 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Arena of Titans. If not, see <http://www.gnu.org/licenses/>.
################################################################################


from time import time
from types import MappingProxyType


def get_time():
    return int(time() * 1000)


def make_immutable(data):
    """Make the supplied data immutable.

    It only works with basic data types like dict, list and sets.
    """
    if isinstance(data, (bool, int, float, str, bytes, type(None))):
        return data
    elif isinstance(data, (tuple, list)):
        # A tuple is immutable but it can be made of things that are not.
        return tuple(make_immutable(elt) for elt in data)
    elif isinstance(data, (set, frozenset)):
        # A frozenset is immutable but it can be made of things that are not.
        return frozenset(make_immutable(elt) for elt in data)
    elif isinstance(data, dict):
        return MappingProxyType({key: make_immutable(value) for key, value in data.items()})
    else:
        raise ValueError(f"{type(data)} cannot be made immutable with basic types.")


def remove_mappingproxies(data: dict):
    """Remove mappingproxies from the data structure by copying them.

    It can be required because mappingproxies cannot be pickled.
    """
    if isinstance(data, (bool, int, float, str, bytes, type(None))):
        return data

    data = data.copy()
    for key, value in data.items():
        if isinstance(value, MappingProxyType):
            data[key] = remove_mappingproxies(value)
        elif isinstance(value, (list, tuple)):
            data[key] = tuple(remove_mappingproxies(elts) for elts in value)

    return data


class SimpleEnumMeta(type):
    def __new__(metacls, cls, bases, classdict):  # noqa: N804
        object_attrs = set(dir(type(cls, (object,), {})))
        simple_enum_cls = super().__new__(metacls, cls, bases, classdict)
        simple_enum_cls._member_names_ = set(classdict.keys()) - object_attrs
        non_members = set()
        for attr in simple_enum_cls._member_names_:
            if attr.startswith("_") and attr.endswith("_"):
                non_members.add(attr)
            else:
                setattr(simple_enum_cls, attr, attr)

        simple_enum_cls._member_names_.difference_update(non_members)

        return simple_enum_cls

    def __getitem__(cls, key):  # noqa: N805
        return getattr(cls, key.upper())

    def __iter__(cls):  # noqa: N805
        return (name for name in cls._member_names_)

    def __len__(cls):  # pragma: no cover  # noqa: N805
        return len(cls._member_names_)

@@ -1,86 +1,8 @@
-###############################################################################
 #%0A#
+ 
  Cop
@@ -23,10 +23,10 @@
 5-20
-16
+20
  by 
@@ -58,16 +58,17 @@
 ors.%0A#%0A#
+ 
  This fi
@@ -97,24 +97,25 @@
  Titans.%0A#%0A#
+ 
  Arena of Ti
@@ -176,16 +176,17 @@
 modify%0A#
+ 
  it unde
@@ -255,16 +255,17 @@
 hed by%0A#
+ 
  the Fre
@@ -324,16 +324,17 @@
 se, or%0A#
+ 
  (at you
@@ -365,16 +365,17 @@
 ion.%0A#%0A#
+ 
  Arena o
@@ -435,16 +435,17 @@
 seful,%0A#
+ 
  but WIT
@@ -501,16 +501,17 @@
 nty of%0A#
+ 
  MERCHAN
@@ -566,16 +566,17 @@
 ee the%0A#
+ 
  GNU Aff
@@ -623,16 +623,17 @@
 ils.%0A#%0A#
+ 
  You sho
@@ -699,16 +699,17 @@
 icense%0A#
+ 
  along w
@@ -778,87 +778,8 @@
 %3E.%0A#
-###############################################################################
 %0A%0A%0Af
@@ -1600,16 +1600,61 @@
 ems()%7D)%0A
+    elif callable(data):%0A        return data%0A
     else

add support for functions in make_immutable