mapres 2.3__tar.gz → 2.4a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mapres-2.3/src/mapres.egg-info → mapres-2.4a1}/PKG-INFO +1 -1
- {mapres-2.3 → mapres-2.4a1}/pyproject.toml +1 -1
- {mapres-2.3 → mapres-2.4a1}/src/mapres/__init__.py +2 -1
- {mapres-2.3 → mapres-2.4a1}/src/mapres/datamap.py +12 -12
- mapres-2.4a1/src/mapres/maps/color.py +75 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres/maps/time.py +25 -20
- {mapres-2.3 → mapres-2.4a1}/src/mapres/resolver.py +81 -40
- {mapres-2.3 → mapres-2.4a1/src/mapres.egg-info}/PKG-INFO +1 -1
- mapres-2.3/src/mapres/maps/color.py +0 -75
- {mapres-2.3 → mapres-2.4a1}/LICENSE +0 -0
- {mapres-2.3 → mapres-2.4a1}/README.md +0 -0
- {mapres-2.3 → mapres-2.4a1}/setup.cfg +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres/cache.py +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres/exceptions.py +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres/layers.py +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres/maps/__init__.py +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres.egg-info/SOURCES.txt +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres.egg-info/dependency_links.txt +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres.egg-info/requires.txt +0 -0
- {mapres-2.3 → mapres-2.4a1}/src/mapres.egg-info/top_level.txt +0 -0
|
@@ -7,7 +7,7 @@ try:
|
|
|
7
7
|
except PackageNotFoundError:
|
|
8
8
|
__version__ = '0.0.0'
|
|
9
9
|
|
|
10
|
-
from .resolver import MapResolver, res
|
|
10
|
+
from .resolver import MapResolver, res, setGlobalMaps
|
|
11
11
|
from .datamap import DataMap, datamap, syntax
|
|
12
12
|
from .layers import Layer, LayerStack
|
|
13
13
|
|
|
@@ -37,6 +37,7 @@ __all__ = [
|
|
|
37
37
|
'syntax',
|
|
38
38
|
'Layer',
|
|
39
39
|
'LayerStack',
|
|
40
|
+
'setGlobalMaps',
|
|
40
41
|
|
|
41
42
|
# maps
|
|
42
43
|
'ColorMap',
|
|
@@ -2,10 +2,10 @@ import re
|
|
|
2
2
|
from dataclasses import dataclass, fields, is_dataclass
|
|
3
3
|
|
|
4
4
|
class syntax:
|
|
5
|
-
braces = r
|
|
6
|
-
dollars = r
|
|
7
|
-
angles = r
|
|
8
|
-
percents = r
|
|
5
|
+
braces = r'\{([^{}]+)\}'
|
|
6
|
+
dollars = r'\$\{([^{}]+)\}'
|
|
7
|
+
angles = r'<([^<>]+)>'
|
|
8
|
+
percents = r'%([^%]+)%'
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
@dataclass
|
|
@@ -17,11 +17,11 @@ class DataMap:
|
|
|
17
17
|
def as_map(self):
|
|
18
18
|
result = {}
|
|
19
19
|
for f in fields(self):
|
|
20
|
-
if not f.init or f.name in (
|
|
20
|
+
if not f.init or f.name in ('__syntax__', '__mode__'):
|
|
21
21
|
continue
|
|
22
22
|
val = getattr(self, f.name)
|
|
23
|
-
if self.__mode__ ==
|
|
24
|
-
providers = getattr(self,
|
|
23
|
+
if self.__mode__ == 'dynamic':
|
|
24
|
+
providers = getattr(self, 'providers', None)
|
|
25
25
|
if isinstance(providers, dict) and f.name in providers:
|
|
26
26
|
val = providers[f.name]
|
|
27
27
|
if callable(val):
|
|
@@ -31,7 +31,7 @@ class DataMap:
|
|
|
31
31
|
|
|
32
32
|
@classmethod
|
|
33
33
|
def get_syntax(cls):
|
|
34
|
-
return getattr(cls,
|
|
34
|
+
return getattr(cls, '__syntax__', syntax.braces)
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
# decorator
|
|
@@ -39,20 +39,20 @@ def datamap(
|
|
|
39
39
|
_cls = None,
|
|
40
40
|
*,
|
|
41
41
|
syntax: str = syntax.braces,
|
|
42
|
-
mode: bool | None = None,
|
|
42
|
+
mode: bool | str | None = None,
|
|
43
43
|
):
|
|
44
44
|
'''@datamap decorator with optional values'''
|
|
45
45
|
def wrap(cls):
|
|
46
46
|
cls.__syntax__ = syntax
|
|
47
47
|
cls.__mode__ = mode
|
|
48
48
|
namespace = dict(cls.__dict__)
|
|
49
|
-
namespace[
|
|
49
|
+
namespace['__dict__'] = {}
|
|
50
50
|
# preserve any rules class defined in the original namespace by attaching it to the generated class
|
|
51
|
-
rules_obj = namespace.get(
|
|
51
|
+
rules_obj = namespace.get('rules', None)
|
|
52
52
|
cls = type(cls.__name__, (DataMap,), namespace)
|
|
53
53
|
# attach rules (if present) to the new class so validators can read them via the datamap class
|
|
54
54
|
if rules_obj is not None:
|
|
55
|
-
setattr(cls,
|
|
55
|
+
setattr(cls, 'rules', rules_obj)
|
|
56
56
|
return dataclass(frozen=False)(cls)
|
|
57
57
|
return wrap if _cls is None else wrap(_cls)
|
|
58
58
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from mapres.datamap import datamap, syntax
|
|
2
|
+
|
|
3
|
+
@datamap(syntax=syntax.angles) # produces <>
|
|
4
|
+
class ColorMap:
|
|
5
|
+
black: str = '\033[30m'
|
|
6
|
+
dark_blue: str = '\033[34m'
|
|
7
|
+
dark_green: str = '\033[32m'
|
|
8
|
+
dark_aqua: str = '\033[36m'
|
|
9
|
+
dark_red: str = '\033[31m'
|
|
10
|
+
dark_purple: str = '\033[35m'
|
|
11
|
+
gold: str = '\033[33m'
|
|
12
|
+
gray: str = '\033[37m'
|
|
13
|
+
dark_gray: str = '\033[90m'
|
|
14
|
+
blue: str = '\033[94m'
|
|
15
|
+
green: str = '\033[92m'
|
|
16
|
+
aqua: str = '\033[96m'
|
|
17
|
+
red: str = '\033[91m'
|
|
18
|
+
light_purple: str = '\033[95m'
|
|
19
|
+
yellow: str = '\033[93m'
|
|
20
|
+
white: str = '\033[97m'
|
|
21
|
+
reset: str = '\033[0m'
|
|
22
|
+
bold: str = '\033[1m'
|
|
23
|
+
italic: str = '\033[3m'
|
|
24
|
+
|
|
25
|
+
def as_dict(self):
|
|
26
|
+
return {f'<{k}>': getattr(self, k) for k in self.__dataclass_fields__}
|
|
27
|
+
|
|
28
|
+
# ASCII color map
|
|
29
|
+
ascii_colors = ColorMap()
|
|
30
|
+
|
|
31
|
+
# Minecraft color map
|
|
32
|
+
mc_colors = ColorMap(
|
|
33
|
+
black='§0',
|
|
34
|
+
dark_blue='§1',
|
|
35
|
+
dark_green='§2',
|
|
36
|
+
dark_aqua='§3',
|
|
37
|
+
dark_red='§4',
|
|
38
|
+
dark_purple='§5',
|
|
39
|
+
gold='§6',
|
|
40
|
+
gray='§7',
|
|
41
|
+
dark_gray='§8',
|
|
42
|
+
blue='§9',
|
|
43
|
+
green='§a',
|
|
44
|
+
aqua='§b',
|
|
45
|
+
red='§c',
|
|
46
|
+
light_purple='§d',
|
|
47
|
+
yellow='§e',
|
|
48
|
+
white='§f',
|
|
49
|
+
reset='§r',
|
|
50
|
+
bold='§l',
|
|
51
|
+
italic='§o'
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Color strip map
|
|
55
|
+
strip_colors = ColorMap(
|
|
56
|
+
black='',
|
|
57
|
+
dark_blue='',
|
|
58
|
+
dark_green='',
|
|
59
|
+
dark_aqua='',
|
|
60
|
+
dark_red='',
|
|
61
|
+
dark_purple='',
|
|
62
|
+
gold='',
|
|
63
|
+
gray='',
|
|
64
|
+
dark_gray='',
|
|
65
|
+
blue='',
|
|
66
|
+
green='',
|
|
67
|
+
aqua='',
|
|
68
|
+
red='',
|
|
69
|
+
light_purple='',
|
|
70
|
+
yellow='',
|
|
71
|
+
white='',
|
|
72
|
+
reset='',
|
|
73
|
+
bold='',
|
|
74
|
+
italic=''
|
|
75
|
+
)
|
|
@@ -1,31 +1,36 @@
|
|
|
1
|
-
from datetime import datetime
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
2
|
from zoneinfo import ZoneInfo
|
|
3
3
|
from mapres.datamap import datamap, syntax
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
def safe_zoneinfo(tz: str):
|
|
7
|
+
try:
|
|
8
|
+
return ZoneInfo(tz)
|
|
9
|
+
except Exception:
|
|
10
|
+
return timezone.utc
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
@datamap(syntax=syntax.percents, mode='dynamic')
|
|
7
14
|
class TimeMap:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
DD: str = None
|
|
25
|
-
weekday: str = None
|
|
15
|
+
_default_tz = safe_zoneinfo("America/Chicago")
|
|
16
|
+
|
|
17
|
+
hh: str | None = None
|
|
18
|
+
h: str | None = None
|
|
19
|
+
h12: str | None = None
|
|
20
|
+
hh12: str | None = None
|
|
21
|
+
ampm: str | None = None
|
|
22
|
+
mm: str | None = None
|
|
23
|
+
m: str | None = None
|
|
24
|
+
ss: str | None = None
|
|
25
|
+
s: str | None = None
|
|
26
|
+
ms: str | None = None
|
|
27
|
+
YYYY: str | None = None
|
|
28
|
+
MM: str | None = None
|
|
29
|
+
DD: str | None = None
|
|
30
|
+
weekday: str | None = None
|
|
26
31
|
|
|
27
32
|
def __init__(self, tz: str | None = None):
|
|
28
|
-
self.TZ =
|
|
33
|
+
self.TZ = safe_zoneinfo(tz) if tz else self._default_tz
|
|
29
34
|
|
|
30
35
|
@property
|
|
31
36
|
def providers(self):
|
|
@@ -6,7 +6,7 @@ from .exceptions import MapResError, MissingKeyError, MapSyntaxError
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class MapResolver:
|
|
9
|
-
|
|
9
|
+
'''
|
|
10
10
|
Core resolution engine for mapres.
|
|
11
11
|
|
|
12
12
|
Handles:
|
|
@@ -14,9 +14,9 @@ class MapResolver:
|
|
|
14
14
|
- syntax providers
|
|
15
15
|
- layered maps
|
|
16
16
|
- context substitution
|
|
17
|
-
-
|
|
17
|
+
- multi-pass resolution (controlled by `passes`)
|
|
18
18
|
- optional caching
|
|
19
|
-
|
|
19
|
+
'''
|
|
20
20
|
def __init__(
|
|
21
21
|
self,
|
|
22
22
|
layers: list | None = None,
|
|
@@ -24,14 +24,16 @@ class MapResolver:
|
|
|
24
24
|
pipeline: list | None = None,
|
|
25
25
|
cache: bool = False,
|
|
26
26
|
cache_size: int = 1024,
|
|
27
|
-
|
|
27
|
+
passes_default: int = 5
|
|
28
28
|
):
|
|
29
29
|
self.layers = layers or LayerStack()
|
|
30
30
|
self.syntax = syntax or []
|
|
31
31
|
self.pipeline = pipeline or []
|
|
32
32
|
self.cache_enabled = cache
|
|
33
33
|
self.cache = LRUCache(cache_size) if cache else None
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
# unified recursion control
|
|
36
|
+
self.passes_default = passes_default
|
|
35
37
|
|
|
36
38
|
# pipeline
|
|
37
39
|
def _apply_pipeline(self, text: str, ctx: dict) -> str:
|
|
@@ -40,81 +42,93 @@ class MapResolver:
|
|
|
40
42
|
text = stage(text, ctx, self)
|
|
41
43
|
return text
|
|
42
44
|
except Exception as exc:
|
|
43
|
-
raise MapResError(f
|
|
45
|
+
raise MapResError(f'Pipeline stage failed: {exc}') from exc
|
|
44
46
|
|
|
45
47
|
# syntax providers
|
|
46
48
|
def _apply_syntax(self, text: str, ctx: dict) -> str:
|
|
47
49
|
for provider in self.syntax:
|
|
48
50
|
pattern = provider.pattern
|
|
49
51
|
d = provider.get_map(ctx, self)
|
|
52
|
+
|
|
50
53
|
def repl(match: re.Match) -> str:
|
|
51
54
|
k = match.group(1)
|
|
52
55
|
if k not in d:
|
|
53
|
-
raise MissingKeyError(f
|
|
56
|
+
raise MissingKeyError(f'Missing key "{k}" in syntax provider {provider}')
|
|
54
57
|
return str(d[k])
|
|
58
|
+
|
|
55
59
|
try:
|
|
56
60
|
text = re.sub(pattern, repl, text)
|
|
57
61
|
except re.error as exc:
|
|
58
62
|
raise MapSyntaxError(
|
|
59
|
-
f
|
|
63
|
+
f'Regex error in syntax provider {provider}: {exc}'
|
|
60
64
|
) from exc
|
|
65
|
+
|
|
61
66
|
return text
|
|
62
67
|
|
|
63
68
|
# layered maps
|
|
64
69
|
def _apply_maps(self, text: str, ctx: dict, layerstack: LayerStack):
|
|
65
70
|
syntax_patterns = []
|
|
71
|
+
|
|
66
72
|
for m in layerstack:
|
|
67
|
-
if isinstance(m, type) and hasattr(m,
|
|
73
|
+
if isinstance(m, type) and hasattr(m, 'as_map'):
|
|
68
74
|
m = m()
|
|
69
|
-
if hasattr(m,
|
|
75
|
+
if hasattr(m, 'as_map'):
|
|
70
76
|
syntax_patterns.append(m.get_syntax())
|
|
71
77
|
elif isinstance(m, dict):
|
|
72
|
-
pattern = ctx.get(
|
|
78
|
+
pattern = ctx.get('syntax')
|
|
73
79
|
if pattern:
|
|
74
80
|
syntax_patterns.append(pattern)
|
|
81
|
+
|
|
75
82
|
syntax_patterns = list(dict.fromkeys(syntax_patterns))
|
|
83
|
+
|
|
76
84
|
for pattern in syntax_patterns:
|
|
77
85
|
def repl(match: re.Match):
|
|
78
86
|
k = match.group(1)
|
|
87
|
+
|
|
79
88
|
for m in layerstack:
|
|
80
89
|
layer = m
|
|
81
|
-
if isinstance(layer, type) and hasattr(layer,
|
|
90
|
+
if isinstance(layer, type) and hasattr(layer, 'as_map'):
|
|
82
91
|
layer = layer()
|
|
83
|
-
if hasattr(layer,
|
|
92
|
+
if hasattr(layer, 'as_map'):
|
|
84
93
|
d = layer.as_map()
|
|
85
94
|
elif isinstance(layer, dict):
|
|
86
95
|
d = layer
|
|
87
96
|
else:
|
|
88
97
|
continue
|
|
98
|
+
|
|
89
99
|
if k in d:
|
|
90
100
|
return str(d[k])
|
|
91
101
|
|
|
92
102
|
if k in ctx:
|
|
93
103
|
return str(ctx[k])
|
|
94
104
|
|
|
95
|
-
raise MissingKeyError(f
|
|
105
|
+
raise MissingKeyError(f'Missing key "{k}" in any layer or context')
|
|
96
106
|
|
|
97
107
|
try:
|
|
98
108
|
text = re.sub(pattern, repl, text)
|
|
99
109
|
except re.error as exc:
|
|
100
|
-
raise MapSyntaxError(f
|
|
110
|
+
raise MapSyntaxError(f'Regex error in syntax pattern {pattern}: {exc}') from exc
|
|
111
|
+
|
|
101
112
|
return text
|
|
102
113
|
|
|
103
114
|
# context
|
|
104
115
|
def _apply_ctx(self, text: str, ctx: dict) -> str:
|
|
105
116
|
if not ctx:
|
|
106
117
|
return text
|
|
118
|
+
|
|
107
119
|
pattern = syntax.braces
|
|
108
120
|
d = ctx
|
|
121
|
+
|
|
109
122
|
def repl(match: re.Match) -> str:
|
|
110
123
|
k = match.group(1)
|
|
111
124
|
if k not in d:
|
|
112
|
-
raise MissingKeyError(f
|
|
125
|
+
raise MissingKeyError(f'Missing ctx key "{k}"')
|
|
113
126
|
return str(d[k])
|
|
127
|
+
|
|
114
128
|
try:
|
|
115
129
|
return re.sub(pattern, repl, text)
|
|
116
130
|
except re.error as exc:
|
|
117
|
-
raise MapSyntaxError(f
|
|
131
|
+
raise MapSyntaxError(f'Regex error in ctx syntax: {exc}') from exc
|
|
118
132
|
|
|
119
133
|
# one pass
|
|
120
134
|
def _resolve_once(self, text: str, ctx: dict, layerstack: LayerStack) -> str:
|
|
@@ -124,45 +138,53 @@ class MapResolver:
|
|
|
124
138
|
text = self._apply_ctx(text, ctx)
|
|
125
139
|
return text
|
|
126
140
|
|
|
127
|
-
# recursion
|
|
128
|
-
def _recursive(self, text: str, ctx: dict, layerstack: LayerStack) -> str:
|
|
129
|
-
current = text
|
|
130
|
-
for _ in range(self.max_depth):
|
|
131
|
-
result = self._resolve_once(current, ctx, layerstack)
|
|
132
|
-
if result == current:
|
|
133
|
-
return result
|
|
134
|
-
current = result
|
|
135
|
-
return current
|
|
136
|
-
|
|
137
141
|
# public api
|
|
138
142
|
def res(
|
|
139
143
|
self,
|
|
140
144
|
text: str,
|
|
141
145
|
*,
|
|
146
|
+
passes: int | None = None,
|
|
142
147
|
extra_maps: dict | None = None,
|
|
143
148
|
override_maps: dict | None = None,
|
|
144
149
|
**ctx
|
|
145
150
|
) -> str:
|
|
146
|
-
|
|
151
|
+
'''
|
|
147
152
|
Resolve a string using maps, syntax providers, pipeline, and context.
|
|
148
|
-
|
|
153
|
+
'''
|
|
149
154
|
try:
|
|
155
|
+
# determine number of passes
|
|
156
|
+
depth = passes if passes is not None else self.passes_default
|
|
157
|
+
|
|
158
|
+
if depth <= 0:
|
|
159
|
+
raise MapResError("passes must be >= 1")
|
|
160
|
+
|
|
161
|
+
# override maps
|
|
150
162
|
if override_maps is not None:
|
|
151
|
-
temp = LayerStack([Layer(
|
|
152
|
-
return self.
|
|
163
|
+
temp = LayerStack([Layer('override', override_maps, priority=0)])
|
|
164
|
+
return self._resolve_once(text, ctx, temp)
|
|
153
165
|
|
|
166
|
+
# extra maps
|
|
154
167
|
if extra_maps:
|
|
155
168
|
temp = self.layers.clone()
|
|
156
|
-
temp.add_layer(Layer(
|
|
157
|
-
return self.
|
|
169
|
+
temp.add_layer(Layer('extra', extra_maps, priority=999))
|
|
170
|
+
return self._resolve_once(text, ctx, temp)
|
|
158
171
|
|
|
172
|
+
# caching
|
|
159
173
|
if self.cache_enabled:
|
|
160
174
|
key = (text, tuple(sorted(ctx.items())))
|
|
161
175
|
cached = self.cache.get(key)
|
|
162
176
|
if cached is not None:
|
|
163
177
|
return cached
|
|
164
178
|
|
|
165
|
-
|
|
179
|
+
# multi-pass resolution
|
|
180
|
+
current = text
|
|
181
|
+
for _ in range(depth):
|
|
182
|
+
new = self._resolve_once(current, ctx, self.layers)
|
|
183
|
+
if new == current:
|
|
184
|
+
break
|
|
185
|
+
current = new
|
|
186
|
+
|
|
187
|
+
result = current
|
|
166
188
|
|
|
167
189
|
if self.cache_enabled:
|
|
168
190
|
self.cache.set(key, result)
|
|
@@ -172,14 +194,33 @@ class MapResolver:
|
|
|
172
194
|
except MapResError:
|
|
173
195
|
raise
|
|
174
196
|
except Exception as exc:
|
|
175
|
-
raise MapResError(f
|
|
197
|
+
raise MapResError(f'Unhandled resolver error: {exc}') from exc
|
|
176
198
|
|
|
177
199
|
|
|
178
|
-
#
|
|
179
|
-
|
|
200
|
+
# ----------------------------------
|
|
201
|
+
# ---------- SIMPLE USAGE ----------
|
|
202
|
+
# ----------------------------------
|
|
203
|
+
_DEFAULT_RESOLVER = MapResolver() # global resolver
|
|
180
204
|
|
|
181
|
-
def
|
|
205
|
+
def setGlobalMaps(maps, *, name=None, priority=0):
|
|
182
206
|
"""
|
|
183
|
-
|
|
207
|
+
Register a global map or datamap class into the default resolver.
|
|
208
|
+
|
|
209
|
+
maps: datamap class OR dict
|
|
210
|
+
name: optional layer name (default = class name or 'global')
|
|
211
|
+
priority: layer priority (lower = earlier)
|
|
184
212
|
"""
|
|
185
|
-
|
|
213
|
+
layer_name = name or getattr(maps, "__name__", "global")
|
|
214
|
+
layer = Layer(layer_name, maps=[maps], priority=priority)
|
|
215
|
+
_DEFAULT_RESOLVER.layers.add_layer(layer)
|
|
216
|
+
|
|
217
|
+
def setDefaultPasses(passes: int):
|
|
218
|
+
if passes < 1:
|
|
219
|
+
raise MapResError("Passes cannot be less than 1")
|
|
220
|
+
_DEFAULT_RESOLVER.passes_default = passes
|
|
221
|
+
|
|
222
|
+
def res(text: str, passes=_DEFAULT_PASSES, **ctx) -> str:
|
|
223
|
+
'''
|
|
224
|
+
Simple resolution using the global default resolver.
|
|
225
|
+
'''
|
|
226
|
+
return _DEFAULT_RESOLVER.res(text, passes=passes, **ctx)
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
from mapres.datamap import datamap, syntax
|
|
2
|
-
|
|
3
|
-
@datamap(syntax=syntax.angles) # produces <>
|
|
4
|
-
class ColorMap:
|
|
5
|
-
black: str = "\033[30m"
|
|
6
|
-
dark_blue: str = "\033[34m"
|
|
7
|
-
dark_green: str = "\033[32m"
|
|
8
|
-
dark_aqua: str = "\033[36m"
|
|
9
|
-
dark_red: str = "\033[31m"
|
|
10
|
-
dark_purple: str = "\033[35m"
|
|
11
|
-
gold: str = "\033[33m"
|
|
12
|
-
gray: str = "\033[37m"
|
|
13
|
-
dark_gray: str = "\033[90m"
|
|
14
|
-
blue: str = "\033[94m"
|
|
15
|
-
green: str = "\033[92m"
|
|
16
|
-
aqua: str = "\033[96m"
|
|
17
|
-
red: str = "\033[91m"
|
|
18
|
-
light_purple: str = "\033[95m"
|
|
19
|
-
yellow: str = "\033[93m"
|
|
20
|
-
white: str = "\033[97m"
|
|
21
|
-
reset: str = "\033[0m"
|
|
22
|
-
bold: str = "\033[1m"
|
|
23
|
-
italic: str = "\033[3m"
|
|
24
|
-
|
|
25
|
-
def as_dict(self):
|
|
26
|
-
return {f"<{k}>": getattr(self, k) for k in self.__dataclass_fields__}
|
|
27
|
-
|
|
28
|
-
# ASCII color map
|
|
29
|
-
ascii_colors = ColorMap()
|
|
30
|
-
|
|
31
|
-
# Minecraft color map
|
|
32
|
-
mc_colors = ColorMap(
|
|
33
|
-
black="§0",
|
|
34
|
-
dark_blue="§1",
|
|
35
|
-
dark_green="§2",
|
|
36
|
-
dark_aqua="§3",
|
|
37
|
-
dark_red="§4",
|
|
38
|
-
dark_purple="§5",
|
|
39
|
-
gold="§6",
|
|
40
|
-
gray="§7",
|
|
41
|
-
dark_gray="§8",
|
|
42
|
-
blue="§9",
|
|
43
|
-
green="§a",
|
|
44
|
-
aqua="§b",
|
|
45
|
-
red="§c",
|
|
46
|
-
light_purple="§d",
|
|
47
|
-
yellow="§e",
|
|
48
|
-
white="§f",
|
|
49
|
-
reset="§r",
|
|
50
|
-
bold="§l",
|
|
51
|
-
italic="§o"
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
# Color strip map
|
|
55
|
-
strip_colors = ColorMap(
|
|
56
|
-
black="",
|
|
57
|
-
dark_blue="",
|
|
58
|
-
dark_green="",
|
|
59
|
-
dark_aqua="",
|
|
60
|
-
dark_red="",
|
|
61
|
-
dark_purple="",
|
|
62
|
-
gold="",
|
|
63
|
-
gray="",
|
|
64
|
-
dark_gray="",
|
|
65
|
-
blue="",
|
|
66
|
-
green="",
|
|
67
|
-
aqua="",
|
|
68
|
-
red="",
|
|
69
|
-
light_purple="",
|
|
70
|
-
yellow="",
|
|
71
|
-
white="",
|
|
72
|
-
reset="",
|
|
73
|
-
bold="",
|
|
74
|
-
italic=""
|
|
75
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|