zrb 1.21.29__py3-none-any.whl → 2.0.0a4__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.
Potentially problematic release.
This version of zrb might be problematic. Click here for more details.
- zrb/__init__.py +118 -129
- zrb/builtin/__init__.py +54 -2
- zrb/builtin/llm/chat.py +147 -0
- zrb/callback/callback.py +8 -1
- zrb/cmd/cmd_result.py +2 -1
- zrb/config/config.py +491 -280
- zrb/config/helper.py +84 -0
- zrb/config/web_auth_config.py +50 -35
- zrb/context/any_shared_context.py +13 -2
- zrb/context/context.py +31 -3
- zrb/context/print_fn.py +13 -0
- zrb/context/shared_context.py +14 -1
- zrb/input/option_input.py +30 -2
- zrb/llm/agent/__init__.py +9 -0
- zrb/llm/agent/agent.py +215 -0
- zrb/llm/agent/summarizer.py +20 -0
- zrb/llm/app/__init__.py +10 -0
- zrb/llm/app/completion.py +281 -0
- zrb/llm/app/confirmation/allow_tool.py +66 -0
- zrb/llm/app/confirmation/handler.py +178 -0
- zrb/llm/app/confirmation/replace_confirmation.py +77 -0
- zrb/llm/app/keybinding.py +34 -0
- zrb/llm/app/layout.py +117 -0
- zrb/llm/app/lexer.py +155 -0
- zrb/llm/app/redirection.py +28 -0
- zrb/llm/app/style.py +16 -0
- zrb/llm/app/ui.py +733 -0
- zrb/llm/config/__init__.py +4 -0
- zrb/llm/config/config.py +122 -0
- zrb/llm/config/limiter.py +247 -0
- zrb/llm/history_manager/__init__.py +4 -0
- zrb/llm/history_manager/any_history_manager.py +23 -0
- zrb/llm/history_manager/file_history_manager.py +91 -0
- zrb/llm/history_processor/summarizer.py +108 -0
- zrb/llm/note/__init__.py +3 -0
- zrb/llm/note/manager.py +122 -0
- zrb/llm/prompt/__init__.py +29 -0
- zrb/llm/prompt/claude_compatibility.py +92 -0
- zrb/llm/prompt/compose.py +55 -0
- zrb/llm/prompt/default.py +51 -0
- zrb/llm/prompt/markdown/mandate.md +23 -0
- zrb/llm/prompt/markdown/persona.md +3 -0
- zrb/llm/prompt/markdown/summarizer.md +21 -0
- zrb/llm/prompt/note.py +41 -0
- zrb/llm/prompt/system_context.py +46 -0
- zrb/llm/prompt/zrb.py +41 -0
- zrb/llm/skill/__init__.py +3 -0
- zrb/llm/skill/manager.py +86 -0
- zrb/llm/task/__init__.py +4 -0
- zrb/llm/task/llm_chat_task.py +316 -0
- zrb/llm/task/llm_task.py +245 -0
- zrb/llm/tool/__init__.py +39 -0
- zrb/llm/tool/bash.py +75 -0
- zrb/llm/tool/code.py +266 -0
- zrb/llm/tool/file.py +419 -0
- zrb/llm/tool/note.py +70 -0
- zrb/{builtin/llm → llm}/tool/rag.py +8 -5
- zrb/llm/tool/search/brave.py +53 -0
- zrb/llm/tool/search/searxng.py +47 -0
- zrb/llm/tool/search/serpapi.py +47 -0
- zrb/llm/tool/skill.py +19 -0
- zrb/llm/tool/sub_agent.py +70 -0
- zrb/llm/tool/web.py +97 -0
- zrb/llm/tool/zrb_task.py +66 -0
- zrb/llm/util/attachment.py +101 -0
- zrb/llm/util/prompt.py +104 -0
- zrb/llm/util/stream_response.py +178 -0
- zrb/session/any_session.py +0 -3
- zrb/session/session.py +1 -1
- zrb/task/base/context.py +25 -13
- zrb/task/base/execution.py +52 -47
- zrb/task/base/lifecycle.py +7 -4
- zrb/task/base_task.py +48 -49
- zrb/task/base_trigger.py +4 -1
- zrb/task/cmd_task.py +6 -0
- zrb/task/http_check.py +11 -5
- zrb/task/make_task.py +3 -0
- zrb/task/rsync_task.py +5 -0
- zrb/task/scaffolder.py +7 -4
- zrb/task/scheduler.py +3 -0
- zrb/task/tcp_check.py +6 -4
- zrb/util/ascii_art/art/bee.txt +17 -0
- zrb/util/ascii_art/art/cat.txt +9 -0
- zrb/util/ascii_art/art/ghost.txt +16 -0
- zrb/util/ascii_art/art/panda.txt +17 -0
- zrb/util/ascii_art/art/rose.txt +14 -0
- zrb/util/ascii_art/art/unicorn.txt +15 -0
- zrb/util/ascii_art/banner.py +92 -0
- zrb/util/cli/markdown.py +22 -2
- zrb/util/cmd/command.py +33 -10
- zrb/util/file.py +51 -32
- zrb/util/match.py +78 -0
- zrb/util/run.py +3 -3
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/METADATA +9 -15
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/RECORD +100 -128
- zrb/attr/__init__.py +0 -0
- zrb/builtin/llm/attachment.py +0 -40
- zrb/builtin/llm/chat_completion.py +0 -274
- zrb/builtin/llm/chat_session.py +0 -270
- zrb/builtin/llm/chat_session_cmd.py +0 -288
- zrb/builtin/llm/chat_trigger.py +0 -79
- zrb/builtin/llm/history.py +0 -71
- zrb/builtin/llm/input.py +0 -27
- zrb/builtin/llm/llm_ask.py +0 -269
- zrb/builtin/llm/previous-session.js +0 -21
- zrb/builtin/llm/tool/__init__.py +0 -0
- zrb/builtin/llm/tool/api.py +0 -75
- zrb/builtin/llm/tool/cli.py +0 -52
- zrb/builtin/llm/tool/code.py +0 -236
- zrb/builtin/llm/tool/file.py +0 -560
- zrb/builtin/llm/tool/note.py +0 -84
- zrb/builtin/llm/tool/sub_agent.py +0 -150
- zrb/builtin/llm/tool/web.py +0 -171
- zrb/builtin/project/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/__init__.py +0 -0
- zrb/builtin/project/create/__init__.py +0 -0
- zrb/builtin/shell/__init__.py +0 -0
- zrb/builtin/shell/autocomplete/__init__.py +0 -0
- zrb/callback/__init__.py +0 -0
- zrb/cmd/__init__.py +0 -0
- zrb/config/default_prompt/interactive_system_prompt.md +0 -29
- zrb/config/default_prompt/persona.md +0 -1
- zrb/config/default_prompt/summarization_prompt.md +0 -57
- zrb/config/default_prompt/system_prompt.md +0 -38
- zrb/config/llm_config.py +0 -339
- zrb/config/llm_context/config.py +0 -166
- zrb/config/llm_context/config_parser.py +0 -40
- zrb/config/llm_context/workflow.py +0 -81
- zrb/config/llm_rate_limitter.py +0 -190
- zrb/content_transformer/__init__.py +0 -0
- zrb/context/__init__.py +0 -0
- zrb/dot_dict/__init__.py +0 -0
- zrb/env/__init__.py +0 -0
- zrb/group/__init__.py +0 -0
- zrb/input/__init__.py +0 -0
- zrb/runner/__init__.py +0 -0
- zrb/runner/web_route/__init__.py +0 -0
- zrb/runner/web_route/home_page/__init__.py +0 -0
- zrb/session/__init__.py +0 -0
- zrb/session_state_log/__init__.py +0 -0
- zrb/session_state_logger/__init__.py +0 -0
- zrb/task/__init__.py +0 -0
- zrb/task/base/__init__.py +0 -0
- zrb/task/llm/__init__.py +0 -0
- zrb/task/llm/agent.py +0 -204
- zrb/task/llm/agent_runner.py +0 -152
- zrb/task/llm/config.py +0 -122
- zrb/task/llm/conversation_history.py +0 -209
- zrb/task/llm/conversation_history_model.py +0 -67
- zrb/task/llm/default_workflow/coding/workflow.md +0 -41
- zrb/task/llm/default_workflow/copywriting/workflow.md +0 -68
- zrb/task/llm/default_workflow/git/workflow.md +0 -118
- zrb/task/llm/default_workflow/golang/workflow.md +0 -128
- zrb/task/llm/default_workflow/html-css/workflow.md +0 -135
- zrb/task/llm/default_workflow/java/workflow.md +0 -146
- zrb/task/llm/default_workflow/javascript/workflow.md +0 -158
- zrb/task/llm/default_workflow/python/workflow.md +0 -160
- zrb/task/llm/default_workflow/researching/workflow.md +0 -153
- zrb/task/llm/default_workflow/rust/workflow.md +0 -162
- zrb/task/llm/default_workflow/shell/workflow.md +0 -299
- zrb/task/llm/error.py +0 -95
- zrb/task/llm/file_replacement.py +0 -206
- zrb/task/llm/file_tool_model.py +0 -57
- zrb/task/llm/history_processor.py +0 -206
- zrb/task/llm/history_summarization.py +0 -25
- zrb/task/llm/print_node.py +0 -221
- zrb/task/llm/prompt.py +0 -321
- zrb/task/llm/subagent_conversation_history.py +0 -41
- zrb/task/llm/tool_wrapper.py +0 -361
- zrb/task/llm/typing.py +0 -3
- zrb/task/llm/workflow.py +0 -76
- zrb/task/llm_task.py +0 -379
- zrb/task_status/__init__.py +0 -0
- zrb/util/__init__.py +0 -0
- zrb/util/cli/__init__.py +0 -0
- zrb/util/cmd/__init__.py +0 -0
- zrb/util/codemod/__init__.py +0 -0
- zrb/util/string/__init__.py +0 -0
- zrb/xcom/__init__.py +0 -0
- /zrb/{config/default_prompt/file_extractor_system_prompt.md → llm/prompt/markdown/file_extractor.md} +0 -0
- /zrb/{config/default_prompt/repo_extractor_system_prompt.md → llm/prompt/markdown/repo_extractor.md} +0 -0
- /zrb/{config/default_prompt/repo_summarizer_system_prompt.md → llm/prompt/markdown/repo_summarizer.md} +0 -0
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/WHEEL +0 -0
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/entry_points.txt +0 -0
zrb/task/base_task.py
CHANGED
|
@@ -3,8 +3,9 @@ import inspect
|
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
|
-
from zrb.attr.type import
|
|
6
|
+
from zrb.attr.type import fstring
|
|
7
7
|
from zrb.context.any_context import AnyContext
|
|
8
|
+
from zrb.context.print_fn import PrintFn
|
|
8
9
|
from zrb.env.any_env import AnyEnv
|
|
9
10
|
from zrb.input.any_input import AnyInput
|
|
10
11
|
from zrb.session.any_session import AnySession
|
|
@@ -55,7 +56,7 @@ class BaseTask(AnyTask):
|
|
|
55
56
|
input: list[AnyInput | None] | AnyInput | None = None,
|
|
56
57
|
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
57
58
|
action: fstring | Callable[[AnyContext], Any] | None = None,
|
|
58
|
-
execute_condition:
|
|
59
|
+
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
|
59
60
|
retries: int = 2,
|
|
60
61
|
retry_period: float = 0,
|
|
61
62
|
readiness_check: list[AnyTask] | AnyTask | None = None,
|
|
@@ -67,10 +68,20 @@ class BaseTask(AnyTask):
|
|
|
67
68
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
68
69
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
69
70
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
71
|
+
print_fn: PrintFn | None = None,
|
|
70
72
|
):
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
# Optimized stack retrieval
|
|
74
|
+
frame = inspect.currentframe()
|
|
75
|
+
if frame is not None:
|
|
76
|
+
caller_frame = frame.f_back
|
|
77
|
+
self.__decl_file = (
|
|
78
|
+
caller_frame.f_code.co_filename if caller_frame else "unknown"
|
|
79
|
+
)
|
|
80
|
+
self.__decl_line = caller_frame.f_lineno if caller_frame else 0
|
|
81
|
+
else:
|
|
82
|
+
self.__decl_file = "unknown"
|
|
83
|
+
self.__decl_line = 0
|
|
84
|
+
|
|
74
85
|
self._name = name
|
|
75
86
|
self._color = color
|
|
76
87
|
self._icon = icon
|
|
@@ -80,10 +91,10 @@ class BaseTask(AnyTask):
|
|
|
80
91
|
self._envs = env
|
|
81
92
|
self._retries = retries
|
|
82
93
|
self._retry_period = retry_period
|
|
83
|
-
self._upstreams = upstream
|
|
84
|
-
self._fallbacks = fallback
|
|
85
|
-
self._successors = successor
|
|
86
|
-
self._readiness_checks = readiness_check
|
|
94
|
+
self._upstreams = self._ensure_task_list(upstream)
|
|
95
|
+
self._fallbacks = self._ensure_task_list(fallback)
|
|
96
|
+
self._successors = self._ensure_task_list(successor)
|
|
97
|
+
self._readiness_checks = self._ensure_task_list(readiness_check)
|
|
87
98
|
self._readiness_check_delay = readiness_check_delay
|
|
88
99
|
self._readiness_check_period = readiness_check_period
|
|
89
100
|
self._readiness_failure_threshold = readiness_failure_threshold
|
|
@@ -91,6 +102,14 @@ class BaseTask(AnyTask):
|
|
|
91
102
|
self._monitor_readiness = monitor_readiness
|
|
92
103
|
self._execute_condition = execute_condition
|
|
93
104
|
self._action = action
|
|
105
|
+
self._print_fn = print_fn
|
|
106
|
+
|
|
107
|
+
def _ensure_task_list(self, tasks: AnyTask | list[AnyTask] | None) -> list[AnyTask]:
|
|
108
|
+
if tasks is None:
|
|
109
|
+
return []
|
|
110
|
+
if isinstance(tasks, list):
|
|
111
|
+
return tasks
|
|
112
|
+
return [tasks]
|
|
94
113
|
|
|
95
114
|
def __repr__(self):
|
|
96
115
|
return f"<{self.__class__.__name__} name={self.name}>"
|
|
@@ -132,18 +151,10 @@ class BaseTask(AnyTask):
|
|
|
132
151
|
@property
|
|
133
152
|
def fallbacks(self) -> list[AnyTask]:
|
|
134
153
|
"""Returns the list of fallback tasks."""
|
|
135
|
-
|
|
136
|
-
return []
|
|
137
|
-
elif isinstance(self._fallbacks, list):
|
|
138
|
-
return self._fallbacks
|
|
139
|
-
return [self._fallbacks] # Assume single task
|
|
154
|
+
return self._fallbacks
|
|
140
155
|
|
|
141
156
|
def append_fallback(self, fallbacks: AnyTask | list[AnyTask]):
|
|
142
157
|
"""Appends fallback tasks, ensuring no duplicates."""
|
|
143
|
-
if self._fallbacks is None:
|
|
144
|
-
self._fallbacks = []
|
|
145
|
-
elif not isinstance(self._fallbacks, list):
|
|
146
|
-
self._fallbacks = [self._fallbacks]
|
|
147
158
|
to_add = fallbacks if isinstance(fallbacks, list) else [fallbacks]
|
|
148
159
|
for fb in to_add:
|
|
149
160
|
if fb not in self._fallbacks:
|
|
@@ -152,18 +163,10 @@ class BaseTask(AnyTask):
|
|
|
152
163
|
@property
|
|
153
164
|
def successors(self) -> list[AnyTask]:
|
|
154
165
|
"""Returns the list of successor tasks."""
|
|
155
|
-
|
|
156
|
-
return []
|
|
157
|
-
elif isinstance(self._successors, list):
|
|
158
|
-
return self._successors
|
|
159
|
-
return [self._successors] # Assume single task
|
|
166
|
+
return self._successors
|
|
160
167
|
|
|
161
168
|
def append_successor(self, successors: AnyTask | list[AnyTask]):
|
|
162
169
|
"""Appends successor tasks, ensuring no duplicates."""
|
|
163
|
-
if self._successors is None:
|
|
164
|
-
self._successors = []
|
|
165
|
-
elif not isinstance(self._successors, list):
|
|
166
|
-
self._successors = [self._successors]
|
|
167
170
|
to_add = successors if isinstance(successors, list) else [successors]
|
|
168
171
|
for succ in to_add:
|
|
169
172
|
if succ not in self._successors:
|
|
@@ -172,18 +175,10 @@ class BaseTask(AnyTask):
|
|
|
172
175
|
@property
|
|
173
176
|
def readiness_checks(self) -> list[AnyTask]:
|
|
174
177
|
"""Returns the list of readiness check tasks."""
|
|
175
|
-
|
|
176
|
-
return []
|
|
177
|
-
elif isinstance(self._readiness_checks, list):
|
|
178
|
-
return self._readiness_checks
|
|
179
|
-
return [self._readiness_checks] # Assume single task
|
|
178
|
+
return self._readiness_checks
|
|
180
179
|
|
|
181
180
|
def append_readiness_check(self, readiness_checks: AnyTask | list[AnyTask]):
|
|
182
181
|
"""Appends readiness check tasks, ensuring no duplicates."""
|
|
183
|
-
if self._readiness_checks is None:
|
|
184
|
-
self._readiness_checks = []
|
|
185
|
-
elif not isinstance(self._readiness_checks, list):
|
|
186
|
-
self._readiness_checks = [self._readiness_checks]
|
|
187
182
|
to_add = (
|
|
188
183
|
readiness_checks
|
|
189
184
|
if isinstance(readiness_checks, list)
|
|
@@ -196,18 +191,10 @@ class BaseTask(AnyTask):
|
|
|
196
191
|
@property
|
|
197
192
|
def upstreams(self) -> list[AnyTask]:
|
|
198
193
|
"""Returns the list of upstream tasks."""
|
|
199
|
-
|
|
200
|
-
return []
|
|
201
|
-
elif isinstance(self._upstreams, list):
|
|
202
|
-
return self._upstreams
|
|
203
|
-
return [self._upstreams] # Assume single task
|
|
194
|
+
return self._upstreams
|
|
204
195
|
|
|
205
196
|
def append_upstream(self, upstreams: AnyTask | list[AnyTask]):
|
|
206
197
|
"""Appends upstream tasks, ensuring no duplicates."""
|
|
207
|
-
if self._upstreams is None:
|
|
208
|
-
self._upstreams = []
|
|
209
|
-
elif not isinstance(self._upstreams, list):
|
|
210
|
-
self._upstreams = [self._upstreams]
|
|
211
198
|
to_add = upstreams if isinstance(upstreams, list) else [upstreams]
|
|
212
199
|
for up in to_add:
|
|
213
200
|
if up not in self._upstreams:
|
|
@@ -240,7 +227,13 @@ class BaseTask(AnyTask):
|
|
|
240
227
|
"""
|
|
241
228
|
# Use asyncio.run() to execute the async cleanup wrapper
|
|
242
229
|
return asyncio.run(
|
|
243
|
-
run_and_cleanup(
|
|
230
|
+
run_and_cleanup(
|
|
231
|
+
self,
|
|
232
|
+
session=session,
|
|
233
|
+
print_fn=self._print_fn,
|
|
234
|
+
str_kwargs=str_kwargs,
|
|
235
|
+
kwargs=kwargs,
|
|
236
|
+
)
|
|
244
237
|
)
|
|
245
238
|
|
|
246
239
|
async def async_run(
|
|
@@ -250,7 +243,11 @@ class BaseTask(AnyTask):
|
|
|
250
243
|
kwargs: dict[str, Any] | None = None,
|
|
251
244
|
) -> Any:
|
|
252
245
|
return await run_task_async(
|
|
253
|
-
self,
|
|
246
|
+
self,
|
|
247
|
+
session=session,
|
|
248
|
+
print_fn=self._print_fn,
|
|
249
|
+
str_kwargs=str_kwargs,
|
|
250
|
+
kwargs=kwargs,
|
|
254
251
|
)
|
|
255
252
|
|
|
256
253
|
async def exec_root_tasks(self, session: AnySession):
|
|
@@ -277,6 +274,8 @@ class BaseTask(AnyTask):
|
|
|
277
274
|
try:
|
|
278
275
|
# Delegate to the helper function for the default behavior
|
|
279
276
|
return await run_default_action(self, ctx)
|
|
277
|
+
except (KeyboardInterrupt, GeneratorExit):
|
|
278
|
+
raise
|
|
280
279
|
except BaseException as e:
|
|
281
280
|
additional_error_note = (
|
|
282
281
|
f"Task: {self.name} ({self.__decl_file}:{self.__decl_line})"
|
|
@@ -298,7 +297,7 @@ class BaseTask(AnyTask):
|
|
|
298
297
|
|
|
299
298
|
def task_runner_fn(**kwargs) -> Any:
|
|
300
299
|
task_kwargs = self._get_func_kwargs(kwargs)
|
|
301
|
-
shared_ctx = SharedContext()
|
|
300
|
+
shared_ctx = SharedContext(print_fn=self._print_fn)
|
|
302
301
|
session = Session(shared_ctx=shared_ctx)
|
|
303
302
|
return self.run(session=session, kwargs=task_kwargs)
|
|
304
303
|
|
|
@@ -318,7 +317,7 @@ class BaseTask(AnyTask):
|
|
|
318
317
|
def _create_fn_docstring(self) -> str:
|
|
319
318
|
from zrb.context.shared_context import SharedContext
|
|
320
319
|
|
|
321
|
-
stub_shared_ctx = SharedContext()
|
|
320
|
+
stub_shared_ctx = SharedContext(print_fn=self._print_fn)
|
|
322
321
|
str_input_default_values = {}
|
|
323
322
|
for inp in self.inputs:
|
|
324
323
|
str_input_default_values[inp.name] = inp.get_default_str(stub_shared_ctx)
|
zrb/task/base_trigger.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Any
|
|
|
5
5
|
from zrb.attr.type import fstring
|
|
6
6
|
from zrb.callback.any_callback import AnyCallback
|
|
7
7
|
from zrb.context.any_context import AnyContext
|
|
8
|
-
from zrb.context.
|
|
8
|
+
from zrb.context.print_fn import PrintFn
|
|
9
9
|
from zrb.context.shared_context import SharedContext
|
|
10
10
|
from zrb.dot_dict.dot_dict import DotDict
|
|
11
11
|
from zrb.env.any_env import AnyEnv
|
|
@@ -50,6 +50,7 @@ class BaseTrigger(BaseTask):
|
|
|
50
50
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
51
51
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
52
52
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
53
|
+
print_fn: PrintFn | None = None,
|
|
53
54
|
):
|
|
54
55
|
"""
|
|
55
56
|
Initializes a new instance of the BaseTrigger class.
|
|
@@ -103,6 +104,7 @@ class BaseTrigger(BaseTask):
|
|
|
103
104
|
upstream=upstream,
|
|
104
105
|
fallback=fallback,
|
|
105
106
|
successor=successor,
|
|
107
|
+
print_fn=print_fn,
|
|
106
108
|
)
|
|
107
109
|
self._callbacks = callback
|
|
108
110
|
self._queue_name = queue_name
|
|
@@ -144,6 +146,7 @@ class BaseTrigger(BaseTask):
|
|
|
144
146
|
shared_ctx=SharedContext(
|
|
145
147
|
input=dict(session.shared_ctx.input),
|
|
146
148
|
xcom=xcom_dict,
|
|
149
|
+
print_fn=self._print_fn,
|
|
147
150
|
),
|
|
148
151
|
parent=session,
|
|
149
152
|
root_group=session.root_group,
|
zrb/task/cmd_task.py
CHANGED
|
@@ -6,6 +6,7 @@ from zrb.cmd.cmd_result import CmdResult
|
|
|
6
6
|
from zrb.cmd.cmd_val import AnyCmdVal, CmdVal, SingleCmdVal
|
|
7
7
|
from zrb.config.config import CFG
|
|
8
8
|
from zrb.context.any_context import AnyContext
|
|
9
|
+
from zrb.context.print_fn import PrintFn
|
|
9
10
|
from zrb.env.any_env import AnyEnv
|
|
10
11
|
from zrb.input.any_input import AnyInput
|
|
11
12
|
from zrb.task.any_task import AnyTask
|
|
@@ -48,6 +49,7 @@ class CmdTask(BaseTask):
|
|
|
48
49
|
warn_unrecommended_command: bool | None = None,
|
|
49
50
|
max_output_line: int = 1000,
|
|
50
51
|
max_error_line: int = 1000,
|
|
52
|
+
execution_timeout: int = 3600,
|
|
51
53
|
is_interactive: bool = False,
|
|
52
54
|
execute_condition: BoolAttr = True,
|
|
53
55
|
retries: int = 2,
|
|
@@ -61,6 +63,7 @@ class CmdTask(BaseTask):
|
|
|
61
63
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
62
64
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
63
65
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
66
|
+
print_fn: PrintFn | None = None,
|
|
64
67
|
):
|
|
65
68
|
super().__init__(
|
|
66
69
|
name=name,
|
|
@@ -82,6 +85,7 @@ class CmdTask(BaseTask):
|
|
|
82
85
|
upstream=upstream,
|
|
83
86
|
fallback=fallback,
|
|
84
87
|
successor=successor,
|
|
88
|
+
print_fn=print_fn,
|
|
85
89
|
)
|
|
86
90
|
self._shell = shell
|
|
87
91
|
self._render_shell = render_shell
|
|
@@ -103,6 +107,7 @@ class CmdTask(BaseTask):
|
|
|
103
107
|
self._render_cwd = render_cwd
|
|
104
108
|
self._max_output_line = max_output_line
|
|
105
109
|
self._max_error_line = max_error_line
|
|
110
|
+
self._execution_timeout = execution_timeout
|
|
106
111
|
self._should_plain_print = plain_print
|
|
107
112
|
self._should_warn_unrecommended_command = warn_unrecommended_command
|
|
108
113
|
self._is_interactive = is_interactive
|
|
@@ -142,6 +147,7 @@ class CmdTask(BaseTask):
|
|
|
142
147
|
register_pid_method=lambda pid: ctx.xcom.get(xcom_pid_key).push(pid),
|
|
143
148
|
max_output_line=self._max_output_line,
|
|
144
149
|
max_error_line=self._max_error_line,
|
|
150
|
+
timeout=self._execution_timeout,
|
|
145
151
|
is_interactive=self._is_interactive,
|
|
146
152
|
)
|
|
147
153
|
# Check for errors
|
zrb/task/http_check.py
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from collections.abc import Callable
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
3
4
|
|
|
4
5
|
from zrb.attr.type import StrAttr
|
|
5
6
|
from zrb.context.any_context import AnyContext
|
|
6
|
-
from zrb.context.
|
|
7
|
+
from zrb.context.print_fn import PrintFn
|
|
7
8
|
from zrb.env.any_env import AnyEnv
|
|
8
9
|
from zrb.input.any_input import AnyInput
|
|
9
10
|
from zrb.task.any_task import AnyTask
|
|
10
11
|
from zrb.task.base_task import BaseTask
|
|
11
12
|
from zrb.util.attr import get_str_attr
|
|
12
13
|
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from requests import Response
|
|
16
|
+
|
|
13
17
|
|
|
14
18
|
class HttpCheck(BaseTask):
|
|
15
19
|
def __init__(
|
|
@@ -19,16 +23,17 @@ class HttpCheck(BaseTask):
|
|
|
19
23
|
icon: str | None = None,
|
|
20
24
|
description: str | None = None,
|
|
21
25
|
cli_only: bool = False,
|
|
22
|
-
input: list[AnyInput] | AnyInput | None = None,
|
|
23
|
-
env: list[AnyEnv] | AnyEnv | None = None,
|
|
26
|
+
input: list[AnyInput | None] | AnyInput | None = None,
|
|
27
|
+
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
24
28
|
url: StrAttr = "http://localhost",
|
|
25
29
|
render_url: bool = True,
|
|
26
30
|
http_method: StrAttr = "GET",
|
|
27
31
|
interval: int = 5,
|
|
28
|
-
execute_condition: bool | str | Callable[[
|
|
32
|
+
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
|
29
33
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
30
34
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
31
35
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
36
|
+
print_fn: PrintFn | None = None,
|
|
32
37
|
):
|
|
33
38
|
super().__init__(
|
|
34
39
|
name=name,
|
|
@@ -43,6 +48,7 @@ class HttpCheck(BaseTask):
|
|
|
43
48
|
upstream=upstream,
|
|
44
49
|
fallback=fallback,
|
|
45
50
|
successor=successor,
|
|
51
|
+
print_fn=print_fn,
|
|
46
52
|
)
|
|
47
53
|
self._url = url
|
|
48
54
|
self._render_url = render_url
|
|
@@ -57,7 +63,7 @@ class HttpCheck(BaseTask):
|
|
|
57
63
|
def _get_http_method(self, ctx: AnyContext) -> str:
|
|
58
64
|
return get_str_attr(ctx, self._http_method, "GET", auto_render=True).upper()
|
|
59
65
|
|
|
60
|
-
async def _exec_action(self, ctx: AnyContext) -> bool:
|
|
66
|
+
async def _exec_action(self, ctx: AnyContext) -> "bool | Response":
|
|
61
67
|
import requests
|
|
62
68
|
|
|
63
69
|
url = self._get_url(ctx)
|
zrb/task/make_task.py
CHANGED
|
@@ -2,6 +2,7 @@ from collections.abc import Callable
|
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
4
|
from zrb.context.any_context import AnyContext
|
|
5
|
+
from zrb.context.print_fn import PrintFn
|
|
5
6
|
from zrb.env.any_env import AnyEnv
|
|
6
7
|
from zrb.group.any_group import AnyGroup
|
|
7
8
|
from zrb.input.any_input import AnyInput
|
|
@@ -29,6 +30,7 @@ def make_task(
|
|
|
29
30
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
30
31
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
31
32
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
33
|
+
print_fn: PrintFn | None = None,
|
|
32
34
|
group: AnyGroup | None = None,
|
|
33
35
|
alias: str | None = None,
|
|
34
36
|
) -> Callable[[Callable[[AnyContext], Any]], AnyTask]:
|
|
@@ -54,6 +56,7 @@ def make_task(
|
|
|
54
56
|
upstream=upstream,
|
|
55
57
|
fallback=fallback,
|
|
56
58
|
successor=successor,
|
|
59
|
+
print_fn=print_fn,
|
|
57
60
|
)
|
|
58
61
|
if group is not None:
|
|
59
62
|
return group.add_task(task, alias=alias)
|
zrb/task/rsync_task.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from zrb.attr.type import BoolAttr, IntAttr, StrAttr
|
|
2
2
|
from zrb.context.any_context import AnyContext
|
|
3
|
+
from zrb.context.print_fn import PrintFn
|
|
3
4
|
from zrb.env.any_env import AnyEnv
|
|
4
5
|
from zrb.input.any_input import AnyInput
|
|
5
6
|
from zrb.task.any_task import AnyTask
|
|
@@ -44,6 +45,7 @@ class RsyncTask(CmdTask):
|
|
|
44
45
|
plain_print: bool = False,
|
|
45
46
|
max_output_line: int = 1000,
|
|
46
47
|
max_error_line: int = 1000,
|
|
48
|
+
execution_timeout: int = 3600,
|
|
47
49
|
execute_condition: BoolAttr = True,
|
|
48
50
|
retries: int = 2,
|
|
49
51
|
retry_period: float = 0,
|
|
@@ -51,6 +53,7 @@ class RsyncTask(CmdTask):
|
|
|
51
53
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
52
54
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
53
55
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
56
|
+
print_fn: PrintFn | None = None,
|
|
54
57
|
):
|
|
55
58
|
super().__init__(
|
|
56
59
|
name=name,
|
|
@@ -77,6 +80,7 @@ class RsyncTask(CmdTask):
|
|
|
77
80
|
plain_print=plain_print,
|
|
78
81
|
max_output_line=max_output_line,
|
|
79
82
|
max_error_line=max_error_line,
|
|
83
|
+
execution_timeout=execution_timeout,
|
|
80
84
|
execute_condition=execute_condition,
|
|
81
85
|
retries=retries,
|
|
82
86
|
retry_period=retry_period,
|
|
@@ -84,6 +88,7 @@ class RsyncTask(CmdTask):
|
|
|
84
88
|
upstream=upstream,
|
|
85
89
|
fallback=fallback,
|
|
86
90
|
successor=successor,
|
|
91
|
+
print_fn=print_fn,
|
|
87
92
|
)
|
|
88
93
|
self._remote_source_path = remote_source_path
|
|
89
94
|
self._render_remote_source_path = render_remote_source_path
|
zrb/task/scaffolder.py
CHANGED
|
@@ -2,10 +2,11 @@ import os
|
|
|
2
2
|
import shutil
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
|
|
5
|
-
from zrb.attr.type import
|
|
5
|
+
from zrb.attr.type import StrAttr
|
|
6
6
|
from zrb.content_transformer.any_content_transformer import AnyContentTransformer
|
|
7
7
|
from zrb.content_transformer.content_transformer import ContentTransformer
|
|
8
8
|
from zrb.context.any_context import AnyContext
|
|
9
|
+
from zrb.context.print_fn import PrintFn
|
|
9
10
|
from zrb.env.any_env import AnyEnv
|
|
10
11
|
from zrb.input.any_input import AnyInput
|
|
11
12
|
from zrb.task.any_task import AnyTask
|
|
@@ -24,8 +25,8 @@ class Scaffolder(BaseTask):
|
|
|
24
25
|
icon: str | None = None,
|
|
25
26
|
description: str | None = None,
|
|
26
27
|
cli_only: bool = False,
|
|
27
|
-
input: list[AnyInput] | AnyInput | None = None,
|
|
28
|
-
env: list[AnyEnv] | AnyEnv | None = None,
|
|
28
|
+
input: list[AnyInput | None] | AnyInput | None = None,
|
|
29
|
+
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
29
30
|
source_path: StrAttr | None = None,
|
|
30
31
|
render_source_path: bool = True,
|
|
31
32
|
destination_path: StrAttr | None = None,
|
|
@@ -36,7 +37,7 @@ class Scaffolder(BaseTask):
|
|
|
36
37
|
list[AnyContentTransformer] | AnyContentTransformer | TransformConfig
|
|
37
38
|
) = [],
|
|
38
39
|
render_transform_content: bool = True,
|
|
39
|
-
execute_condition:
|
|
40
|
+
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
|
40
41
|
retries: int = 2,
|
|
41
42
|
retry_period: float = 0,
|
|
42
43
|
readiness_check: list[AnyTask] | AnyTask | None = None,
|
|
@@ -48,6 +49,7 @@ class Scaffolder(BaseTask):
|
|
|
48
49
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
49
50
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
50
51
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
52
|
+
print_fn: PrintFn | None = None,
|
|
51
53
|
):
|
|
52
54
|
super().__init__(
|
|
53
55
|
name=name,
|
|
@@ -69,6 +71,7 @@ class Scaffolder(BaseTask):
|
|
|
69
71
|
upstream=upstream,
|
|
70
72
|
fallback=fallback,
|
|
71
73
|
successor=successor,
|
|
74
|
+
print_fn=print_fn,
|
|
72
75
|
)
|
|
73
76
|
self._source_path = source_path
|
|
74
77
|
self._render_source_path = render_source_path
|
zrb/task/scheduler.py
CHANGED
|
@@ -6,6 +6,7 @@ from zrb.attr.type import StrAttr, fstring
|
|
|
6
6
|
from zrb.callback.any_callback import AnyCallback
|
|
7
7
|
from zrb.context.any_context import AnyContext
|
|
8
8
|
from zrb.context.any_shared_context import AnySharedContext
|
|
9
|
+
from zrb.context.print_fn import PrintFn
|
|
9
10
|
from zrb.env.any_env import AnyEnv
|
|
10
11
|
from zrb.input.any_input import AnyInput
|
|
11
12
|
from zrb.task.any_task import AnyTask
|
|
@@ -39,6 +40,7 @@ class Scheduler(BaseTrigger):
|
|
|
39
40
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
40
41
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
41
42
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
43
|
+
print_fn: PrintFn | None = None,
|
|
42
44
|
):
|
|
43
45
|
super().__init__(
|
|
44
46
|
name=name,
|
|
@@ -62,6 +64,7 @@ class Scheduler(BaseTrigger):
|
|
|
62
64
|
upstream=upstream,
|
|
63
65
|
fallback=fallback,
|
|
64
66
|
successor=successor,
|
|
67
|
+
print_fn=print_fn,
|
|
65
68
|
)
|
|
66
69
|
self._cron_pattern = schedule
|
|
67
70
|
|
zrb/task/tcp_check.py
CHANGED
|
@@ -3,7 +3,7 @@ from collections.abc import Callable
|
|
|
3
3
|
|
|
4
4
|
from zrb.attr.type import IntAttr, StrAttr
|
|
5
5
|
from zrb.context.any_context import AnyContext
|
|
6
|
-
from zrb.context.
|
|
6
|
+
from zrb.context.print_fn import PrintFn
|
|
7
7
|
from zrb.env.any_env import AnyEnv
|
|
8
8
|
from zrb.input.any_input import AnyInput
|
|
9
9
|
from zrb.task.any_task import AnyTask
|
|
@@ -19,16 +19,17 @@ class TcpCheck(BaseTask):
|
|
|
19
19
|
icon: str | None = None,
|
|
20
20
|
description: str | None = None,
|
|
21
21
|
cli_only: bool = False,
|
|
22
|
-
input: list[AnyInput] | AnyInput | None = None,
|
|
23
|
-
env: list[AnyEnv] | AnyEnv | None = None,
|
|
22
|
+
input: list[AnyInput | None] | AnyInput | None = None,
|
|
23
|
+
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
24
24
|
host: StrAttr = "localhost",
|
|
25
25
|
render_host: bool = True,
|
|
26
26
|
port: IntAttr = 80,
|
|
27
27
|
interval: int = 5,
|
|
28
|
-
execute_condition: bool | str | Callable[[
|
|
28
|
+
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
|
29
29
|
upstream: list[AnyTask] | AnyTask | None = None,
|
|
30
30
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
31
31
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
32
|
+
print_fn: PrintFn | None = None,
|
|
32
33
|
):
|
|
33
34
|
super().__init__(
|
|
34
35
|
name=name,
|
|
@@ -43,6 +44,7 @@ class TcpCheck(BaseTask):
|
|
|
43
44
|
upstream=upstream,
|
|
44
45
|
fallback=fallback,
|
|
45
46
|
successor=successor,
|
|
47
|
+
print_fn=print_fn,
|
|
46
48
|
)
|
|
47
49
|
self._host = host
|
|
48
50
|
self._render_host = render_host
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⣉⡙⣿⣿⣿⣿⣿⣿⣿⣿
|
|
2
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⣡⣴⣿⣿⠇⣾⣿⣿⣿⣿⣿⣿⣿
|
|
3
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢃⣴⣿⣿⣿⣿⡟⢰⣿⣿⣿⣿⣿⣿⣿⣿
|
|
4
|
+
⣿⣿⠟⢿⣿⣿⣿⣿⣿⡇⣸⣿⣿⣿⣿⡟⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
5
|
+
⣇⣀⡲⣦⢻⣿⣿⣿⣿⡇⣿⣿⣿⣿⡟⣰⣿⡿⠿⠿⢿⣿⣿⣿⣿⣿
|
|
6
|
+
⣿⣿⣧⠙⠸⣿⣿⣿⣿⡇⣿⣿⣿⢏⠼⣋⣥⣶⣿⣿⣦⣤⣉⡛⠻⢿
|
|
7
|
+
⣿⢟⡁⠀⠀⠀⠙⣿⣿⣇⢿⣿⠋⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠈
|
|
8
|
+
⡇⠀⡿⠀⠀⠀⠀⠈⠉⣹⣾⠕⠾⣿⣿⣿⣿⡿⠿⠿⠟⠛⢛⣉⣤⣾
|
|
9
|
+
⣇⠀⠀⢀⠀⠀⠠⢀⣴⣿⠏⠀⢀⣶⡶⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿
|
|
10
|
+
⣿⣶⣤⣤⣤⣦⣶⡿⠟⠁⠀⢠⣾⣿⠃⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
11
|
+
⣿⣿⣿⣿⣿⣿⡄⠀⣀⣠⣴⣿⠟⠁⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
12
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⠛⠛⠋⠁⠀⠀⣠⣿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
13
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣤⣤⣶⣿⡿⠋⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
14
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⡁⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
15
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
16
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
17
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢿⣿⣿⣿⣿
|
|
2
|
+
⣿⣿⣿⣿⡿⢋⠹⣿⣿⣿⣿⣿⠟⢿⣿⣿⣿⣿⣿⣿⠃⠀⢨⣿⣿⣿⣿
|
|
3
|
+
⣿⣿⣿⠟⣠⣿⣧⣈⣉⣉⣉⣁⣶⡌⢻⣿⣿⣿⣿⣿⠘⠀⣿⣿⣿⣿⣿
|
|
4
|
+
⣿⣿⠏⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠛⠛⠛⠛⠛⠀⡀⠻⣿⣿⣿⣿
|
|
5
|
+
⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠘⣿⣿⣿⣿⣿⣿⣦⠈⢋⣉⠙
|
|
6
|
+
⣿⣿⡎⢿⣿⣶⣶⣿⣿⣿⣿⣤⣼⣿⡟⢠⣿⣿⣿⡿⠿⠟⠛⣀⣡⣤⣴
|
|
7
|
+
⠟⣁⣴⣦⠉⠛⠛⠛⠛⠛⠿⠟⠛⠁⠀⣋⣉⣥⣴⣶⣾⣿⣿⣿⣿⣿⣿
|
|
8
|
+
⣤⣭⣤⣶⣶⣿⣿⣿⠋⣠⡼⢋⣤⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
9
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣤⣤⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⢋⣉⣉⣉⣉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
2
|
+
⣿⣿⣿⣿⣿⣿⣿⡿⠋⣠⣾⣿⣿⣿⣿⣿⣷⣦⡈⢻⣿⣿⣿⣿⣿⣿⣿
|
|
3
|
+
⣿⣿⣿⣿⣿⣿⡿⢁⣾⡟⠁⣨⣿⣿⡅⠈⢻⣿⣿⡄⢻⣿⣿⣿⣿⣿⣿
|
|
4
|
+
⣿⠏⣤⣤⣉⠛⠃⢸⣿⣷⣾⡟⠉⠉⢻⣶⣾⣿⣿⡇⢸⣿⣿⣿⣿⣿⣿
|
|
5
|
+
⣿⣧⠄⣹⣿⣿⣷⣬⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⡇⢸⡿⠿⠿⠿⢿⣿
|
|
6
|
+
⣿⠇⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣴⣿⣿⣿⣿⣿⣥⣤⣶⣶⣶⡶⠆⣹
|
|
7
|
+
⡏⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⢰⣾⣿
|
|
8
|
+
⣧⠘⢿⡿⠟⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⣿⣿
|
|
9
|
+
⣿⣷⣦⣴⠂⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⣿⣿
|
|
10
|
+
⣿⣿⣿⣿⡀⠻⠿⠋⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢠⣈⠛⣁⣼⣿⣿
|
|
11
|
+
⣿⣿⣿⣿⣿⣿⣾⣿⣆⠘⣿⣿⣿⣿⣿⣿⡟⠙⠛⠃⣼⣿⣿⣿⣿⣿⣿
|
|
12
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡘⢿⣿⣿⣿⣿⡀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
13
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⡙⢿⣿⣿⣧⡈⠻⣿⣿⣿⣿⣿⣿⣿⣿
|
|
14
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣉⡙⠻⠿⣦⠙⢿⣿⣿⣿⣿⣿⣿
|
|
15
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣌⠡⠘⣿⣿⣿⣿⣿⣿
|
|
16
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣠⣿⣿⣿⣿⣿⣿
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
2
|
+
⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠙⠿⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
3
|
+
⣿⣿⣿⣿⣿⣿⡀⠀⣠⣴⣶⣿⣿⣿⣿⣶⣮⣝⠻⢿⣿⣿⣿⣿⣿
|
|
4
|
+
⣿⣿⣿⣿⣿⡟⣡⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠙⢿
|
|
5
|
+
⣿⠿⣿⣿⡿⢰⣿⡿⠋⠉⠉⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⣸
|
|
6
|
+
⠁⠀⠀⠙⠃⢿⣿⡅⠀⠀⢀⣼⣿⣿⣿⣿⠟⠛⠻⣿⣿⣷⢀⣴⣿
|
|
7
|
+
⡀⠀⠀⠀⠀⠸⣿⣛⣳⣾⣿⢿⡍⢉⣻⡇⠰⠀⠀⣿⣿⣿⢸⣿⣿
|
|
8
|
+
⣷⡀⠀⠀⠀⠀⠈⠻⢿⣿⣿⣷⣶⣬⣽⣿⣦⣤⣤⣟⣿⢇⣾⣿⣿
|
|
9
|
+
⣿⣿⣄⠀⠀⠀⠀⠀⠀⠈⠙⠻⠿⣿⣿⣿⣿⣮⣿⠟⣡⣾⣿⣿⣿
|
|
10
|
+
⣿⣿⣿⡇⢰⣶⣤⣤⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿
|
|
11
|
+
⣿⣿⣿⣇⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣤⡀⠀⠀⠀⠀⢻⣿⣿⣿⣿
|
|
12
|
+
⣿⣿⣿⡈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⢿⣿⣿⣿
|
|
13
|
+
⣿⣿⣿⡇⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⢸⣿⣿⣿
|
|
14
|
+
⣿⣿⣿⡇⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⢠⣄⣀⣠⣿⣿⣿⣿
|
|
15
|
+
⣿⣿⣿⣿⠀⠀⠀⠀⠉⣉⣛⣛⡛⠉⠁⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿
|
|
16
|
+
⣿⣿⣿⣿⣆⠀⠀⠀⣰⣿⣿⣿⣷⡀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿
|
|
17
|
+
⣿⣿⣿⣿⣿⣷⣶⣶⣿⣿⣿⣿⣿⣿⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⣿⣿⣿⠁⠀⠉⠉⠛⠛⠛⠉⠛⢻⣿⣿⣿⣿⣿⣿
|
|
2
|
+
⣿⣿⣿⣿⣿⠟⠋⠁⠀⠀⠀⠈⠙⢧⣤⣤⡀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿
|
|
3
|
+
⣿⣿⣿⣿⡿⠀⠀⠀⠀⠀⢀⣠⡴⠾⠛⠛⠿⣷⣄⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿
|
|
4
|
+
⣿⣿⣿⠋⠀⠀⠀⠀⣠⣶⣿⠁⠀⠀⣀⡀⠀⠈⠻⣦⡀⠀⠀⠀⠀⠀⣿⣿⣿⣿
|
|
5
|
+
⣿⣿⡏⠀⠀⠀⠀⣰⡿⠛⠙⠿⠛⠉⠛⠟⢿⣷⣄⣸⡇⠐⢦⣤⣤⠔⠛⠻⣿⣿
|
|
6
|
+
⣿⣿⡃⠀⠀⠀⠀⡟⠀⣠⠀⠀⠀⠀⢀⠀⠀⠹⠛⠛⣧⠀⠀⠙⠁⠀⠀⠀⠘⣿
|
|
7
|
+
⣿⣿⣷⡀⠀⠀⢸⠀⢰⣿⡀⠀⠀⠀⢹⣿⠀⢀⡆⠀⠘⣆⣴⣿⠀⠀⠀⠀⠀⠘
|
|
8
|
+
⣿⡟⠀⠙⣄⠀⢸⠀⠀⢻⣷⣄⠀⠤⠞⠋⣠⡾⠁⠀⢠⠟⠉⠻⡇⠀⠀⠀⠀⢰
|
|
9
|
+
⡿⠁⠀⠀⣿⣷⣾⣧⠀⠀⠈⠛⢳⠤⠒⠚⠉⠀⢀⡴⠃⠀⠀⠀⠃⠀⠀⠀⣠⣿
|
|
10
|
+
⡁⠀⠀⠀⣿⠀⠀⠹⣷⠄⢀⣠⣴⣿⣶⣤⣶⡾⠋⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿
|
|
11
|
+
⣷⡄⠀⠀⢻⠀⠀⠀⠘⢧⡀⠈⠉⠛⠛⠋⠉⠀⠀⠀⣀⣠⣴⣂⣀⠠⠊⢹⣿⣿
|
|
12
|
+
⣿⣿⣦⡀⢈⡄⠀⠀⠀⠀⠉⠙⠒⠒⠦⠤⠤⣶⣶⣿⣿⠿⠛⠋⠁⠀⢀⣾⣿⣿
|
|
13
|
+
⣿⣿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠋⠀⠀⠀⠀⣠⣴⣿⣿⣿⣿
|
|
14
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣦⣄⡀⠀⠀⢀⣀⣠⣴⣾⣿⣶⣤⣠⣴⣿⣿⣿⣿⣿⣿⣿
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
2
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⠉⢠⡟⠋⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
3
|
+
⣿⣿⣿⣿⣿⣿⠿⠛⠋⠉⠑⠁⠀⠀⠈⠀⣼⣿⣿⣿⣿⠿⠟⢛⣫⣽⣶
|
|
4
|
+
⣿⣿⣿⡿⠋⠁⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⢁⣠⣴⣾⣿⣿⣿⣿
|
|
5
|
+
⣿⣿⣯⡴⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿
|
|
6
|
+
⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠈⠁⢻⣿⣿⣿⣿⣿⣿⣿⣿
|
|
7
|
+
⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⣧⡀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿
|
|
8
|
+
⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⣶⣦⡀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿
|
|
9
|
+
⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⠀⡀⠀⢸⣿⣿⣿⣿⣿⣿⣿
|
|
10
|
+
⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣧⣷⣤⣾⣿⣿⣿⣿⣿⣿⣿
|
|
11
|
+
⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
12
|
+
⣿⣿⣿⣿⣦⣄⡀⠀⠀⠈⢦⡀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
13
|
+
⣿⣿⣿⣿⣿⣿⣿⣧⣤⣀⠀⣿⡀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
14
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣾⣷⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
15
|
+
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|