artlab 1.0.0__py3-none-any.whl

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.
artlab/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """artlab - ASCII art in your terminal."""
2
+
3
+ __version__ = "1.0.0"
artlab/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ from artlab.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
artlab/cli.py ADDED
@@ -0,0 +1,82 @@
1
+ """artlab command-line interface."""
2
+
3
+ import argparse
4
+ import random
5
+ import sys
6
+
7
+ from artlab import __version__
8
+ import artlab.core as core
9
+ from artlab.core import ART, list_pieces, show
10
+
11
+
12
+ def build_parser():
13
+ p = argparse.ArgumentParser(
14
+ prog="artlab",
15
+ description="ASCII art in your terminal. Show bundled art, rainbow text, "
16
+ "or animate it. Zero dependencies.",
17
+ )
18
+ p.add_argument("piece", nargs="?", default=None,
19
+ help="name of a piece to show (see 'artlab list')")
20
+ p.add_argument("-t", "--text", default=None,
21
+ help="render text as block letters (big ASCII)")
22
+ p.add_argument("-l", "--list", action="store_true",
23
+ help="list all available pieces")
24
+ p.add_argument("-r", "--random", action="store_true",
25
+ help="show a random piece")
26
+ p.add_argument("-c", "--color", choices=["rainbow", "green", "cyan",
27
+ "magenta", "none"],
28
+ default="rainbow", help="color palette (default rainbow)")
29
+ p.add_argument("-w", "--width", type=int, default=None,
30
+ help="pad art to a fixed width")
31
+ p.add_argument("--no-center", action="store_true",
32
+ help="don't center the art")
33
+ p.add_argument("--no-color", action="store_true",
34
+ help="don't colorize output")
35
+ p.add_argument("-a", "--animate", action="store_true",
36
+ help="reveal the art with an animation")
37
+ p.add_argument("--version", action="version", version=f"artlab {__version__}")
38
+ return p
39
+
40
+
41
+ def main(argv=None):
42
+ args = build_parser().parse_args(argv)
43
+
44
+ if args.no_color:
45
+ core.NO_COLOR = True
46
+
47
+ if args.list:
48
+ for name in list_pieces():
49
+ print(f" {name}")
50
+ print(f"\n({len(ART)} pieces available)")
51
+ return 0
52
+
53
+ if args.text is not None:
54
+ pieces = args.text if args.text else None
55
+ show(text=args.text, color=args.color, width=args.width,
56
+ center=not args.no_center, animate=args.animate)
57
+ return 0
58
+
59
+ if args.random:
60
+ key, art = random.choice(list(ART.items()))
61
+ show(name=key, color=args.color, width=args.width,
62
+ center=not args.no_center, animate=args.animate)
63
+ return 0
64
+
65
+ if args.piece:
66
+ from artlab.core import pick_piece
67
+ if pick_piece(args.piece)[0] is None:
68
+ print(f"artlab: unknown piece '{args.piece}' (try 'artlab -l')",
69
+ file=sys.stderr)
70
+ return 1
71
+ show(name=args.piece, color=args.color, width=args.width,
72
+ center=not args.no_center, animate=args.animate)
73
+ return 0
74
+
75
+ # default: random piece
76
+ show(color=args.color, width=args.width, center=not args.no_center,
77
+ animate=args.animate)
78
+ return 0
79
+
80
+
81
+ if __name__ == "__main__":
82
+ sys.exit(main())
artlab/core.py ADDED
@@ -0,0 +1,334 @@
1
+ """artlab - ASCII art in your terminal.
2
+
3
+ Bundled ASCII art library, a zero-dependency block-letter text renderer,
4
+ color/rainbow helpers, and simple frame animation. Zero dependencies.
5
+ """
6
+
7
+ import colorsys
8
+ import random
9
+ import shutil
10
+ import sys
11
+ import time
12
+
13
+ # --------------------------------------------------------------------------
14
+ # Bundled ASCII art library
15
+ # --------------------------------------------------------------------------
16
+
17
+ ART = {
18
+ "robot": r""" .-""" + """""" + r""".
19
+ .'_________'.
20
+ / _ _ \
21
+ | (o) (o) |
22
+ | ___ |
23
+ | \_______/ |
24
+ \ _ _ /
25
+ | [ o ] |
26
+ |___|_|___|
27
+ / | | | \
28
+ | | | | |
29
+ ~~~~~~~~~~~~~""",
30
+ "cat": r""" /\_/\
31
+ ( o.o )
32
+ > ^ <
33
+ / \
34
+ \_____/ meow""",
35
+ "dog": r""" / \__
36
+ ( @\___
37
+ / O
38
+ / (_____/
39
+ /_____/ U
40
+ dog""",
41
+ "fox": r""" /\_/\
42
+ ( o.o )
43
+ > ^ <
44
+ / _ \
45
+ \__|__/ ring-ding-ding""",
46
+ "dragon": r""" __====-_ _-====___
47
+ _--^^^#####// \\#####^^^--_
48
+ -^##########/ ( ) \##########^-
49
+ ############/ ( ) \############
50
+ ###########/ ( ) \###########
51
+ #########/ ( ) ( ) \#########
52
+ ########( ( ) ( ) )#######
53
+ #########\ ( ) /#########
54
+ #######\ ( ) /#######
55
+ ####### \ ( ) /#######
56
+ ####### \______/ #######
57
+ d r a g o n""",
58
+ "unicorn": r""" /
59
+ \ /
60
+ \ /____
61
+ ( ____\_________
62
+ ___/ \____\tttt___
63
+ / \____( ' ' ) |\
64
+ ( o' (o o) ) | )
65
+ \ \ (_,_)\___/ /
66
+ \ \____)___(____ )
67
+ \__(___________\__/
68
+ unicorn ~*~*~""",
69
+ "heart": r""" ****** ******
70
+ ********* *********
71
+ *********** ***********
72
+ *********************
73
+ *******************
74
+ *****************
75
+ ***************
76
+ *************
77
+ ***********
78
+ *********
79
+ *******
80
+ *****
81
+ ***
82
+ *""",
83
+ "yoda": r""" ..,
84
+ ( o o )
85
+ ( > < )
86
+ /A A\
87
+ |+. _ .+|
88
+ \_|_|_/
89
+ v v
90
+ use the source""",
91
+ "octopus": r""" _
92
+ .-( )-.
93
+ / _ _ \
94
+ ( (o)(o)(o) )
95
+ \ \___/ /
96
+ \_______/
97
+ | |
98
+ /| |\
99
+ / |_____| \
100
+ ~~~ ~~~
101
+ octopus""",
102
+ "ghost": r""" .-~~~~-.
103
+ / ____ \
104
+ | / \ |
105
+ | | o o | |
106
+ | \____/ |
107
+ \ ____ /
108
+ | | | |
109
+ \|__|/
110
+ / / \ \
111
+ ~~ ~~
112
+ boo!""",
113
+ }
114
+
115
+ # --------------------------------------------------------------------------
116
+ # Minimal block-letter text renderer (zero-dependency figlet-style)
117
+ # --------------------------------------------------------------------------
118
+
119
+ _FONT = {}
120
+
121
+ _Q = [" ##### ", "## ##", "## ##", "## ##", " ##### "]
122
+ _W = ["## ##", "## ##", "## ## ##", "#### ###", "## ##"]
123
+ _H = ["## ##", "## ##", "#######", "## ##", "## ##"]
124
+ _A = [" ##### ", "## ##", "#######", "## ##", "## ##"]
125
+ _R = [" ##### ", "## ##", "##### ", "## ## ", "## ##"]
126
+ _T = ["#######", " # ", " # ", " # ", " # "]
127
+ _P = ["###### ", "## ##", "###### ", "## ", "## "]
128
+ _L = ["## ", "## ", "## ", "## ", "#######"]
129
+ _I = ["###", " # ", " # ", " # ", "###"]
130
+ _E = ["#######", "## ", "##### ", "## ", "#######"]
131
+ _S = [" ######", "## ", " ##### ", " ##", "###### "]
132
+ _O = [" ##### ", "## ##", "## ##", "## ##", " ##### "]
133
+ _U = ["## ##", "## ##", "## ##", "## ##", " ##### "]
134
+ _N = ["## #", "### #", "## # #", "## # #", "## ##"]
135
+ _Y = ["## ##", "## ##", " ##### ", " ## ", " ## "]
136
+ _G = [" ##### ", "## ", "## ###", "## ##", " ##### "]
137
+ _D = ["###### ", "## ##", "## ##", "## ##", "###### "]
138
+ _K = ["## ## ", "## ## ", "#### ", "## ## ", "## ## "]
139
+ _X = ["## ##", " ## ## ", " ### ", " ## ## ", "## ##"]
140
+ _Z = ["#######", " ## ", " ## ", " ## ", "#######"]
141
+ _V = ["## ##", "## ##", "## ##", " ## ## ", " ### "]
142
+ _J = [" ###", " ##", " ##", "## ##", " ##### "]
143
+ _M = ["## ## ##", "### ### ##", "## # # ##", "## ##", "## ##"]
144
+ _B = ["###### ", "## ##", "###### ", "## ##", "###### "]
145
+ _F = ["#######", "## ", "##### ", "## ", "## "]
146
+ _C = [" ##### ", "## ", "## ", "## ", " ##### "]
147
+
148
+ _FONT = {
149
+ "0": _O, "1": [" ## ", " #### ", " ## ", " ## ", " ## "],
150
+ "2": [" #### ", " ##", " #### ", "## ", "##### "],
151
+ "3": [" #### ", " ##", " #### ", " ##", " #### "],
152
+ "4": ["## ##", "## ##", "#######", " ##", " ##"],
153
+ "5": ["#######", "## ", "##### ", " ##", "##### "],
154
+ "6": [" ##### ", "## ", "###### ", "## ##", " ##### "],
155
+ "7": ["#######", " ## ", " ## ", " ## ", " ## "],
156
+ "8": [" ##### ", "## ##", " ##### ", "## ##", " ##### "],
157
+ "9": [" ##### ", "## ##", " #######", " ##", " ##### "],
158
+ ".": [" ", " ", " ", " ", " ## "],
159
+ " ": [" ", " ", " ", " ", " "],
160
+ "!": ["###", "###", "###", " ", " # "],
161
+ "?": ["#### ", " ##", " ## ", " ", " # "],
162
+ "-": [" ", " ", "#####", " ", " "],
163
+ }
164
+
165
+ # Assign letters to their glyphs
166
+ for _char, _glyph in [
167
+ ("A", _A), ("B", _B), ("C", _C), ("D", _D), ("E", _E), ("F", _F),
168
+ ("G", _G), ("H", _H), ("I", _I), ("J", _J), ("K", _K), ("L", _L),
169
+ ("M", _M), ("N", _N), ("O", _O), ("P", _P), ("Q", _Q), ("R", _R),
170
+ ("S", _S), ("T", _T), ("U", _U), ("V", _V), ("W", _W), ("X", _X),
171
+ ("Y", _Y), ("Z", _Z),
172
+ ]:
173
+ _FONT[_char] = _glyph
174
+
175
+
176
+ def render_text(text, font="block"):
177
+ """Render text as block letters (zero dependencies). Returns list of lines."""
178
+ lines = ["" for _ in range(5)]
179
+ for ch in text.upper():
180
+ glyph = _FONT.get(ch, _FONT[" "])
181
+ for i in range(5):
182
+ lines[i] += glyph[i] + " "
183
+ return [line.rstrip() for line in lines]
184
+
185
+
186
+ # --------------------------------------------------------------------------
187
+ # Color helpers
188
+ # --------------------------------------------------------------------------
189
+
190
+ NO_COLOR = False
191
+ FORCE_COLOR = False
192
+
193
+ RESET = "\033[0m"
194
+
195
+
196
+ def _should_colorize(palette, out):
197
+ if NO_COLOR or palette[0] == "":
198
+ return False
199
+ if FORCE_COLOR:
200
+ return True
201
+ return bool(getattr(out, "isatty", lambda: False)())
202
+
203
+
204
+ def _rainbow_codes(n):
205
+ codes = []
206
+ for i in range(n):
207
+ h = i / max(1, n) if n > 1 else 0.0
208
+ r, g, b = colorsys.hsv_to_rgb(h, 1.0, 1.0)
209
+ codes.append(f"\033[38;2;{int(r*255)};{int(g*255)};{int(b*255)}m")
210
+ return codes
211
+
212
+
213
+ def _color_lines(lines, palette, cycle=False, out=None):
214
+ if not _should_colorize(palette, out):
215
+ return lines
216
+ res = []
217
+ for idx, line in enumerate(lines):
218
+ code = palette[idx % len(palette)] if cycle else palette[0]
219
+ res.append(code + line + RESET)
220
+ return res
221
+
222
+
223
+ RAINBOW_PALETTE = [
224
+ "\033[38;5;196m", "\033[38;5;208m", "\033[38;5;226m", "\033[38;5;46m",
225
+ "\033[38;5;39m", "\033[38;5;93m", "\033[38;5;201m",
226
+ ]
227
+ GREEN = "\033[38;5;82m"
228
+ CYAN = "\033[38;5;45m"
229
+ MAGENTA = "\033[38;5;201m"
230
+
231
+
232
+ def _palette(kind):
233
+ return {
234
+ "rainbow": RAINBOW_PALETTE,
235
+ "green": [GREEN],
236
+ "cyan": [CYAN],
237
+ "magenta": [MAGENTA],
238
+ "none": [""],
239
+ }.get(kind, RAINBOW_PALETTE)
240
+
241
+
242
+ # --------------------------------------------------------------------------
243
+ # Art selection and display
244
+ # --------------------------------------------------------------------------
245
+
246
+ def list_pieces():
247
+ return sorted(ART.keys())
248
+
249
+
250
+ def pick_piece(name=None):
251
+ if name:
252
+ name = name.lower()
253
+ if name in ART:
254
+ return name, ART[name]
255
+ for key in ART:
256
+ if key.startswith(name):
257
+ return key, ART[key]
258
+ return None, None
259
+ return None, None
260
+
261
+
262
+ def show(name=None, text=None, color="rainbow", width=None, center=True,
263
+ animate=False, frames=20, delay=0.06, out=None, return_lines=False):
264
+ """Render and (optionally) print art. Returns the rendered lines."""
265
+ if out is None:
266
+ out = sys.stdout
267
+
268
+ def build():
269
+ if text is not None:
270
+ return render_text(text)
271
+ if name:
272
+ key, art = pick_piece(name)
273
+ if not art:
274
+ return None
275
+ return art.splitlines()
276
+ key, art = random.choice(list(ART.items()))
277
+ return art.splitlines()
278
+
279
+ lines = build()
280
+ if lines is None:
281
+ return None
282
+ if return_lines:
283
+ return lines
284
+
285
+ lines = _fit_width(lines, width, center=center)
286
+ lines = _color_lines(lines, _palette(color), cycle=(color == "rainbow"), out=out)
287
+ if animate:
288
+ _animate(lines, out, frames, delay)
289
+ else:
290
+ for line in lines:
291
+ out.write(line + "\n")
292
+ out.flush()
293
+ return lines
294
+
295
+
296
+ def _fit_width(lines, width, center=True):
297
+ if not width:
298
+ maxlen = max((len(line) for line in lines), default=0)
299
+ width = maxlen
300
+ return [_center(line, width) if center else line for line in lines]
301
+
302
+
303
+ def _center(line, width):
304
+ pad = width - len(line)
305
+ if pad <= 0:
306
+ return line
307
+ left = pad // 2
308
+ return " " * left + line
309
+
310
+
311
+ def _animate(lines, out, frames, delay):
312
+ terminal = shutil.get_terminal_size((80, 24)).lines
313
+ height = len(lines)
314
+ for frame in range(frames):
315
+ upto = int((frame + 1) / frames * height)
316
+ view = lines[max(0, upto - min(terminal, height)) : upto]
317
+ out.write("\033[H\033[J")
318
+ for line in view:
319
+ out.write(line + "\n")
320
+ out.flush()
321
+ time.sleep(delay)
322
+
323
+
324
+ def random_piece():
325
+ name, art = random.choice(list(ART.items()))
326
+ return name, art
327
+
328
+
329
+ def pieces_count():
330
+ return len(ART)
331
+
332
+
333
+ def main_extras():
334
+ return None
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.4
2
+ Name: artlab
3
+ Version: 1.0.0
4
+ Summary: ASCII art in your terminal. Zero dependencies.
5
+ Author: dsk-dev-ai
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/dsk-dev-ai/artlab
8
+ Project-URL: Source, https://github.com/dsk-dev-ai/artlab
9
+ Project-URL: Issues, https://github.com/dsk-dev-ai/artlab/issues
10
+ Project-URL: Funding, https://github.com/sponsors/dsk-dev-ai
11
+ Keywords: ascii,art,terminal,cli,fun,text,rainbow,ascii-art
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Artistic Software
24
+ Classifier: Topic :: Terminals
25
+ Classifier: Topic :: Utilities
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Dynamic: license-file
30
+
31
+ <div align="center">
32
+
33
+ # 🎨 artlab
34
+
35
+ **ASCII art in your terminal.**
36
+
37
+ Bundled retro art, big block-letter text, rainbow colors, and animation.
38
+ Zero dependencies. Works in Python 3.8+.
39
+
40
+ [![PyPI](https://img.shields.io/pypi/v/artlab?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/artlab/)
41
+ [![Python](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)](#)
42
+ [![License](https://img.shields.io/badge/license-MIT-green)](#)
43
+ [![Docker](https://img.shields.io/badge/docker-ghcr.io%2Fdsk--dev--ai%2Fartlab-blue?logo=docker)](https://github.com/dsk-dev-ai/artlab/pkgs/container/artlab)
44
+
45
+ </div>
46
+
47
+ ---
48
+
49
+ ## Why artlab?
50
+
51
+ Because the terminal deserves a little personality.
52
+
53
+ - **Bundled ASCII art** — robots, cats, dragons, unicorns, yoda, octopuses, hearts and more.
54
+ - **Block-letter text** — print any word big, `figlet`-style, with zero dependencies.
55
+ - **Rainbow & colors** — 256-color palettes, or dims down for your pipelines.
56
+ - **Animation** — reveal art with a slick frame-by-frame intro.
57
+ - **Zero dependencies** — pure Python stdlib. No install drama.
58
+
59
+ ## Install
60
+
61
+ ```bash
62
+ pip install artlab
63
+ ```
64
+
65
+ Or run without installing:
66
+
67
+ ```bash
68
+ pipx run artlab --help
69
+ ```
70
+
71
+ Via Docker:
72
+
73
+ ```bash
74
+ docker run --rm ghcr.io/dsk-dev-ai/artlab --help
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ ```bash
80
+ # Show a random piece
81
+ artlab
82
+
83
+ # Show a specific piece
84
+ artlab robot
85
+ artlab cat
86
+ artlab dragon
87
+
88
+ # List everything
89
+ artlab -l
90
+
91
+ # Print big block text
92
+ artlab --text "SHIP IT"
93
+ artlab -t "artlab" -c cyan
94
+
95
+ # Force a palette
96
+ artlab robot -c green
97
+ artlab dragon -c magenta
98
+
99
+ # Animate the reveal
100
+ artlab unicorn -a
101
+
102
+ # No color (for scripts / piping)
103
+ artlab robot --no-color
104
+ ```
105
+
106
+ ### Options
107
+
108
+ | Flag | Description |
109
+ |------|-------------|
110
+ | `-l, --list` | List all available pieces |
111
+ | `-r, --random` | Show a random piece |
112
+ | `-t, --text TEXT` | Render text as big block letters |
113
+ | `-c, --color` | Palette: `rainbow`, `green`, `cyan`, `magenta`, `none` |
114
+ | `-w, --width N` | Pad art to a fixed width |
115
+ | `--no-center` | Don't center the art |
116
+ | `-a, --animate` | Reveal the art with an animation |
117
+ | `--no-color` | Disable color output |
118
+ | `--version` | Print version |
119
+
120
+ ## Gallery
121
+
122
+ Run `artlab` to see a random piece, or `artlab -l` to browse the full library.
123
+ Everything is bundled — no API, no network, no nonsense.
124
+
125
+ ```
126
+ /\_/\
127
+ ( o.o )
128
+ > ^ <
129
+ / \
130
+ \_____/ meow
131
+ ```
132
+
133
+ ## Tests
134
+
135
+ ```bash
136
+ python -m pytest
137
+ ```
138
+
139
+ Tested on Python 3.8–3.12 via GitHub Actions.
140
+
141
+ ## Sponsor
142
+
143
+ Like `artlab`? Keep the terminal artsy for free by [becoming a sponsor](https://github.com/sponsors/dsk-dev-ai) on GitHub 💜.
144
+
145
+ ---
146
+
147
+ <div align="center">
148
+
149
+ **artlab** · because the terminal deserves art.
150
+
151
+ </div>
@@ -0,0 +1,10 @@
1
+ artlab/__init__.py,sha256=WbUsMzYEirGLjM6yxwN34pqhNYAjQ0HjsViR6wH1mGE,66
2
+ artlab/__main__.py,sha256=zJBxAKu18wg4b_wE0GaiRUplpNLEVZTEBNlz2JUtdwo,67
3
+ artlab/cli.py,sha256=OBygYnY6tXvSkjfD2IhLElcoNS6CFyFl3haTiAXcPUg,2901
4
+ artlab/core.py,sha256=KI6rCZcOHbw_6NmFmg9A5AJAZ9_d85POoEB425ZwHt4,9612
5
+ artlab-1.0.0.dist-info/licenses/LICENSE,sha256=EAxljeOlydi0CA5dhf2z72wEjAtq_9Ig44QyLQ7XWLM,1067
6
+ artlab-1.0.0.dist-info/METADATA,sha256=G6HgvfUPwans2seRs2UW_Lo06Hgg77-_L25967xLFks,3884
7
+ artlab-1.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
8
+ artlab-1.0.0.dist-info/entry_points.txt,sha256=TADcrd5_LCLJQFJeNL_eI8gKJ5nyLfe1KmJ-yOODgfU,43
9
+ artlab-1.0.0.dist-info/top_level.txt,sha256=oO456VQwkMHu8SEyupOvEwYdXxhHJ-bjn4o_mkxye-k,7
10
+ artlab-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ artlab = artlab.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsk-dev-ai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ artlab